static int hashtable_do_rehash(hashtable_t *hashtable) { list_t *list, *next; pair_t *pair; size_t i, index, new_size; jsonp_free(hashtable->buckets); hashtable->num_buckets++; new_size = num_buckets(hashtable); hashtable->buckets = jsonp_malloc(new_size * sizeof(bucket_t)); if(!hashtable->buckets) return -1; for(i = 0; i < num_buckets(hashtable); i++) { hashtable->buckets[i].first = hashtable->buckets[i].last = &hashtable->list; } list = hashtable->list.next; list_init(&hashtable->list); for(; list != &hashtable->list; list = next) { next = list->next; pair = list_to_pair(list); index = pair->hash % new_size; insert_to_bucket(hashtable, &hashtable->buckets[index], &pair->list); } return 0; }
int hashtable_set(hashtable_t *hashtable, const char *key, size_t serial, json_t *value) { pair_t *pair; bucket_t *bucket; size_t hash, index; /* rehash if the load ratio exceeds 1 */ if(hashtable->size >= hashsize(hashtable->order)) if(hashtable_do_rehash(hashtable)) return -1; hash = hash_str(key); index = hash & hashmask(hashtable->order); bucket = &hashtable->buckets[index]; pair = hashtable_find_pair(hashtable, bucket, key, hash); if(pair) { json_decref(pair->value); pair->value = value; } else { /* offsetof(...) returns the size of pair_t without the last, flexible member. This way, the correct amount is allocated. */ size_t len = strlen(key); if(len >= (size_t)-1 - offsetof(pair_t, key)) { /* Avoid an overflow if the key is very long */ return -1; } pair = jsonp_malloc(offsetof(pair_t, key) + len + 1); if(!pair) return -1; pair->hash = hash; pair->serial = serial; strncpy(pair->key, key, len + 1); pair->value = value; list_init(&pair->list); insert_to_bucket(hashtable, bucket, &pair->list); hashtable->size++; } return 0; }
int hashtable_set(hashtable_t *hashtable, const char *key, size_t serial, json_t *value) { pair_t *pair; bucket_t *bucket; size_t hash, index; /* rehash if the load ratio exceeds 1 */ if(hashtable->size >= num_buckets(hashtable)) if(hashtable_do_rehash(hashtable)) return -1; hash = hash_str(key); index = hash % num_buckets(hashtable); bucket = &hashtable->buckets[index]; pair = hashtable_find_pair(hashtable, bucket, key, hash); if(pair) { json_decref(pair->value); pair->value = value; } else { /* offsetof(...) returns the size of pair_t without the last, flexible member. This way, the correct amount is allocated. */ pair = jsonp_malloc(offsetof(pair_t, key) + strlen(key) + 1); if(!pair) return -1; pair->hash = hash; pair->serial = serial; strcpy(pair->key, key); pair->value = value; list_init(&pair->list); insert_to_bucket(hashtable, bucket, &pair->list); hashtable->size++; } return 0; }
int hashtable_set(hashtable_t *hashtable, void *key, void *value) { pair_t *pair; bucket_t *bucket; unsigned int hash, index; /* rehash if the load ratio exceeds 1 */ if(hashtable->size >= num_buckets(hashtable)) if(hashtable_do_rehash(hashtable)) return -1; hash = hashtable->hash_key(key); index = hash % num_buckets(hashtable); bucket = &hashtable->buckets[index]; pair = hashtable_find_pair(hashtable, bucket, key, hash); 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); insert_to_bucket(hashtable, bucket, &pair->list); hashtable->size++; } return 0; }