From: Anton Likhtarov Date: Tue, 26 Nov 2013 02:26:29 +0000 (-0800) Subject: sort_keys option for json X-Git-Tag: v0.22.0~782 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bfa6ffb55e8a371130b1d391926afd3030a8cedc;p=folly.git sort_keys option for json Summary: A dumb&slow implementation. I just needed something that outputs keys in a sorted order. No easy to use API to discourage the use due to perf implications. Test Plan: unit test Reviewed By: delong.j@fb.com FB internal diff: D1073757 --- diff --git a/folly/json.cpp b/folly/json.cpp index 5fe44a59..ab45d594 100644 --- a/folly/json.cpp +++ b/folly/json.cpp @@ -159,6 +159,16 @@ private: (*this)(p.second); } + template + void printKVPairs(Iterator begin, Iterator end) const { + printKV(*begin); + for (++begin; begin != end; ++begin) { + out_ += ','; + newline(); + printKV(*begin); + } + } + void printObject(dynamic const& o) const { if (o.empty()) { out_ += "{}"; @@ -168,12 +178,13 @@ private: out_ += '{'; indent(); newline(); - auto it = o.items().begin(); - printKV(*it); - for (++it; it != o.items().end(); ++it) { - out_ += ','; - newline(); - printKV(*it); + if (opts_.sort_keys) { + std::vector> items( + o.items().begin(), o.items().end()); + std::sort(items.begin(), items.end()); + printKVPairs(items.begin(), items.end()); + } else { + printKVPairs(o.items().begin(), o.items().end()); } outdent(); newline(); diff --git a/folly/json.h b/folly/json.h index 40f23f2a..149ca8ff 100644 --- a/folly/json.h +++ b/folly/json.h @@ -59,6 +59,7 @@ namespace json { , encode_non_ascii(false) , validate_utf8(false) , allow_trailing_comma(false) + , sort_keys(false) {} // If true, keys in an object can be non-strings. (In strict @@ -85,6 +86,9 @@ namespace json { // Allow trailing comma in lists of values / items bool allow_trailing_comma; + + // Sort keys of all objects before printing out (potentially slow) + bool sort_keys; }; /* diff --git a/folly/test/JsonTest.cpp b/folly/test/JsonTest.cpp index cfa84f4c..6dfdcb48 100644 --- a/folly/test/JsonTest.cpp +++ b/folly/test/JsonTest.cpp @@ -331,6 +331,37 @@ TEST(Json, ParseNonStringKeys) { EXPECT_EQ(1.5, dval.items().begin()->first.asDouble()); } +TEST(Json, SortKeys) { + folly::json::serialization_opts opts_on, opts_off; + opts_on.sort_keys = true; + opts_off.sort_keys = false; + + dynamic value = dynamic::object + ("foo", "bar") + ("junk", 12) + ("another", 32.2) + ("a", + { + dynamic::object("a", "b") + ("c", "d"), + 12.5, + "Yo Dawg", + { "heh" }, + nullptr + } + ) + ; + + std::string sorted_keys = + R"({"a":[{"a":"b","c":"d"},12.5,"Yo Dawg",["heh"],null],)" + R"("another":32.2,"foo":"bar","junk":12})"; + + EXPECT_EQ(value, parseJson(folly::json::serialize(value, opts_on))); + EXPECT_EQ(value, parseJson(folly::json::serialize(value, opts_off))); + + EXPECT_EQ(sorted_keys, folly::json::serialize(value, opts_on)); +} + BENCHMARK(jsonSerialize, iters) { folly::json::serialization_opts opts; for (int i = 0; i < iters; ++i) {