Skip to content

Commit

Permalink
optimize order preservation (keep pointers to keys instead of copies)…
Browse files Browse the repository at this point in the history
…; remove (unnecessary) prserveOrder flag from Stringifier::stringify()
  • Loading branch information
aleks-f committed Jun 1, 2015
1 parent 4ac92e5 commit 956f385
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 39 deletions.
16 changes: 8 additions & 8 deletions JSON/include/Poco/JSON/Object.h
Expand Up @@ -191,7 +191,7 @@ class JSON_API Object
/// Sets a new value

void stringify(std::ostream& out, unsigned int indent = 0, int step = -1) const;
/// Prints the object to out. When indent is 0, the object
/// Prints the object to out stream. When indent is 0, the object
/// will be printed on a single line without indentation.

void remove(const std::string& key);
Expand Down Expand Up @@ -239,16 +239,16 @@ class JSON_API Object
out << '}';
}

typedef std::deque<std::string> KeyList;
typedef Poco::DynamicStruct::Ptr StructPtr;
typedef std::deque<const std::string*> KeyPtrList;
typedef Poco::DynamicStruct::Ptr StructPtr;

const std::string& getKey(ValueMap::const_iterator& it) const;
const Dynamic::Var& getValue(ValueMap::const_iterator& it) const;
const std::string& getKey(KeyList::const_iterator& it) const;
const Dynamic::Var& getValue(KeyList::const_iterator& it) const;
const std::string& getKey(KeyPtrList::const_iterator& it) const;
const Dynamic::Var& getValue(KeyPtrList::const_iterator& it) const;

ValueMap _values;
KeyList _keys;
KeyPtrList _keys;
bool _preserveInsOrder;
mutable StructPtr _pStruct;
};
Expand Down Expand Up @@ -318,9 +318,9 @@ inline const Dynamic::Var& Object::getValue(ValueMap::const_iterator& it) const
}


inline const Dynamic::Var& Object::getValue(KeyList::const_iterator& it) const
inline const Dynamic::Var& Object::getValue(KeyPtrList::const_iterator& it) const
{
return _values.at(*it);
return _values.at(**it);
}


Expand Down
21 changes: 4 additions & 17 deletions JSON/include/Poco/JSON/Stringifier.h
Expand Up @@ -37,15 +37,9 @@ class JSON_API Stringifier
/// Writes a condensed string representation of the value to the output stream while preserving the insertion order.
/// This is just a "shortcut" to stringify(any, out) with name indicating the function effect.

static void stringify(const Dynamic::Var& any, bool preserveInsertionOrder, std::ostream& out, unsigned int indent = 0);
/// Writes a String representation of the value to the output stream while preserving the insertion order.
/// When indent is 0, the generated string will be created as small as possible (condensed).
/// When preserveInsertionOrder is true, the original string object members order will be preserved.
/// This is a "shortcut" to stringify(any, out, indent, -1, preserveInsertionOrder).

static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0, int step = -1, bool preserveInsertionOrder = false);
/// Writes a String representation of the value to the output stream.
/// When indent is 0, the String will be created as small as possible.
static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0, int step = -1);
/// Writes a string representation of the value to the output stream.
/// When indent is 0, the string will be created as small as possible.
/// When preserveInsertionOrder is true, the original string object members order will be preserved;
/// otherwise, object members are sorted by their names.

Expand All @@ -56,16 +50,9 @@ class JSON_API Stringifier

inline void Stringifier::condense(const Dynamic::Var& any, std::ostream& out)
{
stringify(any, out, 0, -1, true);
}


inline void Stringifier::stringify(const Dynamic::Var& any, bool preserveInsertionOrder, std::ostream& out, unsigned int indent)
{
stringify(any, out, indent, -1, preserveInsertionOrder);
stringify(any, out, 0, -1);
}


}} // namespace Poco::JSON


Expand Down
16 changes: 8 additions & 8 deletions JSON/src/Object.cpp
Expand Up @@ -101,31 +101,31 @@ void Object::stringify(std::ostream& out, unsigned int indent, int step) const
}


const std::string& Object::getKey(KeyList::const_iterator& iter) const
const std::string& Object::getKey(KeyPtrList::const_iterator& iter) const
{
ValueMap::const_iterator it = _values.begin();
ValueMap::const_iterator end = _values.end();
for (; it != end; ++it)
{
if (it->first == *iter) return it->first;
if (it->first == **iter) return it->first;
}

throw NotFoundException(*iter);
throw NotFoundException(**iter);
}


void Object::set(const std::string& key, const Dynamic::Var& value)
{
_values[key] = value;
std::pair<ValueMap::iterator, bool> ret = _values.insert(ValueMap::value_type(key, value));
if (_preserveInsOrder)
{
KeyList::iterator it = _keys.begin();
KeyList::iterator end = _keys.end();
KeyPtrList::iterator it = _keys.begin();
KeyPtrList::iterator end = _keys.end();
for (; it != end; ++it)
{
if (key == *it) return;
if (key == **it) return;
}
_keys.push_back(key);
_keys.push_back(&ret.first->first);
}
}

Expand Down
2 changes: 1 addition & 1 deletion JSON/src/Stringifier.cpp
Expand Up @@ -28,7 +28,7 @@ namespace Poco {
namespace JSON {


void Stringifier::stringify(const Var& any, std::ostream& out, unsigned int indent, int step, bool preserveInsertionOrder)
void Stringifier::stringify(const Var& any, std::ostream& out, unsigned int indent, int step)
{
if (step == -1) step = indent;

Expand Down
24 changes: 19 additions & 5 deletions JSON/testsuite/src/JSONTest.cpp
Expand Up @@ -1394,13 +1394,27 @@ void JSONTest::testStringify()

void JSONTest::testStringifyPreserveOrder()
{
Object jObj(true);
jObj.set("foo", 0);
jObj.set("bar", 0);
jObj.set("baz", 0);
Object presObj(true);
presObj.set("foo", 0);
presObj.set("bar", 0);
presObj.set("baz", 0);
std::stringstream ss;
jObj.stringify(ss);
presObj.stringify(ss);
assert(ss.str() == "{\"foo\":0,\"bar\":0,\"baz\":0}");
ss.str("");
Stringifier::stringify(presObj, ss);
assert(ss.str() == "{\"foo\":0,\"bar\":0,\"baz\":0}");

Object noPresObj;
noPresObj.set("foo", 0);
noPresObj.set("bar", 0);
noPresObj.set("baz", 0);
ss.str("");
noPresObj.stringify(ss);
assert(ss.str() == "{\"bar\":0,\"baz\":0,\"foo\":0}");
ss.str("");
Stringifier::stringify(noPresObj, ss);
assert(ss.str() == "{\"bar\":0,\"baz\":0,\"foo\":0}");

std::string json = "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\" , \"age\" : 38 }, \"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
Expand Down
24 changes: 24 additions & 0 deletions doc/99100-ReleaseNotes.page
@@ -1,6 +1,30 @@
POCO C++ Libraries Release Notes
AAAIntroduction

!!!Release 1.7.0

!!Summary of Changes

- JSON Stringifier fails with preserve insert order #819


!!Incompatible Changes and Possible Transition Issues

- Modified JSON::Stringifier interface (removed preserve order flag which had no effect)


!!!Release 1.6.1

!!Summary of Changes

-


!!Incompatible Changes and Possible Transition Issues

-


!!!Release 1.6.0

!!Summary of Changes
Expand Down

0 comments on commit 956f385

Please sign in to comment.