]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
reduce duplicate hash computation in json_object_object_add()
authorRainer Gerhards <rgerhards@adiscon.com>
Tue, 22 Sep 2015 17:07:30 +0000 (19:07 +0200)
committerRainer Gerhards <rgerhards@adiscon.com>
Tue, 22 Sep 2015 17:07:30 +0000 (19:07 +0200)
This can be a very considerable performance saver.

json_object.c
linkhash.c
linkhash.h

index 8ed02398fb370ea834c6a27e56e2c8edc075df1d..e06c7acc411f251cecbecc396c449ababdbb0e45 100644 (file)
@@ -403,10 +403,11 @@ void json_object_object_add(struct json_object* jso, const char *key,
        // and re-adding it, so the existing key remains valid.
        json_object *existing_value = NULL;
        struct lh_entry *existing_entry;
-       existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
+       const unsigned long hash = lh_get_hash(jso->o.c_object, (void*)key);
+       existing_entry = lh_table_lookup_entry_w_hash(jso->o.c_object, (void*)key, hash);
        if (!existing_entry)
        {
-               lh_table_insert(jso->o.c_object, strdup(key), val);
+               lh_table_insert_w_hash(jso->o.c_object, strdup(key), val, hash);
                return;
        }
        existing_value = (void *)existing_entry->v;
@@ -415,6 +416,7 @@ void json_object_object_add(struct json_object* jso, const char *key,
        existing_entry->v = val;
 }
 
+
 int json_object_object_length(struct json_object *jso)
 {
        return lh_table_length(jso->o.c_object);
index 712c3879e7081a17b35b9c73f7953294d98d378c..b4763cfc5724a2444276cfc3da12fab239753298 100644 (file)
@@ -490,14 +490,13 @@ void lh_table_free(struct lh_table *t)
 }
 
 
-int lh_table_insert(struct lh_table *t, void *k, const void *v)
+int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h)
 {
-       unsigned long h, n;
+       unsigned long n;
 
        t->inserts++;
        if(t->count >= t->size * LH_LOAD_FACTOR) lh_table_resize(t, t->size * 2);
 
-       h = t->hash_fn(k);
        n = h % t->size;
 
        while( 1 ) {
@@ -522,11 +521,14 @@ int lh_table_insert(struct lh_table *t, void *k, const void *v)
 
        return 0;
 }
+int lh_table_insert(struct lh_table *t, void *k, const void *v)
+{
+       return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k));
+}
 
 
-struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
+struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h)
 {
-       unsigned long h = t->hash_fn(k);
        unsigned long n = h % t->size;
        int count = 0;
 
@@ -541,6 +543,10 @@ struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
        return NULL;
 }
 
+struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
+{
+       return lh_table_lookup_entry_w_hash(t, k, lh_get_hash(t, k));
+}
 
 const void* lh_table_lookup(struct lh_table *t, const void *k)
 {
index 950d09f35d70cf026852c9d50cb85a3129944e3c..66f2d9785163499ce8500d7240064b5b88008e51 100644 (file)
@@ -231,6 +231,20 @@ extern void lh_table_free(struct lh_table *t);
 extern int lh_table_insert(struct lh_table *t, void *k, const void *v);
 
 
+/**
+ * Insert a record into the table. This one accepts the key's hash in additon
+ * to the key. This is an exension to support functions that need to calculate
+ * the hash several times and allows them to do it just once and then pass
+ * in the hash to all utility functions. Depending on use case, this can be a 
+ * very considerate performance improvement.
+ * @param t the table to insert into.
+ * @param k a pointer to the key to insert.
+ * @param v a pointer to the value to insert.
+ * @param h hash value of the key to insert
+ */
+extern int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h);
+
+
 /**
  * Lookup a record into the table.
  * @param t the table to lookup
@@ -239,6 +253,19 @@ extern int lh_table_insert(struct lh_table *t, void *k, const void *v);
  */
 extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k);
 
+/**
+ * Lookup a record into the table. This one accepts the key's hash in additon
+ * to the key. This is an exension to support functions that need to calculate
+ * the hash several times and allows them to do it just once and then pass
+ * in the hash to all utility functions. Depending on use case, this can be a 
+ * very considerate performance improvement.
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @param h hash value of the key to lookup
+ * @return a pointer to the record structure of the value or NULL if it does not exist.
+ */
+extern struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h);
+
 /**
  * Lookup a record into the table
  * @param t the table to lookup
@@ -285,6 +312,22 @@ extern int lh_table_length(struct lh_table *t);
 void lh_abort(const char *msg, ...);
 void lh_table_resize(struct lh_table *t, int new_size);
 
+
+/**
+ * Calculate the hash of a key for a given table.
+ * This is an exension to support functions that need to calculate
+ * the hash several times and allows them to do it just once and then pass
+ * in the hash to all utility functions. Depending on use case, this can be a 
+ * very considerate performance improvement.
+ * @param t the table (used to obtain hash function)
+ * @param k a pointer to the key to lookup
+ * @return the key's hash
+ */
+static inline unsigned long lh_get_hash(const struct lh_table *t, const void *k)
+{
+       return t->hash_fn(k);
+}
+
 #ifdef __cplusplus
 }
 #endif