-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathXorFilterTest.cc
More file actions
93 lines (74 loc) · 2.58 KB
/
Copy pathXorFilterTest.cc
File metadata and controls
93 lines (74 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <gtest/gtest.h>
#include <fstream>
#include <sstream>
#include <unistd.h>
#include <cereal/archives/binary.hpp>
#include <src/construct/filter/XorFilter.h>
namespace caramel::tests {
TEST(XorFilterTest, SimpleAddAndCheck) {
auto xf = XorFilter::make(100);
std::vector<std::string> inserted_keys = {
"apple", "banana", "cherry", "date", "elderberry",
"fig", "grape", "honeydew", "kiwi", "lemon",
"mango", "nectarine", "orange", "papaya", "quince"};
for (const auto &key : inserted_keys) {
xf->add(key);
}
// Build the filter after adding all keys
xf->build();
for (const auto &key : inserted_keys) {
ASSERT_TRUE(xf->contains(key))
<< "Key '" << key << "' must be in the filter (no false negatives)";
}
std::vector<std::string> not_inserted_keys = {
"strawberry", "watermelon", "pear", "plum", "guava",
"lychee", "dragonfruit", "passionfruit", "starfruit", "durian"};
int false_positives = 0;
for (const auto &key : not_inserted_keys) {
if (xf->contains(key)) {
false_positives++;
}
}
// Xor filters have ~0.39% FPR, so with 10 queries we expect 0-1 false positives
ASSERT_LE(false_positives, 2)
<< "Too many false positives for xor filter with "
<< not_inserted_keys.size() << " queries";
}
TEST(XorFilterTest, SaveAndLoad) {
std::ostringstream filename;
filename << "/tmp/xor_filter_test_" << getpid() << ".bin";
std::string test_file = filename.str();
// Create and populate a xor filter
auto xf_original = XorFilter::make(100);
std::vector<std::string> test_keys = {
"apple", "banana", "cherry", "date", "elderberry",
"fig", "grape", "honeydew", "kiwi", "lemon"};
for (const auto &key : test_keys) {
xf_original->add(key);
}
xf_original->build();
// Save to file
{
std::ofstream ofs(test_file, std::ios::binary);
cereal::BinaryOutputArchive oarchive(ofs);
oarchive(*xf_original);
}
// Load from file
auto xf_loaded = XorFilter::make(1); // Temporary, will be overwritten by deserialize
{
std::ifstream ifs(test_file, std::ios::binary);
cereal::BinaryInputArchive iarchive(ifs);
iarchive(*xf_loaded);
}
// Verify loaded filter works correctly
for (const auto &key : test_keys) {
ASSERT_TRUE(xf_loaded->contains(key))
<< "Loaded filter should contain key: " << key;
}
// Verify size matches
ASSERT_EQ(xf_loaded->size(), xf_original->size());
ASSERT_EQ(xf_loaded->numElements(), xf_original->numElements());
// Clean up
std::remove(test_file.c_str());
}
} // namespace caramel::tests