Improved hash signature.

This commit is contained in:
Davi Reis 2012-03-20 11:47:55 -03:00
parent e760465fca
commit d4d79c62bd
4 changed files with 44 additions and 32 deletions

View File

@ -27,6 +27,9 @@ cxxmph_LDADD = libcxxmph.la
cxxmph_SOURCES = cxxmph.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_LDADD = libcxxmph.la
mph_bits_test_LDADD = libcxxmph.la

View File

@ -68,10 +68,6 @@ class MPHIndex {
template <class SeededHashFcn, class Key> // must agree with Reset
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:
template <class SeededHashFcn, class ForwardIterator>
bool Mapping(ForwardIterator begin, ForwardIterator end,
@ -160,8 +156,7 @@ bool MPHIndex::Mapping(
std::vector<TriGraph::Edge>* edges, std::vector<uint32_t>* queue) {
TriGraph graph(n_, m_);
for (ForwardIterator it = begin; it != end; ++it) {
uint32_t h[4];
SeededHashFcn().hash64(*it, hash_seed_[0], reinterpret_cast<uint32_t*>(&h));
h128 h = SeededHashFcn().hash128(*it, hash_seed_[0]);
// for (int i = 0; i < 3; ++i) h[i] = SeededHashFcn()(*it, hash_seed_[i]);
uint32_t v0 = h[0] % r_;
uint32_t v1 = h[1] % r_ + r_;
@ -176,16 +171,10 @@ bool MPHIndex::Mapping(
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>
uint32_t MPHIndex::perfect_hash(const Key& key) const {
uint32_t h[4];
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[1] = (h[1] % r_) + nest_displacement_[1];
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 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); }
void hash_vector(const Key& key, uint32_t* h) const { MPHIndex::hash_vector<HashFcn>(key, h); }
};
} // namespace cxxmph

View File

@ -199,8 +199,6 @@ MPH_MAP_METHOD_DECL(void_type, clear)() {
MPH_MAP_METHOD_DECL(void_type, erase)(iterator pos) {
present_[pos - begin] = false;
uint32_t h[4];
index_.hash_vector(pos->first, &h);
*pos = value_type();
--size_;
}

View File

@ -16,6 +16,16 @@ 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<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>
struct seeded_hash_function {
template <class Key>
@ -23,11 +33,13 @@ struct seeded_hash_function {
return HashFcn()(k) ^ seed;
}
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) {
out[i] = HashFcn()(k) ^ seed;
h.uint32[i] = HashFcn()(k) ^ seed;
seed = fmix(seed);
}
return h;
}
};
@ -39,8 +51,10 @@ struct Murmur3 {
return out;
}
template <class Key>
void hash64(const Key& k, uint32_t* out) const {
MurmurHash3_x64_128(reinterpret_cast<const void*>(&k), sizeof(Key), 1 /* seed */, out);
h128 hash128(const Key& k) const {
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;
}
template <class Key>
void hash64(const Key& k, uint32_t* out) const {
h128 hash128(const Key& k) const {
h128 h;
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));
}
template <class Key>
void hash64(const Key& k, uint32_t* out) const {
*reinterpret_cast<uint64_t*>(out) = fmix(k);
*(out + 2) = fmix(*out);
h128 hash128(const Key& k) const {
h128 h;
*h.uint64ptr(0) = fmix(k);
*h.uint64ptr(1) = fmix(h.uint64(0));
}
};
@ -80,8 +97,10 @@ struct seeded_hash_function<Murmur3> {
return out;
}
template <class Key>
void hash64(const Key& k, uint32_t seed, uint32_t* out) const {
MurmurHash3_x64_128(reinterpret_cast<const void*>(&k), sizeof(Key), seed, out);
h128 hash128(const Key& k, uint32_t seed) const {
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;
}
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);
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);
}
template <class Key>
void hash64(const Key& k, uint32_t seed, uint32_t* out) const {
*reinterpret_cast<uint64_t*>(out) = fmix(k ^ seed);
*(out + 2) = fmix(*out);
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;
}
};