52static inline uint64_t
murmur3_64(
const void* key,
size_t len, uint32_t seed=0xB00B1E){
53 const uint8_t* data = (
const uint8_t*)key;
const int nblocks = len / 16;
54 uint64_t h1 = seed, h2 = seed;
55 const uint64_t c1 = 0x87c37b91114253d5ULL, c2 = 0x4cf5ad432745937fULL;
56 const uint64_t* blocks = (
const uint64_t*)(data);
57 for(
int i = 0; i < nblocks; i++){
58 uint64_t k1 = blocks[i*2+0]; uint64_t k2 = blocks[i*2+1];
59 k1 *= c1; k1 =
rotl64(k1,31); k1 *= c2; h1 ^= k1; h1 =
rotl64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
60 k2 *= c2; k2 =
rotl64(k2,33); k2 *= c1; h2 ^= k2; h2 =
rotl64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
62 const uint8_t* tail = (
const uint8_t*)(data + nblocks*16);
63 uint64_t k1 = 0, k2 = 0;
65 case 15: k2 ^= ((uint64_t)tail[14]) << 48; [[fallthrough]];
66 case 14: k2 ^= ((uint64_t)tail[13]) << 40; [[fallthrough]];
67 case 13: k2 ^= ((uint64_t)tail[12]) << 32; [[fallthrough]];
68 case 12: k2 ^= ((uint64_t)tail[11]) << 24; [[fallthrough]];
69 case 11: k2 ^= ((uint64_t)tail[10]) << 16; [[fallthrough]];
70 case 10: k2 ^= ((uint64_t)tail[9]) << 8; [[fallthrough]];
71 case 9: k2 ^= ((uint64_t)tail[8]) << 0; k2 *= c2; k2 =
rotl64(k2,33); k2 *= c1; h2 ^= k2; [[fallthrough]];
72 case 8: k1 ^= ((uint64_t)tail[7]) << 56; [[fallthrough]];
73 case 7: k1 ^= ((uint64_t)tail[6]) << 48; [[fallthrough]];
74 case 6: k1 ^= ((uint64_t)tail[5]) << 40; [[fallthrough]];
75 case 5: k1 ^= ((uint64_t)tail[4]) << 32; [[fallthrough]];
76 case 4: k1 ^= ((uint64_t)tail[3]) << 24; [[fallthrough]];
77 case 3: k1 ^= ((uint64_t)tail[2]) << 16; [[fallthrough]];
78 case 2: k1 ^= ((uint64_t)tail[1]) << 8; [[fallthrough]];
79 case 1: k1 ^= ((uint64_t)tail[0]) << 0; k1 *= c1; k1 =
rotl64(k1,31); k1 *= c2; h1 ^= k1; [[fallthrough]];
82 h1 ^= len; h2 ^= len; h1 += h2; h2 += h1; h1 =
fmix64(h1); h2 =
fmix64(h2); h1 += h2;
139 size_t cap; std::list<uint64_t>
order; std::unordered_map<uint64_t, std::pair<bool,std::list<uint64_t>::iterator>>
map;
141 bool get(uint64_t k,
bool &out){
auto it =
map.find(k);
if(it==
map.end())
return false;
order.erase(it->second.second);
order.push_front(k); it->second.second =
order.begin(); out = it->second.first;
return true; }
142 void put(uint64_t k,
bool v){
auto it =
map.find(k);
if(it!=
map.end()){ it->second.first=v;
order.erase(it->second.second);
order.push_front(k); it->second.second=
order.begin();
return;}
if(
map.size()>=
cap){ uint64_t ev =
order.back();
order.pop_back();
map.erase(ev);}
order.push_front(k);
map.emplace(k, std::make_pair(v,
order.begin())); }
208 sqlite3* db =
nullptr;
209 if (sqlite3_open(db_path.c_str(), &db) != SQLITE_OK)
return false;
211 std::string sql =
"SELECT pattern, is_regex FROM " + table +
";";
212 sqlite3_stmt* stmt =
nullptr;
213 if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt,
nullptr) != SQLITE_OK) {
218 std::vector<std::string> pats; pats.reserve(100000);
219 std::vector<std::string> regex_pats; regex_pats.reserve(10000);
221 while (sqlite3_step(stmt) == SQLITE_ROW) {
222 const unsigned char* p = sqlite3_column_text(stmt, 0);
223 int is_regex = sqlite3_column_int(stmt, 1);
225 std::string s =
reinterpret_cast<const char*
>(p);
227 if (s.empty())
continue;
228 if (is_regex) regex_pats.push_back(s);
else pats.push_back(s);
230 sqlite3_finalize(stmt);
236 for (
auto& p : pats)
ac.
add(p);
240#ifdef FASTFILTER_USE_RE2
242 for (
auto& r : regex_pats) regexes.emplace_back(std::make_unique<RE2>(r));