Bug 73540. Make sure [JS|PL]DHashTable clear live entries while finalizing. Remove induction variable from [JS|PL]_DHashEnumerate() along the way. r=brendan, sr=shaver

git-svn-id: svn://10.0.0.236/trunk@90488 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
waterson%netscape.com 2001-03-27 06:24:25 +00:00
parent bce13671b2
commit 03cb2db790
2 changed files with 64 additions and 24 deletions

View File

@ -196,13 +196,6 @@ JS_DHashTableInit(JSDHashTable *table, JSDHashTableOps *ops, void *data,
return JS_TRUE;
}
JS_PUBLIC_API(void)
JS_DHashTableFinish(JSDHashTable *table)
{
table->ops->finalize(table);
table->ops->freeTable(table, table->entryStore);
}
/*
* Double hashing needs the second hash code to be relatively prime to table
* size, so we simply make hash2 odd.
@ -220,6 +213,31 @@ JS_DHashTableFinish(JSDHashTable *table)
#define ADDRESS_ENTRY(table, index) \
((JSDHashEntryHdr *)((table)->entryStore + (index) * (table)->entrySize))
JS_PUBLIC_API(void)
JS_DHashTableFinish(JSDHashTable *table)
{
char *entryAddr, *entryLimit;
uint32 entrySize;
table->ops->finalize(table);
/* Clear any remaining live entries. */
entryAddr = table->entryStore;
entrySize = table->entrySize;
entryLimit = entryAddr + JS_BIT(table->sizeLog2) * entrySize;
while (entryAddr < entryLimit) {
JSDHashEntryHdr *entry = (JSDHashEntryHdr *)entryAddr;
if (ENTRY_IS_LIVE(entry)) {
METER(table->stats.removeEnums++);
table->ops->clearEntry(table, entry);
}
entryAddr += entrySize;
}
table->ops->freeTable(table, table->entryStore);
}
static JSDHashEntryHdr *
SearchTable(JSDHashTable *table, const void *key, JSDHashNumber keyHash)
{
@ -424,18 +442,20 @@ JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry)
JS_PUBLIC_API(uint32)
JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg)
{
char *entryAddr;
uint32 i, j, capacity, entrySize;
char *entryAddr, *entryLimit;
uint32 i, capacity, entrySize;
JSDHashEntryHdr *entry;
JSDHashOperator op;
entryAddr = table->entryStore;
entrySize = table->entrySize;
capacity = JS_BIT(table->sizeLog2);
for (i = j = 0; i < capacity; i++) {
entryLimit = entryAddr + capacity * entrySize;
i = 0;
while (entryAddr < entryLimit) {
entry = (JSDHashEntryHdr *)entryAddr;
if (ENTRY_IS_LIVE(entry)) {
op = etor(table, entry, j++, arg);
op = etor(table, entry, i++, arg);
if (op & JS_DHASH_REMOVE) {
METER(table->stats.removeEnums++);
JS_DHashTableRawRemove(table, entry);
@ -457,7 +477,7 @@ JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg)
JS_CeilingLog2(capacity) - table->sizeLog2,
NULL);
}
return j;
return i;
}
#ifdef JS_DHASHMETER

View File

@ -197,13 +197,6 @@ PL_DHashTableInit(PLDHashTable *table, PLDHashTableOps *ops, void *data,
return PR_TRUE;
}
PR_IMPLEMENT(void)
PL_DHashTableFinish(PLDHashTable *table)
{
table->ops->finalize(table);
table->ops->freeTable(table, table->entryStore);
}
/*
* Double hashing needs the second hash code to be relatively prime to table
* size, so we simply make hash2 odd.
@ -221,6 +214,31 @@ PL_DHashTableFinish(PLDHashTable *table)
#define ADDRESS_ENTRY(table, index) \
((PLDHashEntryHdr *)((table)->entryStore + (index) * (table)->entrySize))
PR_IMPLEMENT(void)
PL_DHashTableFinish(PLDHashTable *table)
{
char *entryAddr, *entryLimit;
PRUint32 entrySize;
table->ops->finalize(table);
/* Clear any remaining live entries. */
entryAddr = table->entryStore;
entrySize = table->entrySize;
entryLimit = entryAddr + PR_BIT(table->sizeLog2) * entrySize;
while (entryAddr < entryLimit) {
PLDHashEntryHdr *entry = (PLDHashEntryHdr *)entryAddr;
if (ENTRY_IS_LIVE(entry)) {
METER(table->stats.removeEnums++);
table->ops->clearEntry(table, entry);
}
entryAddr += entrySize;
}
table->ops->freeTable(table, table->entryStore);
}
static PLDHashEntryHdr *
SearchTable(PLDHashTable *table, const void *key, PLDHashNumber keyHash)
{
@ -425,18 +443,20 @@ PL_DHashTableRawRemove(PLDHashTable *table, PLDHashEntryHdr *entry)
PR_IMPLEMENT(PRUint32)
PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg)
{
char *entryAddr;
PRUint32 i, j, capacity, entrySize;
char *entryAddr, *entryLimit;
PRUint32 i, capacity, entrySize;
PLDHashEntryHdr *entry;
PLDHashOperator op;
entryAddr = table->entryStore;
entrySize = table->entrySize;
capacity = PR_BIT(table->sizeLog2);
for (i = j = 0; i < capacity; i++) {
entryLimit = entryAddr + capacity * entrySize;
i = 0;
while (entryAddr < entryLimit) {
entry = (PLDHashEntryHdr *)entryAddr;
if (ENTRY_IS_LIVE(entry)) {
op = etor(table, entry, j++, arg);
op = etor(table, entry, i++, arg);
if (op & PL_DHASH_REMOVE) {
METER(table->stats.removeEnums++);
PL_DHashTableRawRemove(table, entry);
@ -458,7 +478,7 @@ PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg)
PR_CeilingLog2(capacity) - table->sizeLog2,
NULL);
}
return j;
return i;
}
#ifdef PL_DHASHMETER