diff options
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Hash.c | 41 | ||||
-rw-r--r-- | rts/Hash.h | 10 | ||||
-rw-r--r-- | rts/Linker.c | 2 | ||||
-rw-r--r-- | rts/SPT.c | 20 |
4 files changed, 73 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) { diff --git a/rts/Hash.h b/rts/Hash.h index d22caba555..0d9df2ea98 100644 --- a/rts/Hash.h +++ b/rts/Hash.h @@ -9,6 +9,10 @@ #ifndef HASH_H #define HASH_H +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + #include "BeginPrivate.h" typedef struct hashtable HashTable; /* abstract */ @@ -27,6 +31,10 @@ int keyCountHashTable (HashTable *table); */ HashTable * allocStrHashTable ( void ); +/* Hash table access where the keys are fingerprints {uint64_t[2]} + */ +HashTable * allocFpHashTable ( void ); + #define lookupStrHashTable(table, key) \ (lookupHashTable(table, (StgWord)key)) @@ -42,6 +50,8 @@ typedef int CompareFunction(StgWord key1, StgWord key2); HashTable * allocHashTable_(HashFunction *hash, CompareFunction *compare); int hashWord(HashTable *table, StgWord key); int hashStr(HashTable *table, char *key); +int hashFingerprint(HashTable *table, uint64_t* key); + /* Freeing hash tables */ diff --git a/rts/Linker.c b/rts/Linker.c index 2c74a0dd35..0e2f3bd8e7 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -1414,6 +1414,8 @@ typedef struct _RtsSymbolVal { SymI_HasProto(stopProfTimer) \ SymI_HasProto(atomic_inc) \ SymI_HasProto(atomic_dec) \ + SymI_HasProto(hs_spt_lookup) \ + SymI_HasProto(hs_spt_insert) \ RTS_USER_SIGNALS_SYMBOLS \ RTS_INTCHAR_SYMBOLS diff --git a/rts/SPT.c b/rts/SPT.c new file mode 100644 index 0000000000..63a3b12d4e --- /dev/null +++ b/rts/SPT.c @@ -0,0 +1,20 @@ +/* + * (c)2014 Tweag I/O + */ + +#include "Rts.h" +#include "Hash.h" + +static HashTable * spt = NULL; + +void hs_spt_insert(StgWord64 key[2],void *spe_closure) { + if (spt == NULL) + spt = allocFpHashTable(); + + getStablePtr(spe_closure); + insertHashTable(spt, (StgWord)key, spe_closure); +} + +StgPtr hs_spt_lookup(StgWord64 key[2]) { + return lookupHashTable(spt, (StgWord)key); +} |