Improved bloom filter
This commit is contained in:
+33
-18
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Authored by Alex Hultman, 2018-2019.
|
* Authored by Alex Hultman, 2018-2022.
|
||||||
* Intellectual property of third-party.
|
* Intellectual property of third-party.
|
||||||
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
#ifndef UWS_BLOOMFILTER_H
|
#ifndef UWS_BLOOMFILTER_H
|
||||||
#define UWS_BLOOMFILTER_H
|
#define UWS_BLOOMFILTER_H
|
||||||
|
|
||||||
/* This filter has a decently low amount of false positives for the
|
/* This filter has no false positives or collisions for the standard
|
||||||
* standard and non-standard common request headers */
|
* and non-standard common request headers */
|
||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
@@ -28,32 +28,47 @@ namespace uWS {
|
|||||||
|
|
||||||
struct BloomFilter {
|
struct BloomFilter {
|
||||||
private:
|
private:
|
||||||
std::bitset<512> filter;
|
std::bitset<256> filter;
|
||||||
|
static inline uint32_t perfectHash(uint32_t features) {
|
||||||
unsigned int hash1(std::string_view key) {
|
return features *= 1843993368;
|
||||||
return ((size_t)key[key.length() - 1] - (key.length() << 3)) & 511;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int hash2(std::string_view key) {
|
union ScrambleArea {
|
||||||
return (((size_t)key[0] + (key.length() << 4)) & 511);
|
unsigned char p[4];
|
||||||
}
|
uint32_t val;
|
||||||
|
};
|
||||||
|
|
||||||
unsigned int hash3(std::string_view key) {
|
ScrambleArea getFeatures(std::string_view key) {
|
||||||
return ((unsigned int)key[key.length() - 2] - 97 - (key.length() << 5)) & 511;
|
ScrambleArea s;
|
||||||
|
s.p[0] = key[0];
|
||||||
|
s.p[1] = key[key.length() - 1];
|
||||||
|
s.p[2] = key[key.length() - 2];
|
||||||
|
s.p[3] = key[key.length() >> 1];
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool mightHave(std::string_view key) {
|
bool mightHave(std::string_view key) {
|
||||||
return !key.length() || (filter.test(hash1(key)) && filter.test(hash2(key)) && (key.length() < 2 || filter.test(hash3(key))));
|
if (key.length() < 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrambleArea s = getFeatures(key);
|
||||||
|
s.val = perfectHash(s.val);
|
||||||
|
return filter.test(s.p[0]) &
|
||||||
|
filter.test(s.p[1]) &
|
||||||
|
filter.test(s.p[2]) &
|
||||||
|
filter.test(s.p[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(std::string_view key) {
|
void add(std::string_view key) {
|
||||||
if (key.length()) {
|
|
||||||
filter.set(hash1(key));
|
|
||||||
filter.set(hash2(key));
|
|
||||||
}
|
|
||||||
if (key.length() >= 2) {
|
if (key.length() >= 2) {
|
||||||
filter.set(hash3(key));
|
ScrambleArea s = getFeatures(key);
|
||||||
|
s.val = perfectHash(s.val);
|
||||||
|
filter.set(s.p[0]);
|
||||||
|
filter.set(s.p[1]);
|
||||||
|
filter.set(s.p[2]);
|
||||||
|
filter.set(s.p[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user