diff options
Diffstat (limited to 'rts/Hash.c')
-rw-r--r-- | rts/Hash.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/rts/Hash.c b/rts/Hash.c index 1f8c0ca00c..8f32ac3076 100644 --- a/rts/Hash.c +++ b/rts/Hash.c @@ -198,9 +198,11 @@ lookupHashTable(const HashTable *table, StgWord key) segment = bucket / HSEGSIZE; index = bucket % HSEGSIZE; - for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) - if (table->compare(hl->key, key)) + CompareFunction *cmp = table->compare; + for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + if (cmp(hl->key, key)) return (void *) hl->data; + } /* It's not there */ return NULL; @@ -374,6 +376,33 @@ freeHashTable(HashTable *table, void (*freeDataFun)(void *) ) } /* ----------------------------------------------------------------------------- + * Map a function over all the keys/values in a HashTable + * -------------------------------------------------------------------------- */ + +void +mapHashTable(HashTable *table, void *data, MapHashFn fn) +{ + long segment; + long index; + HashList *hl; + + /* The last bucket with something in it is table->max + table->split - 1 */ + segment = (table->max + table->split - 1) / HSEGSIZE; + index = (table->max + table->split - 1) % HSEGSIZE; + + while (segment >= 0) { + while (index >= 0) { + for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + fn(data, hl->key, hl->data); + } + index--; + } + segment--; + index = HSEGSIZE - 1; + } +} + +/* ----------------------------------------------------------------------------- * When we initialize a hash table, we set up the first segment as well, * initializing all of the first segment's hash buckets to NULL. * -------------------------------------------------------------------------- */ |