Use https links in user-facing startup and error messages
[ghc.git] / rts / Hash.c
index 1f8c0ca..658187b 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "Hash.h"
 #include "RtsUtils.h"
+#include "xxhash.h"
 
 #include <string.h>
 
@@ -76,20 +77,17 @@ hashWord(const HashTable *table, StgWord key)
 }
 
 int
-hashStr(const HashTable *table, char *key)
+hashStr(const HashTable *table, StgWord w)
 {
-    int h, bucket;
-    char *s;
-
-    s = key;
-    for (h=0; *s; s++) {
-        h *= 128;
-        h += *s;
-        h = h % 1048583;        /* some random large prime */
-    }
+    const char *key = (char*) w;
+#ifdef x86_64_HOST_ARCH
+    StgWord h = XXH64 (key, strlen(key), 1048583);
+#else
+    StgWord h = XXH32 (key, strlen(key), 1048583);
+#endif
 
     /* Mod the size of the hash table (a power of 2) */
-    bucket = h & table->mask1;
+    int bucket = h & table->mask1;
 
     if (bucket < table->split) {
         /* Mod the size of the expanded hash table (also a power of 2) */
@@ -198,9 +196,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 +374,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.
  * -------------------------------------------------------------------------- */
@@ -414,8 +441,7 @@ allocHashTable(void)
 HashTable *
 allocStrHashTable(void)
 {
-    return allocHashTable_((HashFunction *)hashStr,
-                           (CompareFunction *)compareStr);
+    return allocHashTable_(hashStr, compareStr);
 }
 
 void