Search and remove an element. This is a helper function for * HashTableDelete() and HashTableUnlink(), please check the top comment * of those functions. */
| 473 | * HashTableDelete() and HashTableUnlink(), please check the top comment |
| 474 | * of those functions. */ |
| 475 | static dictEntry *dictGenericDelete(dict *d, const void *key, int nofree) { |
| 476 | uint64_t h, idx; |
| 477 | dictEntry *he, *prevHe; |
| 478 | int table; |
| 479 | |
| 480 | /* dict is empty */ |
| 481 | if (dictSize(d) == 0) return NULL; |
| 482 | |
| 483 | if (dictIsRehashing(d)) _dictRehashStep(d); |
| 484 | h = dictHashKey(d, key); |
| 485 | |
| 486 | for (table = 0; table <= 1; table++) { |
| 487 | idx = h & DICTHT_SIZE_MASK(d->ht_size_exp[table]); |
| 488 | he = d->ht_table[table][idx]; |
| 489 | prevHe = NULL; |
| 490 | while(he) { |
| 491 | if (key==he->key || dictCompareKeys(d, key, he->key)) { |
| 492 | /* Unlink the element from the list */ |
| 493 | if (prevHe) |
| 494 | prevHe->next = he->next; |
| 495 | else |
| 496 | d->ht_table[table][idx] = he->next; |
| 497 | if (!nofree) { |
| 498 | HashTableFreeUnlinkedEntry(d, he); |
| 499 | } |
| 500 | d->ht_used[table]--; |
| 501 | return he; |
| 502 | } |
| 503 | prevHe = he; |
| 504 | he = he->next; |
| 505 | } |
| 506 | if (!dictIsRehashing(d)) break; |
| 507 | } |
| 508 | return NULL; /* not found */ |
| 509 | } |
| 510 | |
| 511 | /* Remove an element, returning DICT_OK on success or DICT_ERR if the |
| 512 | * element was not found. */ |
no test coverage detected