| 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 | }
|