hash.h 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright 2010-2011 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #ifndef __BX_HASH_H__
  6. #define __BX_HASH_H__
  7. #include "bx.h"
  8. namespace bx
  9. {
  10. // MurmurHash2 was written by Austin Appleby, and is placed in the public
  11. // domain. The author hereby disclaims copyright to this source code.
  12. #define MURMUR_M 0x5bd1e995
  13. #define MURMUR_R 24
  14. #define mmix(_h, _k) { _k *= MURMUR_M; _k ^= _k >> MURMUR_R; _k *= MURMUR_M; _h *= MURMUR_M; _h ^= _k; }
  15. class HashMurmur2A
  16. {
  17. public:
  18. void begin(uint32_t _seed = 0)
  19. {
  20. m_hash = _seed;
  21. m_tail = 0;
  22. m_count = 0;
  23. m_size = 0;
  24. }
  25. void add(const void* _data, int _len)
  26. {
  27. const uint8_t* data = (uint8_t*)_data;
  28. m_size += _len;
  29. mixTail(data, _len);
  30. while(_len >= 4)
  31. {
  32. uint32_t kk = *(uint32_t*)data;
  33. mmix(m_hash, kk);
  34. data += 4;
  35. _len -= 4;
  36. }
  37. mixTail(data, _len);
  38. }
  39. uint32_t end()
  40. {
  41. mmix(m_hash, m_tail);
  42. mmix(m_hash, m_size);
  43. m_hash ^= m_hash >> 13;
  44. m_hash *= MURMUR_M;
  45. m_hash ^= m_hash >> 15;
  46. return m_hash;
  47. }
  48. private:
  49. void mixTail(const uint8_t*& _data, int& _len)
  50. {
  51. while( _len && ((_len<4) || m_count) )
  52. {
  53. m_tail |= (*_data++) << (m_count * 8);
  54. m_count++;
  55. _len--;
  56. if(m_count == 4)
  57. {
  58. mmix(m_hash, m_tail);
  59. m_tail = 0;
  60. m_count = 0;
  61. }
  62. }
  63. }
  64. uint32_t m_hash;
  65. uint32_t m_tail;
  66. uint32_t m_count;
  67. uint32_t m_size;
  68. };
  69. } // namespace bx
  70. #endif // __BX_HASH_H__