in worker.c [279:323]
static void hdelete(struct hashtable *h, struct bucket *victim)
{
struct bucket *old, *new;
unsigned long origidx, idx;
fatal_on(!victim->ncrx, "Attempt to delete free bucket\n");
if (!timerlist_empty(&victim->timernode))
timerlist_del(&victim->timernode);
h->load--;
ncrx_destroy(victim->ncrx);
memset(victim, 0, sizeof(*victim));
/*
* There's potential to be clever here, but for now just be pedantic and
* rebucket any potentially probed entries.
*/
origidx = victim - h->table;
idx = origidx;
while (h->table[idx].ncrx) {
old = &h->table[idx];
new = hlookup(h, &old->src);
if (new != old) {
memcpy(new, old, sizeof(*new));
memset(old, 0, sizeof(*old));
/*
* If the timernode wasn't on a list, initialize it as
* empty for the new bucket. If it was, update its
* neighbors to point to the new bucket.
*/
if (new->timernode.next == &old->timernode) {
timerlist_init(&new->timernode);
} else {
new->timernode.next->prev = &new->timernode;
new->timernode.prev->next = &new->timernode;
}
}
idx = htable_mask(idx + 1, h->order);
fatal_on(idx == origidx, "Infinite loop in hdelete()\n");
}
}