49 inline uint32_t 
memHash(
const char* val, 
int len)
 
   52     uint64_t val64[4]; val64[0] = 0;
 
   53     memcpy(&val64[0], &val[len64], len & 7);
 
   54     uint64_t hashval[4] = {0,0,0,0};
 
   55     hashval[0] = val64[0]*16777619;
 
   57     for (
int i = 0; i+32 <= len64; i+=32) {
 
   58         for (
int j = 0; j < 4; ++j) {
 
   59             memcpy(&val64[j], &val[i+j*8], 8);
 
   60             hashval[j] = (hashval[j]*16777619) ^ val64[j];
 
   63     hashval[0] = (hashval[0]*16777619) ^ hashval[1];
 
   64     hashval[2] = (hashval[2]*16777619) ^ hashval[3];
 
   65     hashval[0] = (hashval[0]*16777619) ^ hashval[2];
 
   66     return uint32_t(hashval[0]);
 
   69 inline bool memCompare(
const char* a, 
const char* b, 
int len)
 
   73     for (
int i = 0; i < len64; i+=8) {
 
   74         memcpy(&val64[0], &a[i], 8);
 
   75         memcpy(&val64[1], &b[i], 8);
 
   76         if (val64[0] != val64[1]) 
return 1;
 
   78     return memcmp(&a[len64], &b[len64], len & 7);
 
   97         _len = uint32_t(strlen(val));
 
  106         char* newval = 
new char[key.
_len+1];
 
  107         memcpy(newval, key.
_val, key.
_len+1);
 
  147     uint32_t 
hash()
 volatile { 
return (
_val*7919) & ~0xf;  }
 
  150 template <
typename Key, 
typename Value>
 
  207         uint32_t hash = key.hash();
 
  210         for (uint32_t i = hash;; ++i) {
 
  211             Entry& e = entries[i & mask];
 
  212             if (e.key.matches(key)) {
 
  224     Value 
tryInsert(Key& key, Value value, 
size_t& newMemUsed)
 
  228         uint32_t hash = key.hash();
 
  231         for (uint32_t i = hash;; ++i) {
 
  232             Entry& e = entries[i & mask];
 
  241             while (e.key.isEmpty()) ;
 
  242             if (e.key.matches(key)) {
 
  251     template <
typename Fn>
 
  256             Value v = entries[i].value;
 
  266             if (entries) 
return entries;
 
  289             entries = 
grow(entries, newMemUsed);
 
  294     Entry* 
grow(Entry* oldEntries, 
size_t& newMemUsed)
 
  298         Entry* entries = 
new Entry[numNewEntries];
 
  299         newMemUsed = numNewEntries * 
sizeof(Entry);
 
  300         uint32_t mask = numNewEntries-1;
 
  301         for (uint32_t oldIndex = 0; oldIndex < 
_numEntries; ++oldIndex) {
 
  302             Entry& oldEntry = oldEntries[oldIndex];
 
  303             if (oldEntry.value) {
 
  304                 for (
int newIndex = oldEntry.key.hash();; ++newIndex) {
 
  305                     Entry& newEntry = entries[newIndex&mask];
 
  306                     if (!newEntry.value) {
 
  307                         newEntry.key.move(oldEntry.key);
 
  308                         newEntry.value = oldEntry.value;