MCPcopy Create free account
hub / github.com/RedisGraph/RedisGraph / HashTableRehash

Function HashTableRehash

src/util/dict.c:263–321  ·  view source on GitHub ↗

Performs N steps of incremental rehashing. Returns 1 if there are still * keys to move from the old to the new hash table, otherwise 0 is returned. * * Note that a rehashing step consists in moving a bucket (that may have more * than one key as we use chaining) from the old to the new hash table, however * since part of the hash table may be composed of empty spaces, it is not * guaranteed t

Source from the content-addressed store, hash-verified

261 * will visit at max N*10 empty buckets in total, otherwise the amount of
262 * work it does would be unbound and the function may block for a long time. */
263int HashTableRehash(dict *d, int n) {
264 int empty_visits = n*10; /* Max number of empty buckets to visit. */
265 if (dict_can_resize == DICT_RESIZE_FORBID || !dictIsRehashing(d)) return 0;
266 if (dict_can_resize == DICT_RESIZE_AVOID &&
267 (DICTHT_SIZE(d->ht_size_exp[1]) / DICTHT_SIZE(d->ht_size_exp[0]) < dict_force_resize_ratio))
268 {
269 return 0;
270 }
271
272 while(n-- && d->ht_used[0] != 0) {
273 dictEntry *de, *nextde;
274
275 /* Note that rehashidx can't overflow as we are sure there are more
276 * elements because ht[0].used != 0 */
277 assert(DICTHT_SIZE(d->ht_size_exp[0]) > (unsigned long)d->rehashidx);
278 while(d->ht_table[0][d->rehashidx] == NULL) {
279 d->rehashidx++;
280 if (--empty_visits == 0) return 1;
281 }
282 de = d->ht_table[0][d->rehashidx];
283 /* Move all the keys in this bucket from the old to the new hash HT */
284 while(de) {
285 uint64_t h;
286
287 nextde = de->next;
288 /* Get the index in the new hash table */
289 if (d->ht_size_exp[1] > d->ht_size_exp[0]) {
290 h = dictHashKey(d, de->key) & DICTHT_SIZE_MASK(d->ht_size_exp[1]);
291 } else {
292 /* We're shrinking the table. The tables sizes are powers of
293 * two, so we simply mask the bucket index in the larger table
294 * to get the bucket index in the smaller table. */
295 h = d->rehashidx & DICTHT_SIZE_MASK(d->ht_size_exp[1]);
296 }
297 de->next = d->ht_table[1][h];
298 d->ht_table[1][h] = de;
299 d->ht_used[0]--;
300 d->ht_used[1]++;
301 de = nextde;
302 }
303 d->ht_table[0][d->rehashidx] = NULL;
304 d->rehashidx++;
305 }
306
307 /* Check if we already rehashed the whole table... */
308 if (d->ht_used[0] == 0) {
309 free(d->ht_table[0]);
310 /* Copy the new ht onto the old one */
311 d->ht_table[0] = d->ht_table[1];
312 d->ht_used[0] = d->ht_used[1];
313 d->ht_size_exp[0] = d->ht_size_exp[1];
314 _dictReset(d, 1);
315 d->rehashidx = -1;
316 return 0;
317 }
318
319 /* More to rehash... */
320 return 1;

Callers 2

_dictRehashStepFunction · 0.85

Calls 1

_dictResetFunction · 0.85

Tested by

no test coverage detected