#ifndef __CXXMPH_SEEDED_HASH_H__ #define __CXXMPH_SEEDED_HASH_H__ #include // for uint32_t and friends #include #include // for std::hash #include "MurmurHash3.h" #include "stringpiece.h" // From murmur, only used naively to extend 32 bits functions to 128 bits. uint32_t fmix ( uint32_t h ); // Used for a quick and dirty hash function for integers. Probably a bad idea. uint64_t fmix ( uint64_t h ); namespace cxxmph { struct h128 { uint32_t operator[](uint8_t i) const { return uint32[i]; } uint32_t& operator[](uint8_t i) { return uint32[i]; } uint64_t* uint64ptr(bool second) { return reinterpret_cast(&uint32[static_cast(second) << 1]); } uint64_t uint64(bool second) const { return *reinterpret_cast(&uint32[static_cast(second) << 1]); } bool operator==(const h128 rhs) const { return uint64(0) == rhs.uint64(0) && uint64(1) == rhs.uint64(1); } uint32_t uint32[4]; }; template struct seeded_hash_function { template uint32_t operator()(const Key& k, uint32_t seed) const { return HashFcn()(k) ^ seed; } template h128 hash128(const Key& k, uint32_t seed) const { h128 h; for (int i = 0; i < 4; ++i) { h.uint32[i] = HashFcn()(k) ^ seed; seed = fmix(seed); } return h; } }; struct Murmur3 { template uint32_t operator()(const Key& k) const { uint32_t out; MurmurHash3_x86_32(reinterpret_cast(&k), sizeof(Key), 1 /* seed */, &out); return out; } template h128 hash128(const Key& k) const { h128 h; MurmurHash3_x64_128(reinterpret_cast(&k), sizeof(Key), 1 /* seed */, &h); return h; } }; struct Murmur3StringPiece { template uint32_t operator()(const Key& k) const { StringPiece s(k); uint32_t out; MurmurHash3_x86_32(s.data(), s.length(), 1 /* seed */, &out); return out; } template h128 hash128(const Key& k) const { h128 h; StringPiece s(k); MurmurHash3_x64_128(s.data(), s.length(), 1 /* seed */, &h); return h; } }; struct Murmur3Fmix64bitsType { template uint32_t operator()(const Key& k) const { return fmix(*reinterpret_cast(&k)); } template h128 hash128(const Key& k) const { h128 h; *h.uint64ptr(0) = fmix(k); *h.uint64ptr(1) = fmix(h.uint64(0)); } }; template <> struct seeded_hash_function { template uint32_t operator()(const Key& k, uint32_t seed) const { uint32_t out; MurmurHash3_x86_32(reinterpret_cast(&k), sizeof(Key), seed, &out); return out; } template h128 hash128(const Key& k, uint32_t seed) const { h128 h; MurmurHash3_x64_128(reinterpret_cast(&k), sizeof(Key), seed, &h); return h; } }; template <> struct seeded_hash_function { template uint32_t operator()(const Key& k, uint32_t seed) const { StringPiece s(k); uint32_t out; MurmurHash3_x86_32(s.data(), s.length(), seed, &out); return out; } template h128 hash128(const Key& k, uint32_t seed) const { h128 h; StringPiece s(k); MurmurHash3_x64_128(s.data(), s.length(), seed, &h); return h; } }; template <> struct seeded_hash_function { template uint32_t operator()(const Key& k, uint32_t seed) const { return fmix(k + seed); } template h128 hash128(const Key& k, uint32_t seed) const { h128 h; *h.uint64ptr(0) = fmix(k ^ seed); *h.uint64ptr(1) = fmix(h.uint64(0)); return h; } }; template struct seeded_hash { typedef seeded_hash_function hash_function; }; // Use Murmur3 instead for all types defined in std::hash, plus // std::string which is commonly extended. template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; template <> struct seeded_hash > { typedef seeded_hash_function hash_function; }; } // namespace cxxmph #endif // __CXXMPH_SEEDED_HASH_H__