hash.cc 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. #include "util/hash.h"
  5. #include <cstring>
  6. #include "util/coding.h"
  7. // The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
  8. // between switch labels. The real definition should be provided externally.
  9. // This one is a fallback version for unsupported compilers.
  10. #ifndef FALLTHROUGH_INTENDED
  11. #define FALLTHROUGH_INTENDED \
  12. do { \
  13. } while (0)
  14. #endif
  15. namespace leveldb {
  16. uint32_t Hash(const char* data, size_t n, uint32_t seed) {
  17. // Similar to murmur hash
  18. const uint32_t m = 0xc6a4a793;
  19. const uint32_t r = 24;
  20. const char* limit = data + n;
  21. uint32_t h = seed ^ (n * m);
  22. // Pick up four bytes at a time
  23. while (data + 4 <= limit) {
  24. uint32_t w = DecodeFixed32(data);
  25. data += 4;
  26. h += w;
  27. h *= m;
  28. h ^= (h >> 16);
  29. }
  30. // Pick up remaining bytes
  31. switch (limit - data) {
  32. case 3:
  33. h += static_cast<uint8_t>(data[2]) << 16;
  34. FALLTHROUGH_INTENDED;
  35. case 2:
  36. h += static_cast<uint8_t>(data[1]) << 8;
  37. FALLTHROUGH_INTENDED;
  38. case 1:
  39. h += static_cast<uint8_t>(data[0]);
  40. h *= m;
  41. h ^= (h >> r);
  42. break;
  43. }
  44. return h;
  45. }
  46. } // namespace leveldb