Skip to content

Commit 2f3a62b

Browse files
committed
Add multi-type support to bloom filter bindings
- Add efficient overloads for different Python data types: * uint64_t for non-negative integers * int64_t for negative/positive integers * double for floats * std::string for strings * bytes objects for binary data - Use proper static_cast syntax for nanobind compatibility - Add comprehensive unit test for all supported data types - Remove memoryview support (not available in nanobind) - All 16 bloom filter tests pass
1 parent ffe1039 commit 2f3a62b

2 files changed

Lines changed: 70 additions & 2 deletions

File tree

src/bloom_filter_wrapper.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,57 @@ void bind_bloom_filter(nb::module_ &m, const char* name) {
3434
nb::class_<bloom_filter_type>(m, name)
3535
.def("is_empty", &bloom_filter_type::is_empty,
3636
"Returns True if the filter has seen no items, otherwise False")
37+
38+
// Update methods - efficient overloads for Python types
39+
// Non-negative integers (uint64_t)
40+
.def("update", static_cast<void (bloom_filter_type::*)(uint64_t)>(&bloom_filter_type::update),
41+
nb::arg("item"),
42+
"Updates the filter with a non-negative integer")
43+
// Negative/positive integers (int64_t)
44+
.def("update", static_cast<void (bloom_filter_type::*)(int64_t)>(&bloom_filter_type::update),
45+
nb::arg("item"),
46+
"Updates the filter with a negative/positive integer")
47+
// Float (double)
48+
.def("update", static_cast<void (bloom_filter_type::*)(double)>(&bloom_filter_type::update),
49+
nb::arg("item"),
50+
"Updates the filter with a float")
51+
// String (std::string)
3752
.def("update", static_cast<void (bloom_filter_type::*)(const std::string&)>(&bloom_filter_type::update),
3853
nb::arg("item"),
39-
"Updates the filter with the given string")
54+
"Updates the filter with a string")
55+
// Bytes object
56+
.def("update",
57+
[](bloom_filter_type& self, nb::bytes b) {
58+
self.update(b.c_str(), b.size());
59+
},
60+
nb::arg("item"),
61+
"Updates the filter with a bytes object")
62+
63+
// Query methods - efficient overloads for Python types
64+
// Non-negative integers (uint64_t)
65+
.def("query", static_cast<bool (bloom_filter_type::*)(uint64_t) const>(&bloom_filter_type::query),
66+
nb::arg("item"),
67+
"Queries the filter for a non-negative integer")
68+
// Negative/positive integers (int64_t)
69+
.def("query", static_cast<bool (bloom_filter_type::*)(int64_t) const>(&bloom_filter_type::query),
70+
nb::arg("item"),
71+
"Queries the filter for a negative/positive integer")
72+
// Float (double)
73+
.def("query", static_cast<bool (bloom_filter_type::*)(double) const>(&bloom_filter_type::query),
74+
nb::arg("item"),
75+
"Queries the filter for a float")
76+
// String (std::string)
4077
.def("query", static_cast<bool (bloom_filter_type::*)(const std::string&) const>(&bloom_filter_type::query),
4178
nb::arg("item"),
42-
"Queries the filter for the given string")
79+
"Queries the filter for a string")
80+
// Bytes object
81+
.def("query",
82+
[](const bloom_filter_type& self, nb::bytes b) -> bool {
83+
return self.query(b.c_str(), b.size());
84+
},
85+
nb::arg("item"),
86+
"Queries the filter for a bytes object")
87+
4388
.def("reset", &bloom_filter_type::reset,
4489
"Resets the Bloom filter to its original empty state")
4590
.def("get_serialized_size_bytes",

tests/bloom_filter_test.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,29 @@ def test_basic_operations(self):
8484
for i in range(num_items):
8585
self.assertTrue(new_bf.query(str(i)))
8686

87+
def test_update_types(self):
88+
"""Test update and query with different data types."""
89+
bf = bloom_filter.create_by_accuracy(1000, 0.01)
90+
91+
# Test integers (positive and negative)
92+
for v in [0, 1, 2**40, -1, -2**40]:
93+
bf.update(v)
94+
self.assertTrue(bf.query(v))
95+
96+
# Test floats
97+
for v in [0.5, -3.25]:
98+
bf.update(v)
99+
self.assertTrue(bf.query(v))
100+
101+
# Test strings
102+
bf.update("hello")
103+
self.assertTrue(bf.query("hello"))
104+
105+
# Test bytes
106+
b = b"abc\x00def"
107+
bf.update(b)
108+
self.assertTrue(bf.query(b))
109+
87110
def test_reset_method(self):
88111
"""Test the reset method functionality."""
89112
bf = bloom_filter.create_by_accuracy(1000, 0.01)

0 commit comments

Comments
 (0)