murmur.vala 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. /*
  2. * Copyright (c) 2012-2026 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: GPL-3.0-or-later
  4. */
  5. namespace Crown
  6. {
  7. // MurmurHash2 was written by Austin Appleby, and is placed in the public
  8. // domain. The author hereby disclaims copyright to this source code.
  9. //
  10. // Note - This code makes a few assumptions about how your machine behaves -
  11. //
  12. // 1. We can read a 4-byte value from any address without crashing
  13. // 2. sizeof(int) == 4
  14. //
  15. // And it has a few limitations -
  16. //
  17. // 1. It will not work incrementally.
  18. // 2. It will not produce the same results on little-endian and big-endian
  19. // machines.
  20. uint64 murmur64(void* key, uint32 len, uint64 seed)
  21. {
  22. uint64 m = 0xc6a4a7935bd1e995ull;
  23. int r = 47;
  24. uint64 h = seed ^ (len * m);
  25. uint64* data = (uint64*)key;
  26. uint64* end = data + (len/8);
  27. while (data != end) {
  28. uint64 k = *data++;
  29. k *= m;
  30. k ^= k >> r;
  31. k *= m;
  32. h ^= k;
  33. h *= m;
  34. }
  35. uint8* data2 = (uint8*)data;
  36. int i;
  37. uint32 len7 = len & 7;
  38. for (i = 0; i < len7; ++i) {
  39. uint32 idx = len7 - 1 - i;
  40. h ^= ((uint64)data2[idx]) << (idx << 3);
  41. }
  42. h *= i != 0 ? m : 1;
  43. h ^= h >> r;
  44. h *= m;
  45. h ^= h >> r;
  46. return h;
  47. }
  48. } /* namespace Crown */