diff --git a/src/dict.c b/src/dict.c index 541b2d066..f41575a99 100644 --- a/src/dict.c +++ b/src/dict.c @@ -238,7 +238,7 @@ int _dictExpand(dict *d, unsigned long size, int* malloc_failed) signed char new_ht_size_exp = _dictNextExp(size); /* Detect overflows */ - size_t newsize = 1ul<ht_table[0] == NULL) { - if (d->type->rehashingStarted) d->type->rehashingStarted(d); - if (d->type->rehashingCompleted) d->type->rehashingCompleted(d); - d->ht_size_exp[0] = new_ht_size_exp; - d->ht_used[0] = new_ht_used; - d->ht_table[0] = new_ht_table; - return DICT_OK; - } - - /* Prepare a second hash table for incremental rehashing */ + /* Prepare a second hash table for incremental rehashing. + * We do this even for the first initialization, so that we can trigger the + * rehashingStarted more conveniently, we will clean it up right after. */ d->ht_size_exp[1] = new_ht_size_exp; d->ht_used[1] = new_ht_used; d->ht_table[1] = new_ht_table; d->rehashidx = 0; if (d->type->rehashingStarted) d->type->rehashingStarted(d); - /* If the dict is empty, we finish rehashing ASAP.*/ - if (d->ht_used[0] == 0) { + + /* Is this the first initialization or is the first hash table empty? If so + * it's not really a rehashing, we can just set the first hash table so that + * it can accept keys. */ + if (d->ht_table[0] == NULL || d->ht_used[0] == 0) { if (d->type->rehashingCompleted) d->type->rehashingCompleted(d); - zfree(d->ht_table[0]); + if (d->ht_table[0]) zfree(d->ht_table[0]); d->ht_size_exp[0] = new_ht_size_exp; d->ht_used[0] = new_ht_used; d->ht_table[0] = new_ht_table; @@ -284,6 +278,7 @@ int _dictExpand(dict *d, unsigned long size, int* malloc_failed) d->rehashidx = -1; return DICT_OK; } + return DICT_OK; } @@ -1521,12 +1516,6 @@ dictEntry *dictFindEntryByPtrAndHash(dict *d, const void *oldptr, uint64_t hash) /* Provides the old and new ht size for a given dictionary during rehashing. This method * should only be invoked during initialization/rehashing. */ void dictRehashingInfo(dict *d, unsigned long long *from_size, unsigned long long *to_size) { - /* Expansion during initialization. */ - if (d->ht_size_exp[0] == -1) { - *from_size = DICTHT_SIZE(d->ht_size_exp[0]); - *to_size = DICTHT_SIZE(DICT_HT_INITIAL_EXP); - return; - } /* Invalid method usage if rehashing isn't ongoing. */ assert(dictIsRehashing(d)); *from_size = DICTHT_SIZE(d->ht_size_exp[0]); diff --git a/src/dict.h b/src/dict.h index 5b7daf915..334dc441e 100644 --- a/src/dict.h +++ b/src/dict.h @@ -222,7 +222,7 @@ unsigned long dictScan(dict *d, unsigned long v, dictScanFunction *fn, void *pri unsigned long dictScanDefrag(dict *d, unsigned long v, dictScanFunction *fn, dictDefragFunctions *defragfns, void *privdata); uint64_t dictGetHash(dict *d, const void *key); dictEntry *dictFindEntryByPtrAndHash(dict *d, const void *oldptr, uint64_t hash); -void dictRehashingInfo(dict *d, unsigned long long *from, unsigned long long *to); +void dictRehashingInfo(dict *d, unsigned long long *from_size, unsigned long long *to_size); size_t dictGetStatsMsg(char *buf, size_t bufsize, dictStats *stats, int full); dictStats* dictGetStatsHt(dict *d, int htidx, int full);