diff options
author | Philip Withnall <philip.withnall@collabora.co.uk> | 2016-03-01 15:01:07 +0000 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2016-03-01 15:01:07 +0000 |
commit | 6ddbc94c9888e5ddcd1cbb15845d2f1b5524b3ed (patch) | |
tree | cba11bd7504d1f33e48209d2d67b2fd5f0ef00eb /json-glib/json-value.c | |
parent | 1de237a502ceee96df7091c2df4492b8bc08b2c5 (diff) | |
download | json-glib-6ddbc94c9888e5ddcd1cbb15845d2f1b5524b3ed.tar.gz |
core: Add JSON node, object, array hashes
Now that these objects can be marked as immutable, it is possible to
calculate and cache hash values for each of them. This allows efficient
hash-based deduplication of large numbers of JSON nodes, as needed by
Walbottle for JSON test vector generation.
To complement the new hash functions, each of JsonNode, JsonValue,
JsonObject and JsonArray also now have an equal() comparison method.
This compares them structurally and recursively, using the definition of
equality from the JSON Schema specification, which seems as good as any
other.
http://json-schema.org/latest/json-schema-core.html#anchor9
https://bugzilla.gnome.org/show_bug.cgi?id=756121
Signed-off-by: Emmanuele Bassi <ebassi@gnome.org>
Diffstat (limited to 'json-glib/json-value.c')
-rw-r--r-- | json-glib/json-value.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/json-glib/json-value.c b/json-glib/json-value.c index 148cf8d..e636499 100644 --- a/json-glib/json-value.c +++ b/json-glib/json-value.c @@ -186,6 +186,51 @@ json_value_seal (JsonValue *value) value->immutable = TRUE; } +guint +json_value_hash (gconstpointer key) +{ + JsonValue *value; + guint value_hash; + guint type_hash; + + value = (JsonValue *) key; + + /* Hash the type and value separately. + * Use the top 3 bits to store the type. */ + type_hash = value->type << (sizeof (guint) * 8 - 3); + + switch (value->type) + { + case JSON_VALUE_NULL: + value_hash = 0; + break; + case JSON_VALUE_BOOLEAN: + value_hash = json_value_get_boolean (value) ? 1 : 0; + break; + case JSON_VALUE_STRING: + value_hash = json_string_hash (json_value_get_string (value)); + break; + case JSON_VALUE_INT: { + gint64 v = json_value_get_int (value); + value_hash = g_int64_hash (&v); + break; + } + case JSON_VALUE_DOUBLE: { + gdouble v = json_value_get_double (value); + value_hash = g_double_hash (&v); + break; + } + case JSON_VALUE_INVALID: + default: + g_assert_not_reached (); + } + + /* Mask out the top 3 bits of the @value_hash. */ + value_hash &= ~(7 << (sizeof (guint) * 8 - 3)); + + return (type_hash | value_hash); +} + #define _JSON_VALUE_DEFINE_SET(Type,EType,CType,VField) \ void \ json_value_set_##Type (JsonValue *value, CType VField) \ |