aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPetri Lehtinen <petri@digip.org>2010-02-09 20:51:25 +0200
committerPetri Lehtinen <petri@digip.org>2010-02-09 20:51:25 +0200
commit307167fb66e83946dca6d1b22bc43ae9fd406a16 (patch)
tree0aedcc5091986527eac78a22b1bb3581f7ef539a /src
parent8d75235ff22dc4aced697e198c3c024f1f4b88fe (diff)
downloadjansson-307167fb66e83946dca6d1b22bc43ae9fd406a16.zip
jansson-307167fb66e83946dca6d1b22bc43ae9fd406a16.tar.gz
jansson-307167fb66e83946dca6d1b22bc43ae9fd406a16.tar.bz2
Optimize hashtable_set()
If a key already exists in the hashtable, use the existing pair changing its value instead of removing the old one and allocating a new pair.
Diffstat (limited to 'src')
-rw-r--r--src/hashtable.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/src/hashtable.c b/src/hashtable.c
index 0d4a9f2..4b58b26 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -247,31 +247,39 @@ int hashtable_set(hashtable_t *hashtable, void *key, void *value)
bucket_t *bucket;
unsigned int hash, index;
- hash = hashtable->hash_key(key);
-
- /* if the key already exists, delete it */
- hashtable_do_del(hashtable, key, hash);
-
/* rehash if the load ratio exceeds 1 */
if(hashtable->size >= num_buckets(hashtable))
if(hashtable_do_rehash(hashtable))
return -1;
- pair = malloc(sizeof(pair_t));
- if(!pair)
- return -1;
-
- pair->key = key;
- pair->value = value;
- pair->hash = hash;
- list_init(&pair->list);
-
+ hash = hashtable->hash_key(key);
index = hash % num_buckets(hashtable);
bucket = &hashtable->buckets[index];
+ pair = hashtable_find_pair(hashtable, bucket, key, hash);
- insert_to_bucket(hashtable, bucket, &pair->list);
+ if(pair)
+ {
+ if(hashtable->free_key)
+ hashtable->free_key(key);
+ if(hashtable->free_value)
+ hashtable->free_value(pair->value);
+ pair->value = value;
+ }
+ else
+ {
+ pair = malloc(sizeof(pair_t));
+ if(!pair)
+ return -1;
+
+ pair->key = key;
+ pair->value = value;
+ pair->hash = hash;
+ list_init(&pair->list);
- hashtable->size++;
+ insert_to_bucket(hashtable, bucket, &pair->list);
+
+ hashtable->size++;
+ }
return 0;
}