Improved hash signature.
This commit is contained in:
parent
e760465fca
commit
d4d79c62bd
@ -27,6 +27,9 @@ cxxmph_LDADD = libcxxmph.la
|
|||||||
cxxmph_SOURCES = cxxmph.cc
|
cxxmph_SOURCES = cxxmph.cc
|
||||||
|
|
||||||
hollow_iterator_test_SOURCES = hollow_iterator_test.cc
|
hollow_iterator_test_SOURCES = hollow_iterator_test.cc
|
||||||
|
seeded_hash_test_SOURCES = seeded_hash_test.cc
|
||||||
|
|
||||||
mph_bits_test_SOURCES = mph_bits_test.cc
|
mph_bits_test_SOURCES = mph_bits_test.cc
|
||||||
mph_bits_test_LDADD = libcxxmph.la
|
mph_bits_test_LDADD = libcxxmph.la
|
||||||
|
mph_bits_test_LDADD = libcxxmph.la
|
||||||
|
|
||||||
|
@ -68,10 +68,6 @@ class MPHIndex {
|
|||||||
template <class SeededHashFcn, class Key> // must agree with Reset
|
template <class SeededHashFcn, class Key> // must agree with Reset
|
||||||
uint32_t minimal_perfect_hash(const Key& x) const;
|
uint32_t minimal_perfect_hash(const Key& x) const;
|
||||||
|
|
||||||
// Crazy functions. Ignore.
|
|
||||||
template <class SeededHashFcn, class Key> // must agree with Reset
|
|
||||||
void hash_vector(const Key& x, uint32_t* h) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class SeededHashFcn, class ForwardIterator>
|
template <class SeededHashFcn, class ForwardIterator>
|
||||||
bool Mapping(ForwardIterator begin, ForwardIterator end,
|
bool Mapping(ForwardIterator begin, ForwardIterator end,
|
||||||
@ -160,8 +156,7 @@ bool MPHIndex::Mapping(
|
|||||||
std::vector<TriGraph::Edge>* edges, std::vector<uint32_t>* queue) {
|
std::vector<TriGraph::Edge>* edges, std::vector<uint32_t>* queue) {
|
||||||
TriGraph graph(n_, m_);
|
TriGraph graph(n_, m_);
|
||||||
for (ForwardIterator it = begin; it != end; ++it) {
|
for (ForwardIterator it = begin; it != end; ++it) {
|
||||||
uint32_t h[4];
|
h128 h = SeededHashFcn().hash128(*it, hash_seed_[0]);
|
||||||
SeededHashFcn().hash64(*it, hash_seed_[0], reinterpret_cast<uint32_t*>(&h));
|
|
||||||
// for (int i = 0; i < 3; ++i) h[i] = SeededHashFcn()(*it, hash_seed_[i]);
|
// for (int i = 0; i < 3; ++i) h[i] = SeededHashFcn()(*it, hash_seed_[i]);
|
||||||
uint32_t v0 = h[0] % r_;
|
uint32_t v0 = h[0] % r_;
|
||||||
uint32_t v1 = h[1] % r_ + r_;
|
uint32_t v1 = h[1] % r_ + r_;
|
||||||
@ -176,16 +171,10 @@ bool MPHIndex::Mapping(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class SeededHashFcn, class Key>
|
|
||||||
void MPHIndex::hash_vector(const Key& key, uint32_t* h) const {
|
|
||||||
SeededHashFcn().hash64(key, hash_seed_[0], h);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class SeededHashFcn, class Key>
|
template <class SeededHashFcn, class Key>
|
||||||
uint32_t MPHIndex::perfect_hash(const Key& key) const {
|
uint32_t MPHIndex::perfect_hash(const Key& key) const {
|
||||||
uint32_t h[4];
|
|
||||||
if (!g_.size()) return 0;
|
if (!g_.size()) return 0;
|
||||||
SeededHashFcn().hash64(key, hash_seed_[0], h);
|
h128 h = SeededHashFcn().hash128(key, hash_seed_[0]);
|
||||||
h[0] = (h[0] % r_) + nest_displacement_[0];
|
h[0] = (h[0] % r_) + nest_displacement_[0];
|
||||||
h[1] = (h[1] % r_) + nest_displacement_[1];
|
h[1] = (h[1] % r_) + nest_displacement_[1];
|
||||||
h[2] = (h[2] % r_) + nest_displacement_[2];
|
h[2] = (h[2] % r_) + nest_displacement_[2];
|
||||||
@ -222,7 +211,6 @@ class SimpleMPHIndex : public MPHIndex {
|
|||||||
uint32_t index(const Key& key) const { return MPHIndex::index<HashFcn>(key); }
|
uint32_t index(const Key& key) const { return MPHIndex::index<HashFcn>(key); }
|
||||||
uint32_t perfect_hash(const Key& key) const { return MPHIndex::perfect_hash<HashFcn>(key); }
|
uint32_t perfect_hash(const Key& key) const { return MPHIndex::perfect_hash<HashFcn>(key); }
|
||||||
uint32_t minimal_perfect_hash(const Key& key) const { return MPHIndex::minimal_perfect_hash<HashFcn>(key); }
|
uint32_t minimal_perfect_hash(const Key& key) const { return MPHIndex::minimal_perfect_hash<HashFcn>(key); }
|
||||||
void hash_vector(const Key& key, uint32_t* h) const { MPHIndex::hash_vector<HashFcn>(key, h); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cxxmph
|
} // namespace cxxmph
|
||||||
|
@ -199,8 +199,6 @@ MPH_MAP_METHOD_DECL(void_type, clear)() {
|
|||||||
|
|
||||||
MPH_MAP_METHOD_DECL(void_type, erase)(iterator pos) {
|
MPH_MAP_METHOD_DECL(void_type, erase)(iterator pos) {
|
||||||
present_[pos - begin] = false;
|
present_[pos - begin] = false;
|
||||||
uint32_t h[4];
|
|
||||||
index_.hash_vector(pos->first, &h);
|
|
||||||
*pos = value_type();
|
*pos = value_type();
|
||||||
--size_;
|
--size_;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,16 @@ uint64_t fmix ( uint64_t h );
|
|||||||
|
|
||||||
namespace cxxmph {
|
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<uint64_t*>(&uint32[static_cast<uint8_t>(second) << 1]); }
|
||||||
|
uint64_t uint64(bool second) const { return *reinterpret_cast<const uint64_t*>(&uint32[static_cast<uint8_t>(second) << 1]); }
|
||||||
|
bool operator==(const h128 rhs) const { return uint64(0) == rhs.uint64(0) && uint64(1) == rhs.uint64(1); }
|
||||||
|
|
||||||
|
uint32_t uint32[4];
|
||||||
|
};
|
||||||
|
|
||||||
template <class HashFcn>
|
template <class HashFcn>
|
||||||
struct seeded_hash_function {
|
struct seeded_hash_function {
|
||||||
template <class Key>
|
template <class Key>
|
||||||
@ -23,11 +33,13 @@ struct seeded_hash_function {
|
|||||||
return HashFcn()(k) ^ seed;
|
return HashFcn()(k) ^ seed;
|
||||||
}
|
}
|
||||||
template <class Key>
|
template <class Key>
|
||||||
void hash64(const Key& k, uint32_t seed, uint32_t* out) const {
|
h128 hash128(const Key& k, uint32_t seed) const {
|
||||||
|
h128 h;
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
out[i] = HashFcn()(k) ^ seed;
|
h.uint32[i] = HashFcn()(k) ^ seed;
|
||||||
seed = fmix(seed);
|
seed = fmix(seed);
|
||||||
}
|
}
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,8 +51,10 @@ struct Murmur3 {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
template <class Key>
|
template <class Key>
|
||||||
void hash64(const Key& k, uint32_t* out) const {
|
h128 hash128(const Key& k) const {
|
||||||
MurmurHash3_x64_128(reinterpret_cast<const void*>(&k), sizeof(Key), 1 /* seed */, out);
|
h128 h;
|
||||||
|
MurmurHash3_x64_128(reinterpret_cast<const void*>(&k), sizeof(Key), 1 /* seed */, &h);
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,9 +67,11 @@ struct Murmur3StringPiece {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
template <class Key>
|
template <class Key>
|
||||||
void hash64(const Key& k, uint32_t* out) const {
|
h128 hash128(const Key& k) const {
|
||||||
|
h128 h;
|
||||||
StringPiece s(k);
|
StringPiece s(k);
|
||||||
MurmurHash3_x64_128(s.data(), s.length(), 1 /* seed */, out);
|
MurmurHash3_x64_128(s.data(), s.length(), 1 /* seed */, &h);
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,9 +81,10 @@ struct Murmur3Fmix64bitsType {
|
|||||||
return fmix(*reinterpret_cast<const uint64_t*>(&k));
|
return fmix(*reinterpret_cast<const uint64_t*>(&k));
|
||||||
}
|
}
|
||||||
template <class Key>
|
template <class Key>
|
||||||
void hash64(const Key& k, uint32_t* out) const {
|
h128 hash128(const Key& k) const {
|
||||||
*reinterpret_cast<uint64_t*>(out) = fmix(k);
|
h128 h;
|
||||||
*(out + 2) = fmix(*out);
|
*h.uint64ptr(0) = fmix(k);
|
||||||
|
*h.uint64ptr(1) = fmix(h.uint64(0));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,8 +97,10 @@ struct seeded_hash_function<Murmur3> {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
template <class Key>
|
template <class Key>
|
||||||
void hash64(const Key& k, uint32_t seed, uint32_t* out) const {
|
h128 hash128(const Key& k, uint32_t seed) const {
|
||||||
MurmurHash3_x64_128(reinterpret_cast<const void*>(&k), sizeof(Key), seed, out);
|
h128 h;
|
||||||
|
MurmurHash3_x64_128(reinterpret_cast<const void*>(&k), sizeof(Key), seed, &h);
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -95,9 +114,11 @@ struct seeded_hash_function<Murmur3StringPiece> {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
template <class Key>
|
template <class Key>
|
||||||
void hash64(const Key& k, uint32_t seed, uint32_t* out) const {
|
h128 hash128(const Key& k, uint32_t seed) const {
|
||||||
|
h128 h;
|
||||||
StringPiece s(k);
|
StringPiece s(k);
|
||||||
MurmurHash3_x64_128(s.data(), s.length(), seed, out);
|
MurmurHash3_x64_128(s.data(), s.length(), seed, &h);
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,9 +129,11 @@ struct seeded_hash_function<Murmur3Fmix64bitsType> {
|
|||||||
return fmix(k + seed);
|
return fmix(k + seed);
|
||||||
}
|
}
|
||||||
template <class Key>
|
template <class Key>
|
||||||
void hash64(const Key& k, uint32_t seed, uint32_t* out) const {
|
h128 hash128(const Key& k, uint32_t seed) const {
|
||||||
*reinterpret_cast<uint64_t*>(out) = fmix(k ^ seed);
|
h128 h;
|
||||||
*(out + 2) = fmix(*out);
|
*h.uint64ptr(0) = fmix(k ^ seed);
|
||||||
|
*h.uint64ptr(1) = fmix(h.uint64(0));
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user