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
for (int i = 0; ; i++) {
stringstream key;
key << "c" << i;
if (coefficients.getProperties().find(key.str()) == coefficients.getProperties().end())
if (!coefficients.hasProperty(key.str()))
break;
coeff.push_back(coefficients.getDoubleProperty(key.str()));
}
......
......@@ -133,7 +133,7 @@ void* HippoNonbondedForceProxy::deserialize(const SerializationNode& node) const
for (int i = 0; ; i++) {
stringstream key;
key << "c" << i;
if (coefficients.getProperties().find(key.str()) == coefficients.getProperties().end())
if (!coefficients.hasProperty(key.str()))
break;
coeff.push_back(coefficients.getDoubleProperty(key.str()));
}
......
......@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -99,7 +99,7 @@ public:
/**
* 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.
*
......@@ -112,7 +112,7 @@ public:
*
* @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
* the specified name, a default value is returned instead.
......@@ -120,7 +120,7 @@ public:
* @param name the name of the property to get
* @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.
*
......@@ -261,9 +261,10 @@ public:
return reinterpret_cast<T*>(SerializationProxy::getProxy(getStringProperty("type")).deserialize(*this));
}
private:
const char* findPropertyValue(const std::string& name, bool required) const;
std::string name;
std::vector<SerializationNode> children;
std::map<std::string, std::string> properties;
std::string properties;
};
} // namespace OpenMM
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -29,6 +29,7 @@
#include "openmm/serialization/SerializationNode.h"
#include "openmm/OpenMMException.h"
#include <cstring>
#include <sstream>
using namespace OpenMM;
......@@ -67,127 +68,141 @@ SerializationNode& SerializationNode::getChildNode(const std::string& name) {
throw OpenMMException("Unknown child '"+name+"' for node '"+getName()+"'");
}
const map<string, string>& SerializationNode::getProperties() const {
return properties;
const map<string, string> SerializationNode::getProperties() const {
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 {
return (properties.find(name) != properties.end());
return findPropertyValue(name, false) != nullptr;
}
const string& SerializationNode::getStringProperty(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()+"'");
return iter->second;
const string SerializationNode::getStringProperty(const string& name) const {
return string(findPropertyValue(name, true));
}
const string& SerializationNode::getStringProperty(const string& name, const string& defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name);
if (iter == properties.end())
const string SerializationNode::getStringProperty(const string& name, const string& defaultValue) const {
const char* value = findPropertyValue(name, false);
if (value == nullptr)
return defaultValue;
return iter->second;
return 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;
}
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;
stringstream(iter->second) >> value;
stringstream(findPropertyValue(name, true)) >> value;
return value;
}
int SerializationNode::getIntProperty(const string& name, int defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name);
if (iter == properties.end())
const char* value = findPropertyValue(name, false);
if (value == nullptr)
return defaultValue;
int value;
stringstream(iter->second) >> value;
return value;
int result;
stringstream(value) >> result;
return result;
}
SerializationNode& SerializationNode::setIntProperty(const string& name, int value) {
stringstream s;
s << value;
properties[name] = s.str();
return *this;
return setStringProperty(name, s.str());
}
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;
stringstream(iter->second) >> value;
stringstream(findPropertyValue(name, true)) >> value;
return value;
}
long long SerializationNode::getLongProperty(const string& name, long long defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name);
if (iter == properties.end())
const char* value = findPropertyValue(name, false);
if (value == nullptr)
return defaultValue;
long long value;
stringstream(iter->second) >> value;
return value;
long long result;
stringstream(value) >> result;
return result;
}
SerializationNode& SerializationNode::setLongProperty(const string& name, long long value) {
stringstream s;
s << value;
properties[name] = s.str();
return *this;
return setStringProperty(name, s.str());
}
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;
stringstream(iter->second) >> value;
stringstream(findPropertyValue(name, true)) >> value;
return value;
}
bool SerializationNode::getBoolProperty(const string& name, bool defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name);
if (iter == properties.end())
const char* value = findPropertyValue(name, false);
if (value == nullptr)
return defaultValue;
bool value;
stringstream(iter->second) >> value;
return value;
bool result;
stringstream(value) >> result;
return result;
}
SerializationNode& SerializationNode::setBoolProperty(const string& name, bool value) {
stringstream s;
s << value;
properties[name] = s.str();
return *this;
return setStringProperty(name, s.str());
}
double SerializationNode::getDoubleProperty(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()+"'");
return strtod2(iter->second.c_str(), NULL);
return strtod2(findPropertyValue(name, true), NULL);
}
double SerializationNode::getDoubleProperty(const string& name, double defaultValue) const {
map<string, string>::const_iterator iter = properties.find(name);
if (iter == properties.end())
const char* value = findPropertyValue(name, false);
if (value == nullptr)
return defaultValue;
return strtod2(iter->second.c_str(), NULL);
return strtod2(value, NULL);
}
SerializationNode& SerializationNode::setDoubleProperty(const string& name, double value) {
char buffer[32];
g_fmt(buffer, value);
properties[name] = string(buffer);
return *this;
return setStringProperty(name, string(buffer));
}
SerializationNode& SerializationNode::createChildNode(const std::string& name) {
......
......@@ -65,12 +65,12 @@ void testProperties() {
ASSERT_EQUAL("abc", node.getStringProperty("prop1", "abc"));
node.setIntProperty("prop1", 1);
ASSERT_EQUAL(1, node.getIntProperty("prop1"));
node.setDoubleProperty("prop1", 1.5);
ASSERT_EQUAL(1.5, node.getDoubleProperty("prop1"));
node.setStringProperty("prop1", "hello");
ASSERT_EQUAL("hello", node.getStringProperty("prop1"));
node.setDoubleProperty("prop2", 1.5);
ASSERT_EQUAL(1.5, node.getDoubleProperty("prop2"));
node.setStringProperty("prop3", "hello");
ASSERT_EQUAL("hello", node.getStringProperty("prop3"));
ASSERT_EQUAL(true, node.hasProperty("prop1"));
ASSERT_EQUAL(false, node.hasProperty("prop2"));
ASSERT_EQUAL(false, node.hasProperty("prop4"));
}
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