| // Copyright 2011 Google Inc. All Rights Reserved. |
| // |
| // These are the core hashing routines which operate on strings. We define |
| // strings loosely as a sequence of bytes, and these routines are designed to |
| // work with the most fundamental representations of a string of bytes. |
| // |
| // These routines provide "good" hash functions in terms of both quality and |
| // speed. Their values can and will change as their implementations change and |
| // evolve. |
| |
| #ifndef UTIL_HASH_STRING_HASH_H_ |
| #define UTIL_HASH_STRING_HASH_H_ |
| |
| #include <stddef.h> |
| |
| #include "gutil/port.h" |
| #include "gutil/integral_types.h" |
| #include "gutil/hash/city.h" |
| #include "gutil/hash/jenkins.h" |
| #include "gutil/hash/jenkins_lookup2.h" |
| |
| namespace hash_internal { |
| |
| // We have some special cases for 64-bit hardware and x86-64 in particular. |
| // Instead of sprinkling ifdefs through the file, we have one ugly ifdef here. |
| // Later code can then use "if" instead of "ifdef". |
| #if defined(__x86_64__) |
| enum { x86_64 = true, sixty_four_bit = true }; |
| #elif defined(_LP64) |
| enum { x86_64 = false, sixty_four_bit = true }; |
| #else |
| enum { x86_64 = false, sixty_four_bit = false }; |
| #endif |
| |
| // Arbitrary mix constants (pi). |
| static const uint32 kMix32 = 0x12b9b0a1UL; |
| static const uint64 kMix64 = GG_ULONGLONG(0x2b992ddfa23249d6); |
| |
| } // namespace hash_internal |
| |
| inline size_t HashStringThoroughlyWithSeed(const char* s, size_t len, |
| size_t seed) { |
| if (hash_internal::x86_64) |
| return static_cast<size_t>(util_hash::CityHash64WithSeed(s, len, seed)); |
| |
| if (hash_internal::sixty_four_bit) |
| return Hash64StringWithSeed(s, static_cast<uint32>(len), seed); |
| |
| return static_cast<size_t>(Hash32StringWithSeed(s, static_cast<uint32>(len), |
| static_cast<uint32>(seed))); |
| } |
| |
| inline size_t HashStringThoroughly(const char* s, size_t len) { |
| if (hash_internal::x86_64) |
| return static_cast<size_t>(util_hash::CityHash64(s, len)); |
| |
| if (hash_internal::sixty_four_bit) |
| return Hash64StringWithSeed(s, static_cast<uint32>(len), |
| hash_internal::kMix64); |
| |
| return static_cast<size_t>(Hash32StringWithSeed(s, static_cast<uint32>(len), |
| hash_internal::kMix32)); |
| } |
| |
| inline size_t HashStringThoroughlyWithSeeds(const char* s, size_t len, |
| size_t seed0, size_t seed1) { |
| if (hash_internal::x86_64) |
| return util_hash::CityHash64WithSeeds(s, len, seed0, seed1); |
| |
| if (hash_internal::sixty_four_bit) { |
| uint64 a = seed0; |
| uint64 b = seed1; |
| uint64 c = HashStringThoroughly(s, len); |
| mix(a, b, c); |
| return c; |
| } |
| |
| uint32 a = static_cast<uint32>(seed0); |
| uint32 b = static_cast<uint32>(seed1); |
| uint32 c = static_cast<uint32>(HashStringThoroughly(s, len)); |
| mix(a, b, c); |
| return c; |
| } |
| |
| #endif // UTIL_HASH_STRING_HASH_H_ |