mmhash.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #include "mmhash.h"
  2. /*-----------------------------------------------------------------------------
  3. // MurmurHash2, 64-bit versions, by Austin Appleby
  4. //
  5. // The same caveats as 32-bit MurmurHash2 apply here - beware of alignment
  6. // and endian-ness issues if used across multiple platforms.
  7. //
  8. // 64-bit hash for 64-bit platforms
  9. */
  10. uint64_t mmhash(const void *key, int len, uint64_t seed) {
  11. const uint64_t m = 0xc6a4a7935bd1e995LL;
  12. const int r = 47;
  13. uint64_t h = seed ^ (len * m);
  14. const uint64_t *data = (const uint64_t *)key;
  15. const uint64_t *end = data + (len / 8);
  16. while (data != end) {
  17. uint64_t k = *data++;
  18. k *= m;
  19. k ^= k >> r;
  20. k *= m;
  21. h ^= k;
  22. h *= m;
  23. }
  24. const unsigned char *data2 = (const unsigned char *)data;
  25. switch (len & 7) {
  26. case 7:
  27. h ^= ((uint64_t)data2[6]) << 48;
  28. case 6:
  29. h ^= ((uint64_t)data2[5]) << 40;
  30. case 5:
  31. h ^= ((uint64_t)data2[4]) << 32;
  32. case 4:
  33. h ^= ((uint64_t)data2[3]) << 24;
  34. case 3:
  35. h ^= ((uint64_t)data2[2]) << 16;
  36. case 2:
  37. h ^= ((uint64_t)data2[1]) << 8;
  38. case 1:
  39. h ^= ((uint64_t)data2[0]);
  40. h *= m;
  41. };
  42. h ^= h >> r;
  43. h *= m;
  44. h ^= h >> r;
  45. return h;
  46. }