about summary refs log tree commit diff
path: root/src/libexpr/json-to-value.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-09-19T14·49+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-09-19T14·49+0200
commit5b58991a71d15123c010bbbd7f08530dbc31173f (patch)
tree3cec3413ee43ddd8b46b950022e0741a7c166fd7 /src/libexpr/json-to-value.cc
parent0342eb170500f726f11269d26a1f34cded5d3676 (diff)
Store Attrs inside Bindings
This prevents a double allocation per attribute set.
Diffstat (limited to 'src/libexpr/json-to-value.cc')
-rw-r--r--src/libexpr/json-to-value.cc11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/libexpr/json-to-value.cc b/src/libexpr/json-to-value.cc
index af4394b0bbba..1892b0bac1af 100644
--- a/src/libexpr/json-to-value.cc
+++ b/src/libexpr/json-to-value.cc
@@ -14,8 +14,10 @@ static void skipWhitespace(const char * & s)
 
 #if HAVE_BOEHMGC
 typedef std::vector<Value *, gc_allocator<Value *> > ValueVector;
+typedef std::map<Symbol, Value *, std::less<Symbol>, gc_allocator<Value *> > ValueMap;
 #else
 typedef std::vector<Value *> ValueVector;
+typedef std::map<Symbol, Value *> ValueMap;
 #endif
 
 
@@ -76,22 +78,25 @@ static void parseJSON(EvalState & state, const char * & s, Value & v)
 
     else if (*s == '{') {
         s++;
-        state.mkAttrs(v, 1);
+        ValueMap attrs;
         while (1) {
             skipWhitespace(s);
-            if (v.attrs->empty() && *s == '}') break;
+            if (attrs.empty() && *s == '}') break;
             string name = parseJSONString(s);
             skipWhitespace(s);
             if (*s != ':') throw JSONParseError("expected ‘:’ in JSON object");
             s++;
             Value * v2 = state.allocValue();
             parseJSON(state, s, *v2);
-            v.attrs->push_back(Attr(state.symbols.create(name), v2));
+            attrs[state.symbols.create(name)] = v2;
             skipWhitespace(s);
             if (*s == '}') break;
             if (*s != ',') throw JSONParseError("expected ‘,’ or ‘}’ after JSON member");
             s++;
         }
+        state.mkAttrs(v, attrs.size());
+        for (auto & i : attrs)
+            v.attrs->push_back(Attr(i.first, i.second));
         v.attrs->sort();
         s++;
     }