diff options
author | Petri Lehtinen <petri@digip.org> | 2010-02-09 20:51:25 +0200 |
---|---|---|
committer | Petri Lehtinen <petri@digip.org> | 2010-02-09 20:51:25 +0200 |
commit | 307167fb66e83946dca6d1b22bc43ae9fd406a16 (patch) | |
tree | 0aedcc5091986527eac78a22b1bb3581f7ef539a /src | |
parent | 8d75235ff22dc4aced697e198c3c024f1f4b88fe (diff) | |
download | jansson-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.c | 40 |
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; } |