uint64_t murmurHash64A()

in cachelib/common/FurcHash.cpp [55:107]


uint64_t murmurHash64A(const void* key, int len, uint64_t seed) {
  const uint64_t m = 0xc6a4a7935bd1e995;
  const int r = 47;

  uint64_t h = seed ^ (len * m);

  const uint64_t* data = reinterpret_cast<const uint64_t*>(key);
  const uint64_t* end = data + (len / 8);

  while (data != end) {
    uint64_t k = util::strict_aliasing_safe_read64(data);
    data++;

    k *= m;
    k ^= k >> r;
    k *= m;

    h ^= k;
    h *= m;
  }

  const uint8_t* data2 = (const uint8_t*)data;

  switch (len & 7) {
  case 7:
    h ^= (uint64_t)data2[6] << 48;
    FOLLY_FALLTHROUGH;
  case 6:
    h ^= (uint64_t)data2[5] << 40;
    FOLLY_FALLTHROUGH;
  case 5:
    h ^= (uint64_t)data2[4] << 32;
    FOLLY_FALLTHROUGH;
  case 4:
    h ^= (uint64_t)data2[3] << 24;
    FOLLY_FALLTHROUGH;
  case 3:
    h ^= (uint64_t)data2[2] << 16;
    FOLLY_FALLTHROUGH;
  case 2:
    h ^= (uint64_t)data2[1] << 8;
    FOLLY_FALLTHROUGH;
  case 1:
    h ^= (uint64_t)data2[0];
    h *= m;
  };

  h ^= h >> r;
  h *= m;
  h ^= h >> r;

  return h;
}