| 1 | #include "mycpp/hash.h"
 | 
| 2 | 
 | 
| 3 | #include "mycpp/gc_str.h"
 | 
| 4 | #include "mycpp/gc_tuple.h"
 | 
| 5 | 
 | 
| 6 | unsigned fnv1(const char* data, int len) {
 | 
| 7 |   // FNV-1 from http://www.isthe.com/chongo/tech/comp/fnv/#FNV-1
 | 
| 8 |   unsigned h = 2166136261;     // 32-bit FNV-1 offset basis
 | 
| 9 |   constexpr int p = 16777619;  // 32-bit FNV-1 prime
 | 
| 10 |   for (int i = 0; i < len; i++) {
 | 
| 11 |     h *= p;
 | 
| 12 |     // log("1. h = %d", h);
 | 
| 13 |     h ^= data[i];
 | 
| 14 |     // log("2. h = %d", h);
 | 
| 15 |   }
 | 
| 16 |   return h;
 | 
| 17 | }
 | 
| 18 | 
 | 
| 19 | unsigned hash_key(BigStr* s) {
 | 
| 20 |   return s->hash(fnv1);
 | 
| 21 | }
 | 
| 22 | 
 | 
| 23 | unsigned hash_key(int n) {
 | 
| 24 |   return fnv1(reinterpret_cast<const char*>(&n), sizeof(n));
 | 
| 25 | }
 | 
| 26 | 
 | 
| 27 | unsigned hash_key(mops::BigInt n) {
 | 
| 28 |   // Bug fix: our dict sizing is a power of 2, and we don't want integers in
 | 
| 29 |   // the workload to interact badly with it.
 | 
| 30 |   return fnv1(reinterpret_cast<const char*>(&n), sizeof(n));
 | 
| 31 | }
 | 
| 32 | 
 | 
| 33 | unsigned hash_key(void* p) {
 | 
| 34 |   // e.g. for Dict<Token*, int>, hash the pointer itself, which means we use
 | 
| 35 |   // object IDENTITY, not value.
 | 
| 36 |   return fnv1(reinterpret_cast<const char*>(&p), sizeof(void*));
 | 
| 37 | }
 | 
| 38 | 
 | 
| 39 | unsigned hash_key(Tuple2<int, int>* t1) {
 | 
| 40 |   return t1->at0() + t1->at1();
 | 
| 41 | }
 | 
| 42 | 
 | 
| 43 | unsigned hash_key(Tuple2<BigStr*, int>* t1) {
 | 
| 44 |   return t1->at0()->hash(fnv1) + t1->at1();
 | 
| 45 | }
 |