mirror of
https://github.com/zeek/zeek.git
synced 2025-10-14 20:48:21 +00:00
Make hash functions equality comparable.
This commit is contained in:
parent
9c2f57a9d9
commit
eb64f5f961
3 changed files with 93 additions and 38 deletions
12
src/H3.h
12
src/H3.h
|
@ -58,6 +58,7 @@
|
||||||
#define H3_H
|
#define H3_H
|
||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
// The number of values representable by a byte.
|
// The number of values representable by a byte.
|
||||||
#define H3_BYTE_RANGE (UCHAR_MAX+1)
|
#define H3_BYTE_RANGE (UCHAR_MAX+1)
|
||||||
|
@ -112,6 +113,17 @@ public:
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const H3& x, const H3& y)
|
||||||
|
{
|
||||||
|
return ! std::memcmp(x.byte_lookup, y.byte_lookup, N * H3_BYTE_RANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const H3& x, const H3& y)
|
||||||
|
{
|
||||||
|
return ! (x == y);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T byte_lookup[N][H3_BYTE_RANGE];
|
T byte_lookup[N][H3_BYTE_RANGE];
|
||||||
};
|
};
|
||||||
|
|
101
src/Hasher.cc
101
src/Hasher.cc
|
@ -8,56 +8,69 @@ Hasher::UHF::UHF(size_t seed, const std::string& extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
Hasher::digest Hasher::UHF::hash(const void* x, size_t n) const
|
Hasher::digest Hasher::UHF::hash(const void* x, size_t n) const
|
||||||
{
|
{
|
||||||
assert(n <= UHASH_KEY_SIZE);
|
assert(n <= UHASH_KEY_SIZE);
|
||||||
return n == 0 ? 0 : h_(x, n);
|
return n == 0 ? 0 : h_(x, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Hasher::UHF::compute_seed(size_t seed, const std::string& extra)
|
size_t Hasher::UHF::compute_seed(size_t seed, const std::string& extra)
|
||||||
{
|
{
|
||||||
u_char buf[SHA256_DIGEST_LENGTH];
|
u_char buf[SHA256_DIGEST_LENGTH];
|
||||||
SHA256_CTX ctx;
|
SHA256_CTX ctx;
|
||||||
sha256_init(&ctx);
|
sha256_init(&ctx);
|
||||||
if ( extra.empty() )
|
if ( extra.empty() )
|
||||||
{
|
{
|
||||||
unsigned int first_seed = initial_seed();
|
unsigned int first_seed = initial_seed();
|
||||||
sha256_update(&ctx, &first_seed, sizeof(first_seed));
|
sha256_update(&ctx, &first_seed, sizeof(first_seed));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sha256_update(&ctx, extra.c_str(), extra.size());
|
sha256_update(&ctx, extra.c_str(), extra.size());
|
||||||
|
}
|
||||||
|
sha256_update(&ctx, &seed, sizeof(seed));
|
||||||
|
sha256_final(&ctx, buf);
|
||||||
|
// Take the first sizeof(size_t) bytes as seed.
|
||||||
|
return *reinterpret_cast<size_t*>(buf);
|
||||||
}
|
}
|
||||||
sha256_update(&ctx, &seed, sizeof(seed));
|
|
||||||
sha256_final(&ctx, buf);
|
|
||||||
// Take the first sizeof(size_t) bytes as seed.
|
|
||||||
return *reinterpret_cast<size_t*>(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Hasher* Hasher::Create(size_t k, const std::string& name)
|
Hasher* Hasher::Create(size_t k, const std::string& name)
|
||||||
{
|
{
|
||||||
return new DefaultHasher(k, name);
|
return new DefaultHasher(k, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Hasher::Hasher(size_t k, const std::string& name)
|
Hasher::Hasher(size_t k, const std::string& name)
|
||||||
: k_(k), name_(name)
|
: k_(k), name_(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultHasher::DefaultHasher(size_t k, const std::string& name)
|
DefaultHasher::DefaultHasher(size_t k, const std::string& name)
|
||||||
: Hasher(k, name)
|
: Hasher(k, name)
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < k; ++i )
|
for ( size_t i = 0; i < k; ++i )
|
||||||
hash_functions_.push_back(UHF(i, name));
|
hash_functions_.push_back(UHF(i, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Hasher::digest_vector DefaultHasher::Hash(const void* x, size_t n) const
|
Hasher::digest_vector DefaultHasher::Hash(const void* x, size_t n) const
|
||||||
{
|
{
|
||||||
digest_vector h(K(), 0);
|
digest_vector h(K(), 0);
|
||||||
for ( size_t i = 0; i < h.size(); ++i )
|
for ( size_t i = 0; i < h.size(); ++i )
|
||||||
h[i] = hash_functions_[i](x, n);
|
h[i] = hash_functions_[i](x, n);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefaultHasher* DefaultHasher::Clone() const
|
||||||
|
{
|
||||||
|
return new DefaultHasher(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DefaultHasher::Equals(const Hasher* other) const /* final */
|
||||||
|
{
|
||||||
|
if ( typeid(*this) != typeid(*other) )
|
||||||
|
return false;
|
||||||
|
const DefaultHasher* o = static_cast<const DefaultHasher*>(other);
|
||||||
|
return hash_functions_ == o->hash_functions_;
|
||||||
|
}
|
||||||
|
|
||||||
DoubleHasher::DoubleHasher(size_t k, const std::string& name)
|
DoubleHasher::DoubleHasher(size_t k, const std::string& name)
|
||||||
: Hasher(k, name),
|
: Hasher(k, name),
|
||||||
|
@ -67,13 +80,25 @@ DoubleHasher::DoubleHasher(size_t k, const std::string& name)
|
||||||
}
|
}
|
||||||
|
|
||||||
Hasher::digest_vector DoubleHasher::Hash(const void* x, size_t n) const
|
Hasher::digest_vector DoubleHasher::Hash(const void* x, size_t n) const
|
||||||
{
|
{
|
||||||
digest h1 = h1_(x, n);
|
digest h1 = h1_(x, n);
|
||||||
digest h2 = h2_(x, n);
|
digest h2 = h2_(x, n);
|
||||||
digest_vector h(K(), 0);
|
digest_vector h(K(), 0);
|
||||||
for ( size_t i = 0; i < h.size(); ++i )
|
for ( size_t i = 0; i < h.size(); ++i )
|
||||||
h[i] = h1 + i * h2;
|
h[i] = h1 + i * h2;
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DoubleHasher* DoubleHasher::Clone() const
|
||||||
|
{
|
||||||
|
return new DoubleHasher(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DoubleHasher::Equals(const Hasher* other) const /* final */
|
||||||
|
{
|
||||||
|
if ( typeid(*this) != typeid(*other) )
|
||||||
|
return false;
|
||||||
|
const DoubleHasher* o = static_cast<const DoubleHasher*>(other);
|
||||||
|
return h1_ == o->h1_ && h2_ == o->h2_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
18
src/Hasher.h
18
src/Hasher.h
|
@ -31,6 +31,10 @@ public:
|
||||||
|
|
||||||
virtual digest_vector Hash(const void* x, size_t n) const = 0;
|
virtual digest_vector Hash(const void* x, size_t n) const = 0;
|
||||||
|
|
||||||
|
virtual Hasher* Clone() const = 0;
|
||||||
|
|
||||||
|
virtual bool Equals(const Hasher* other) const = 0;
|
||||||
|
|
||||||
size_t K() const { return k_; }
|
size_t K() const { return k_; }
|
||||||
const std::string& Name() const { return name_; }
|
const std::string& Name() const { return name_; }
|
||||||
|
|
||||||
|
@ -64,6 +68,16 @@ protected:
|
||||||
return hash(x, n);
|
return hash(x, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const UHF& x, const UHF& y)
|
||||||
|
{
|
||||||
|
return x.h_ == y.h_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const UHF& x, const UHF& y)
|
||||||
|
{
|
||||||
|
return ! (x == y);
|
||||||
|
}
|
||||||
|
|
||||||
digest hash(const void* x, size_t n) const;
|
digest hash(const void* x, size_t n) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -87,6 +101,8 @@ public:
|
||||||
DefaultHasher(size_t k, const std::string& name);
|
DefaultHasher(size_t k, const std::string& name);
|
||||||
|
|
||||||
virtual digest_vector Hash(const void* x, size_t n) const /* final */;
|
virtual digest_vector Hash(const void* x, size_t n) const /* final */;
|
||||||
|
virtual DefaultHasher* Clone() const /* final */;
|
||||||
|
virtual bool Equals(const Hasher* other) const /* final */;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<UHF> hash_functions_;
|
std::vector<UHF> hash_functions_;
|
||||||
|
@ -100,6 +116,8 @@ public:
|
||||||
DoubleHasher(size_t k, const std::string& name);
|
DoubleHasher(size_t k, const std::string& name);
|
||||||
|
|
||||||
virtual digest_vector Hash(const void* x, size_t n) const /* final */;
|
virtual digest_vector Hash(const void* x, size_t n) const /* final */;
|
||||||
|
virtual DoubleHasher* Clone() const /* final */;
|
||||||
|
virtual bool Equals(const Hasher* other) const /* final */;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UHF h1_;
|
UHF h1_;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue