summaryrefslogtreecommitdiff
path: root/rts/Hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/Hash.c')
-rw-r--r--rts/Hash.c33
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.
* -------------------------------------------------------------------------- */