summaryrefslogtreecommitdiff
path: root/json-glib/json-value.c
diff options
context:
space:
mode:
authorPhilip Withnall <philip.withnall@collabora.co.uk>2016-03-01 15:01:07 +0000
committerEmmanuele Bassi <ebassi@gnome.org>2016-03-01 15:01:07 +0000
commit6ddbc94c9888e5ddcd1cbb15845d2f1b5524b3ed (patch)
treecba11bd7504d1f33e48209d2d67b2fd5f0ef00eb /json-glib/json-value.c
parent1de237a502ceee96df7091c2df4492b8bc08b2c5 (diff)
downloadjson-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.c45
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) \