Unverified Commit 6717a85c authored by Peter Eastman's avatar Peter Eastman Committed by GitHub
Browse files

Reduced memory used by SerializationNode (#5249)

parent 1f2203f6
...@@ -156,7 +156,7 @@ void* AmoebaMultipoleForceProxy::deserialize(const SerializationNode& node) cons ...@@ -156,7 +156,7 @@ void* AmoebaMultipoleForceProxy::deserialize(const SerializationNode& node) cons
for (int i = 0; ; i++) { for (int i = 0; ; i++) {
stringstream key; stringstream key;
key << "c" << i; key << "c" << i;
if (coefficients.getProperties().find(key.str()) == coefficients.getProperties().end()) if (!coefficients.hasProperty(key.str()))
break; break;
coeff.push_back(coefficients.getDoubleProperty(key.str())); coeff.push_back(coefficients.getDoubleProperty(key.str()));
} }
......
...@@ -133,7 +133,7 @@ void* HippoNonbondedForceProxy::deserialize(const SerializationNode& node) const ...@@ -133,7 +133,7 @@ void* HippoNonbondedForceProxy::deserialize(const SerializationNode& node) const
for (int i = 0; ; i++) { for (int i = 0; ; i++) {
stringstream key; stringstream key;
key << "c" << i; key << "c" << i;
if (coefficients.getProperties().find(key.str()) == coefficients.getProperties().end()) if (!coefficients.hasProperty(key.str()))
break; break;
coeff.push_back(coefficients.getDoubleProperty(key.str())); coeff.push_back(coefficients.getDoubleProperty(key.str()));
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2021 Stanford University and the Authors * * Portions copyright (c) 2010-2026 Stanford University and the Authors *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -99,7 +99,7 @@ public: ...@@ -99,7 +99,7 @@ public:
/** /**
* Get a map containing all of this node's properties. * Get a map containing all of this node's properties.
*/ */
const std::map<std::string, std::string>& getProperties() const; const std::map<std::string, std::string> getProperties() const;
/** /**
* Determine whether this node has a property with a particular node. * Determine whether this node has a property with a particular node.
* *
...@@ -112,7 +112,7 @@ public: ...@@ -112,7 +112,7 @@ public:
* *
* @param name the name of the property to get * @param name the name of the property to get
*/ */
const std::string& getStringProperty(const std::string& name) const; const std::string getStringProperty(const std::string& name) const;
/** /**
* Get the property with a particular name, specified as a string. If there is no property with * Get the property with a particular name, specified as a string. If there is no property with
* the specified name, a default value is returned instead. * the specified name, a default value is returned instead.
...@@ -120,7 +120,7 @@ public: ...@@ -120,7 +120,7 @@ public:
* @param name the name of the property to get * @param name the name of the property to get
* @param defaultValue the value to return if the specified property does not exist * @param defaultValue the value to return if the specified property does not exist
*/ */
const std::string& getStringProperty(const std::string& name, const std::string& defaultValue) const; const std::string getStringProperty(const std::string& name, const std::string& defaultValue) const;
/** /**
* Set the value of a property, specified as a string. * Set the value of a property, specified as a string.
* *
...@@ -261,9 +261,10 @@ public: ...@@ -261,9 +261,10 @@ public:
return reinterpret_cast<T*>(SerializationProxy::getProxy(getStringProperty("type")).deserialize(*this)); return reinterpret_cast<T*>(SerializationProxy::getProxy(getStringProperty("type")).deserialize(*this));
} }
private: private:
const char* findPropertyValue(const std::string& name, bool required) const;
std::string name; std::string name;
std::vector<SerializationNode> children; std::vector<SerializationNode> children;
std::map<std::string, std::string> properties; std::string properties;
}; };
} // namespace OpenMM } // namespace OpenMM
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2021 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "openmm/serialization/SerializationNode.h" #include "openmm/serialization/SerializationNode.h"
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include <cstring>
#include <sstream> #include <sstream>
using namespace OpenMM; using namespace OpenMM;
...@@ -67,127 +68,141 @@ SerializationNode& SerializationNode::getChildNode(const std::string& name) { ...@@ -67,127 +68,141 @@ SerializationNode& SerializationNode::getChildNode(const std::string& name) {
throw OpenMMException("Unknown child '"+name+"' for node '"+getName()+"'"); throw OpenMMException("Unknown child '"+name+"' for node '"+getName()+"'");
} }
const map<string, string>& SerializationNode::getProperties() const { const map<string, string> SerializationNode::getProperties() const {
return properties; map<string, string> result;
int start = 0;
while (start < properties.size()) {
string name(&properties[start]);
start += name.size()+1;
string value(&properties[start]);
start += value.size()+1;
result[name] = value;
}
return result;
}
const char* SerializationNode::findPropertyValue(const std::string& name, bool required) const {
int start = 0;
while (start < properties.size()) {
if (strcmp(&properties[start], name.data()) == 0)
return &properties[start+name.size()+1];
// This isn't the property we're looking for. Skip over the name and value.
start += strlen(&properties[start])+1;
start += strlen(&properties[start])+1;
}
if (required)
throw OpenMMException("Unknown property '"+name+"' in node '"+getName()+"'");
// We didn't find it, but that's ok. Report that it wasn't found.
return nullptr;
} }
bool SerializationNode::hasProperty(const string& name) const { bool SerializationNode::hasProperty(const string& name) const {
return (properties.find(name) != properties.end()); return findPropertyValue(name, false) != nullptr;
} }
const string& SerializationNode::getStringProperty(const string& name) const { const string SerializationNode::getStringProperty(const string& name) const {
map<string, string>::const_iterator iter = properties.find(name); return string(findPropertyValue(name, true));
if (iter == properties.end())
throw OpenMMException("Unknown property '"+name+"' in node '"+getName()+"'");
return iter->second;
} }
const string& SerializationNode::getStringProperty(const string& name, const string& defaultValue) const { const string SerializationNode::getStringProperty(const string& name, const string& defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name); const char* value = findPropertyValue(name, false);
if (iter == properties.end()) if (value == nullptr)
return defaultValue; return defaultValue;
return iter->second; return string(value);
} }
SerializationNode& SerializationNode::setStringProperty(const string& name, const string& value) { SerializationNode& SerializationNode::setStringProperty(const string& name, const string& value) {
properties[name] = value; int s = properties.size()+name.size()+value.size()+2;
properties.reserve(properties.size()+name.size()+value.size()+2);
properties.append(name);
properties.push_back(0);
properties.append(value);
properties.push_back(0);
return *this; return *this;
} }
int SerializationNode::getIntProperty(const string& name) const { int SerializationNode::getIntProperty(const string& name) const {
map<string, string>::const_iterator iter = properties.find(name);
if (iter == properties.end())
throw OpenMMException("Unknown property '"+name+"' in node '"+getName()+"'");
int value; int value;
stringstream(iter->second) >> value; stringstream(findPropertyValue(name, true)) >> value;
return value; return value;
} }
int SerializationNode::getIntProperty(const string& name, int defaultValue) const { int SerializationNode::getIntProperty(const string& name, int defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name); const char* value = findPropertyValue(name, false);
if (iter == properties.end()) if (value == nullptr)
return defaultValue; return defaultValue;
int value; int result;
stringstream(iter->second) >> value; stringstream(value) >> result;
return value; return result;
} }
SerializationNode& SerializationNode::setIntProperty(const string& name, int value) { SerializationNode& SerializationNode::setIntProperty(const string& name, int value) {
stringstream s; stringstream s;
s << value; s << value;
properties[name] = s.str(); return setStringProperty(name, s.str());
return *this;
} }
long long SerializationNode::getLongProperty(const string& name) const { long long SerializationNode::getLongProperty(const string& name) const {
map<string, string>::const_iterator iter = properties.find(name);
if (iter == properties.end())
throw OpenMMException("Unknown property '"+name+"' in node '"+getName()+"'");
long long value; long long value;
stringstream(iter->second) >> value; stringstream(findPropertyValue(name, true)) >> value;
return value; return value;
} }
long long SerializationNode::getLongProperty(const string& name, long long defaultValue) const { long long SerializationNode::getLongProperty(const string& name, long long defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name); const char* value = findPropertyValue(name, false);
if (iter == properties.end()) if (value == nullptr)
return defaultValue; return defaultValue;
long long value; long long result;
stringstream(iter->second) >> value; stringstream(value) >> result;
return value; return result;
} }
SerializationNode& SerializationNode::setLongProperty(const string& name, long long value) { SerializationNode& SerializationNode::setLongProperty(const string& name, long long value) {
stringstream s; stringstream s;
s << value; s << value;
properties[name] = s.str(); return setStringProperty(name, s.str());
return *this;
} }
bool SerializationNode::getBoolProperty(const string& name) const { bool SerializationNode::getBoolProperty(const string& name) const {
map<string, string>::const_iterator iter = properties.find(name);
if (iter == properties.end())
throw OpenMMException("Unknown property '"+name+"' in node '"+getName()+"'");
bool value; bool value;
stringstream(iter->second) >> value; stringstream(findPropertyValue(name, true)) >> value;
return value; return value;
} }
bool SerializationNode::getBoolProperty(const string& name, bool defaultValue) const { bool SerializationNode::getBoolProperty(const string& name, bool defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name); const char* value = findPropertyValue(name, false);
if (iter == properties.end()) if (value == nullptr)
return defaultValue; return defaultValue;
bool value; bool result;
stringstream(iter->second) >> value; stringstream(value) >> result;
return value; return result;
} }
SerializationNode& SerializationNode::setBoolProperty(const string& name, bool value) { SerializationNode& SerializationNode::setBoolProperty(const string& name, bool value) {
stringstream s; stringstream s;
s << value; s << value;
properties[name] = s.str(); return setStringProperty(name, s.str());
return *this;
} }
double SerializationNode::getDoubleProperty(const string& name) const { double SerializationNode::getDoubleProperty(const string& name) const {
map<string, string>::const_iterator iter = properties.find(name); return strtod2(findPropertyValue(name, true), NULL);
if (iter == properties.end())
throw OpenMMException("Unknown property '"+name+"' in node '"+getName()+"'");
return strtod2(iter->second.c_str(), NULL);
} }
double SerializationNode::getDoubleProperty(const string& name, double defaultValue) const { double SerializationNode::getDoubleProperty(const string& name, double defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name); const char* value = findPropertyValue(name, false);
if (iter == properties.end()) if (value == nullptr)
return defaultValue; return defaultValue;
return strtod2(iter->second.c_str(), NULL); return strtod2(value, NULL);
} }
SerializationNode& SerializationNode::setDoubleProperty(const string& name, double value) { SerializationNode& SerializationNode::setDoubleProperty(const string& name, double value) {
char buffer[32]; char buffer[32];
g_fmt(buffer, value); g_fmt(buffer, value);
properties[name] = string(buffer); return setStringProperty(name, string(buffer));
return *this;
} }
SerializationNode& SerializationNode::createChildNode(const std::string& name) { SerializationNode& SerializationNode::createChildNode(const std::string& name) {
......
...@@ -65,12 +65,12 @@ void testProperties() { ...@@ -65,12 +65,12 @@ void testProperties() {
ASSERT_EQUAL("abc", node.getStringProperty("prop1", "abc")); ASSERT_EQUAL("abc", node.getStringProperty("prop1", "abc"));
node.setIntProperty("prop1", 1); node.setIntProperty("prop1", 1);
ASSERT_EQUAL(1, node.getIntProperty("prop1")); ASSERT_EQUAL(1, node.getIntProperty("prop1"));
node.setDoubleProperty("prop1", 1.5); node.setDoubleProperty("prop2", 1.5);
ASSERT_EQUAL(1.5, node.getDoubleProperty("prop1")); ASSERT_EQUAL(1.5, node.getDoubleProperty("prop2"));
node.setStringProperty("prop1", "hello"); node.setStringProperty("prop3", "hello");
ASSERT_EQUAL("hello", node.getStringProperty("prop1")); ASSERT_EQUAL("hello", node.getStringProperty("prop3"));
ASSERT_EQUAL(true, node.hasProperty("prop1")); ASSERT_EQUAL(true, node.hasProperty("prop1"));
ASSERT_EQUAL(false, node.hasProperty("prop2")); ASSERT_EQUAL(false, node.hasProperty("prop4"));
} }
int main() { int main() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment