AFFEND static void hashtable_expand(arc *c, value hash) { unsigned int hv, index, i, j, nhashbits; value oldtbl, newtbl, e; nhashbits = HASH_BITS(hash) + 1; newtbl = arc_mkvector(c, HASHSIZE(nhashbits)); ((struct cell *)newtbl)->_type = T_TABLEVEC; for (i=0; i<HASHSIZE(nhashbits); i++) XVINDEX(newtbl, i) = CUNBOUND; oldtbl = HASH_TABLE(hash); /* Search for active keys and move them into the new table */ for (i=0; i<VECLEN(oldtbl); i++) { e = VINDEX(oldtbl, i); if (EMPTYP(e)) continue; /* remove the old link now that we have a copy */ SVINDEX(oldtbl, i, CUNBOUND); /* insert the old key into the new table */ hv = (unsigned int)FIX2INT(BHASHVAL(e)); index = hv & HASHMASK(nhashbits); for (j=0; !EMPTYP(VINDEX(newtbl, index)); j++) index = (index + PROBE(j)) & HASHMASK(nhashbits); BTABLE(e) = newtbl; XVINDEX(newtbl, index) = e; SBINDEX(e, index); /* change index */ SVINDEX(oldtbl, i, CUNBOUND); } SET_HASHBITS(hash, nhashbits); SET_LLIMIT(hash, (HASHSIZE(nhashbits)*MAX_LOAD_FACTOR) / 100); HASH_TABLE(hash) = newtbl; }
static void * assoc_maintenance_thread(void *arg) { uint32_t i, hv; struct item_slh *old_bucket, *new_bucket; struct item *it, *next; while (run_maintenance_thread) { /* * Lock the cache, and bulk move multiple buckets to the new * hash table */ pthread_mutex_lock(&cache_lock); for (i = 0; i < nhash_move_size && expanding == 1; i++) { old_bucket = &old_hashtable[expand_bucket]; SLIST_FOREACH_SAFE(it, old_bucket, h_sle, next) { hv = hash(item_key(it), it->nkey, 0); new_bucket = &primary_hashtable[hv & HASHMASK(hash_power)]; SLIST_REMOVE(old_bucket, it, item, h_sle); SLIST_INSERT_HEAD(new_bucket, it, h_sle); } expand_bucket++; if (expand_bucket == HASHSIZE(hash_power - 1)) { expanding = 0; mc_free(old_hashtable); nbyte_old = 0; } } if (expanding == 0) { /* we are done expanding, just wait for the next invocation */ pthread_cond_wait(&maintenance_cond, &cache_lock); } pthread_mutex_unlock(&cache_lock); }
static struct item_slh * _get_bucket(const char *key, size_t klen, struct hash_table *ht) { return &(ht->table[hash_lookup3(key, klen, 0) & HASHMASK(ht->hash_power)]); }