blob: 4e399973e74f4d3a44facbe5c81bdb1a0ce9efbc [file] [log] [blame]
// 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_