More conservative hash functions.
This commit is contained in:
parent
c06ad3e25e
commit
b3e2ef709d
@ -104,7 +104,7 @@ struct MapTester {
|
||||
if (static_cast<int>(m.size()) != i) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
static bool erase_value() {
|
||||
map_type<int64_t, int64_t> m;
|
||||
int nkeys = 10 * 1000;
|
||||
|
@ -252,7 +252,7 @@ struct FlexibleMPHIndex<false, false, Key, HashFcn>
|
||||
: public SimpleMPHIndex<Key, HashFcn> {
|
||||
FlexibleMPHIndex() : SimpleMPHIndex<Key, HashFcn>(false) {}
|
||||
uint32_t index(const Key& key) const {
|
||||
return MPHIndex::index<HashFcn>(key); }
|
||||
return MPHIndex::perfect_hash<HashFcn>(key); }
|
||||
uint32_t size() const { return MPHIndex::perfect_hash_size(); }
|
||||
};
|
||||
// From a trade-off perspective this case does not make much sense.
|
||||
|
@ -10,11 +10,6 @@
|
||||
#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 {
|
||||
@ -33,15 +28,16 @@ template <class HashFcn>
|
||||
struct seeded_hash_function {
|
||||
template <class Key>
|
||||
uint32_t operator()(const Key& k, uint32_t seed) const {
|
||||
return HashFcn()(k) ^ seed;
|
||||
uint32_t h;
|
||||
uint32_t h0 = HashFcn()(k);
|
||||
MurmurHash3_x86_32(reinterpret_cast<const void*>(&h0), 4, seed, &h);
|
||||
return h;
|
||||
}
|
||||
template <class Key>
|
||||
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);
|
||||
}
|
||||
uint32_t h0 = HashFcn()(k);
|
||||
MurmurHash3_x64_128(reinterpret_cast<const void*>(&h0), 4, seed, &h);
|
||||
return h;
|
||||
}
|
||||
};
|
||||
@ -78,20 +74,6 @@ struct Murmur3StringPiece {
|
||||
}
|
||||
};
|
||||
|
||||
struct Murmur3Fmix64bitsType {
|
||||
template <class Key>
|
||||
uint32_t operator()(const Key& k) const {
|
||||
return fmix(*reinterpret_cast<const uint64_t*>(&k));
|
||||
}
|
||||
template <class Key>
|
||||
h128 hash128(const Key& k) const {
|
||||
h128 h;
|
||||
h.set64(fmix(k), 0);
|
||||
h.set64(fmix(h.get64(0)), 1);
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct seeded_hash_function<Murmur3> {
|
||||
template <class Key>
|
||||
@ -126,22 +108,6 @@ struct seeded_hash_function<Murmur3StringPiece> {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct seeded_hash_function<Murmur3Fmix64bitsType> {
|
||||
template <class Key>
|
||||
uint32_t operator()(const Key& k, uint32_t seed) const {
|
||||
return fmix(k + seed);
|
||||
}
|
||||
template <class Key>
|
||||
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 <class HashFcn> struct seeded_hash
|
||||
{ typedef seeded_hash_function<HashFcn> hash_function; };
|
||||
// Use Murmur3 instead for all types defined in std::hash, plus
|
||||
|
@ -21,7 +21,7 @@ int main(int argc, char** argv) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
unordered_map<uint64_t, int, Murmur3Fmix64bitsType> g;
|
||||
unordered_map<uint64_t, int> g;
|
||||
for (int i = 0; i < 1000; ++i) g[i] = i;
|
||||
for (int i = 0; i < 1000; ++i) if (g[i] != i) exit(-1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user