Hash.cpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. constexpr U64 HASH_M = 0xc6a4a7935bd1e995;
  9. constexpr U64 HASH_R = 47;
  10. U64 appendHash(const void* buffer, PtrSize bufferSize, U64 h)
  11. {
  12. const U64* data = static_cast<const U64*>(buffer);
  13. const U64* const end = data + (bufferSize / sizeof(U64));
  14. while(data != end)
  15. {
  16. U64 k = *data++;
  17. k *= HASH_M;
  18. k ^= k >> HASH_R;
  19. k *= HASH_M;
  20. h ^= k;
  21. h *= HASH_M;
  22. }
  23. const U8* data2 = reinterpret_cast<const U8*>(data);
  24. switch(bufferSize & (sizeof(U64) - 1))
  25. {
  26. case 7:
  27. h ^= U64(data2[6]) << 48;
  28. case 6:
  29. h ^= U64(data2[5]) << 40;
  30. case 5:
  31. h ^= U64(data2[4]) << 32;
  32. case 4:
  33. h ^= U64(data2[3]) << 24;
  34. case 3:
  35. h ^= U64(data2[2]) << 16;
  36. case 2:
  37. h ^= U64(data2[1]) << 8;
  38. case 1:
  39. h ^= U64(data2[0]);
  40. h *= HASH_M;
  41. };
  42. h ^= h >> HASH_R;
  43. h *= HASH_M;
  44. h ^= h >> HASH_R;
  45. ANKI_ASSERT(h != 0);
  46. return h;
  47. }
  48. U64 computeHash(const void* buffer, PtrSize bufferSize, U64 seed)
  49. {
  50. const U64 h = seed ^ (bufferSize * HASH_M);
  51. return appendHash(buffer, bufferSize, h);
  52. }
  53. } // end namespace anki