diff options
Diffstat (limited to 'rts/Hash.c')
-rw-r--r-- | rts/Hash.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/rts/Hash.c b/rts/Hash.c index b91d70c219..1c167168d2 100644 --- a/rts/Hash.c +++ b/rts/Hash.c @@ -16,6 +16,10 @@ #include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + #define HSEGSIZE 1024 /* Size of a single hash table segment */ /* Also the minimum size of a hash table */ #define HDIRSIZE 1024 /* Size of the segment directory */ @@ -99,6 +103,31 @@ hashStr(HashTable *table, char *key) return bucket; } +int +hashFingerprint(HashTable *table, uint64_t *key) +{ + int h, bucket; + char *s; + + s = (char *)key; + size_t i; + for (i=0, h=0; i< sizeof(uint64_t)*2; ++i, ++s) { + h *= 128; + h += *s; + h = h % 1048583; /* some random large prime */ + } + + /* Mod the size of the hash table (a power of 2) */ + bucket = h & table->mask1; + + if (bucket < table->split) { + /* Mod the size of the expanded hash table (also a power of 2) */ + bucket = h & table->mask2; + } + + return bucket; +} + static int compareWord(StgWord key1, StgWord key2) { @@ -111,6 +140,11 @@ compareStr(StgWord key1, StgWord key2) return (strcmp((char *)key1, (char *)key2) == 0); } +static int +compareFingerprint(uint64_t *ptra, uint64_t *ptrb) { + return (ptra[0]-ptrb[0]==0ULL)?((ptra[1] - ptrb[1] == 0ULL)?0:1):1; +} + /* ----------------------------------------------------------------------------- * Allocate a new segment of the dynamically growing hash table. @@ -387,6 +421,13 @@ allocStrHashTable(void) (CompareFunction *)compareStr); } +HashTable * +allocFpHashTable(void) +{ + return allocHashTable_((HashFunction *)hashFingerprint, + (CompareFunction *)compareFingerprint); +} + void exitHashTable(void) { |