Hash.cpp 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Util/Hash.h>
  6. #include <AnKi/Util/Assert.h>
  7. namespace anki
  8. {
  9. constexpr U64 HASH_M = 0xc6a4a7935bd1e995;
  10. constexpr U64 HASH_R = 47;
  11. U64 appendHash(const void* buffer, PtrSize bufferSize, U64 h)
  12. {
  13. const U64* data = static_cast<const U64*>(buffer);
  14. const U64* const end = data + (bufferSize / sizeof(U64));
  15. while(data != end)
  16. {
  17. U64 k = *data++;
  18. k *= HASH_M;
  19. k ^= k >> HASH_R;
  20. k *= HASH_M;
  21. h ^= k;
  22. h *= HASH_M;
  23. }
  24. const U8* data2 = reinterpret_cast<const U8*>(data);
  25. switch(bufferSize & (sizeof(U64) - 1))
  26. {
  27. case 7:
  28. h ^= U64(data2[6]) << 48;
  29. case 6:
  30. h ^= U64(data2[5]) << 40;
  31. case 5:
  32. h ^= U64(data2[4]) << 32;
  33. case 4:
  34. h ^= U64(data2[3]) << 24;
  35. case 3:
  36. h ^= U64(data2[2]) << 16;
  37. case 2:
  38. h ^= U64(data2[1]) << 8;
  39. case 1:
  40. h ^= U64(data2[0]);
  41. h *= HASH_M;
  42. };
  43. h ^= h >> HASH_R;
  44. h *= HASH_M;
  45. h ^= h >> HASH_R;
  46. ANKI_ASSERT(h != 0);
  47. return h;
  48. }
  49. U64 computeHash(const void* buffer, PtrSize bufferSize, U64 seed)
  50. {
  51. const U64 h = seed ^ (bufferSize * HASH_M);
  52. return appendHash(buffer, bufferSize, h);
  53. }
  54. } // end namespace anki