#ifndef __CXXMPH_SEEDED_HASH_H__ #define __CXXMPH_SEEDED_HASH_H__ #include // for uint32_t and friends #include #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 { const uint32_t& operator[](uint8_t i) const { return uint32[i]; } uint32_t& operator[](uint8_t i) { return uint32[i]; } const uint64_t get64(bool second) const { return (static_cast(uint32[second << 1]) << 32) | uint32[1 + (second << 1)]; } void set64(uint64_t v, bool second) { uint32[second << 1] = v >> 32; uint32[1+(second<<1)] = ((v << 32) >> 32); } bool operator==(const h128 rhs) const { return memcmp(uint32, rhs.uint32, sizeof(uint32)) == 0; } uint32_t uint32[4]; struct hash32 { uint32_t operator()(const cxxmph::h128& h) const { return h[3]; } }; }; 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.set64(fmix(k), 0); h.set64(fmix(h.get64(0)), 1); } }; 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.set64(fmix(k ^ seed), 0); h.set64(fmix(h.get64(0)), 1); 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__