JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he) { uint32 n; *hep = he->next; ht->allocOps->freeEntry(ht->allocPriv, he, HT_FREE_ENTRY); /* Shrink table if it's underloaded */ n = NBUCKETS(ht); if (--ht->nentries < UNDERLOADED(n)) { Resize(ht, ht->shift + 1); #ifdef JS_HASHMETER ht->nshrinks++; #endif } }
JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg) { JSHashEntry *he, **hep, **bucket; uint32 nlimit, n, nbuckets, newlog2; int rv; nlimit = ht->nentries; n = 0; for (bucket = ht->buckets; n != nlimit; ++bucket) { hep = bucket; while ((he = *hep) != NULL) { JS_ASSERT(n < nlimit); rv = f(he, n, arg); n++; if (rv & HT_ENUMERATE_REMOVE) { *hep = he->next; ht->allocOps->freeEntry(ht->allocPriv, he, HT_FREE_ENTRY); --ht->nentries; } else { hep = &he->next; } if (rv & HT_ENUMERATE_STOP) { goto out; } } } out: /* Shrink table if removal of entries made it underloaded */ if (ht->nentries != nlimit) { JS_ASSERT(ht->nentries < nlimit); nbuckets = NBUCKETS(ht); if (MINBUCKETS < nbuckets && ht->nentries < UNDERLOADED(nbuckets)) { newlog2 = JS_CeilingLog2(ht->nentries); if (newlog2 < MINBUCKETSLOG2) newlog2 = MINBUCKETSLOG2; /* Check that we really shrink the table. */ JS_ASSERT(JS_HASH_BITS - ht->shift > newlog2); Resize(ht, JS_HASH_BITS - newlog2); } } return (int)n; }
PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he) { PRUint32 i, n; PLHashEntry *next, **oldbuckets; PRSize nb; *hep = he->next; (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY); /* Shrink table if it's underloaded */ n = NBUCKETS(ht); if (--ht->nentries < UNDERLOADED(n)) { oldbuckets = ht->buckets; nb = n * sizeof(PLHashEntry*) / 2; ht->buckets = (PLHashEntry**)( (*ht->allocOps->allocTable)(ht->allocPriv, nb)); if (!ht->buckets) { ht->buckets = oldbuckets; return; } memset(ht->buckets, 0, nb); #ifdef HASHMETER ht->nshrinks++; #endif ht->shift++; for (i = 0; i < n; i++) { for (he = oldbuckets[i]; he; he = next) { next = he->next; hep = PL_HashTableRawLookup(ht, he->keyHash, he->key); PR_ASSERT(*hep == 0); he->next = 0; *hep = he; } } #ifdef DEBUG memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); #endif (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); } }