From 194e71b4c5a5904f13a967b231bd7dd3386b555f Mon Sep 17 00:00:00 2001
From: peterjc
Date: Wed, 12 Sep 2012 15:19:47 +0100
Subject: [PATCH] Support 'key in bloom' in Python wrapper.
This is a more Pythonic usage than bloom.check(key), normally
implemented via a __contains__ method for a class written in
Python, but here via the sq_contains slot in the C code. Note
this implementation Only looks for strings (anything else
returns False).
---
pydablooms/pydablooms.c | 23 ++++++++++++++++++++++-
pydablooms/test_pydablooms.py | 6 +++++-
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/pydablooms/pydablooms.c b/pydablooms/pydablooms.c
index 2074b29..004c341 100644
--- a/pydablooms/pydablooms.c
+++ b/pydablooms/pydablooms.c
@@ -45,6 +45,16 @@ static int Dablooms_init(Dablooms *self, PyObject *args, PyObject *kwds)
return 0;
}
+static int contains(Dablooms *self, PyObject *key)
+{
+ if (!PyString_Check(key)) {
+ return 0; /* return False */
+ }
+ return scaling_bloom_check(self->filter,
+ PyString_AsString(key),
+ (int)PyString_Size(key));
+}
+
static PyObject *check(Dablooms *self, PyObject *args)
{
const char *hash;
@@ -113,6 +123,17 @@ static PyMemberDef Dablooms_members[] = {
{NULL} /* Sentinel */
};
+static PySequenceMethods Dablooms_sequence = {
+ NULL, /*sq_length*/
+ NULL, /*sq_concat*/
+ NULL, /*sq_repeat*/
+ NULL, /*sq_item*/
+ NULL, /*sq_slice*/
+ NULL, /*sq_ass_item*/
+ NULL, /*sq_ass_slice*/
+ (objobjproc)contains, /*sq_contains*/
+};
+
static PyTypeObject DabloomsType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
@@ -126,7 +147,7 @@ static PyTypeObject DabloomsType = {
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
+ &Dablooms_sequence, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
diff --git a/pydablooms/test_pydablooms.py b/pydablooms/test_pydablooms.py
index bd53f69..d8892f7 100644
--- a/pydablooms/test_pydablooms.py
+++ b/pydablooms/test_pydablooms.py
@@ -46,7 +46,11 @@
i = 0
for line in words_file:
exists = bloom.check(line.rstrip())
-
+ contains = line.rstrip() in bloom
+ assert exists == contains, \
+ "ERROR: %r from 'bloom.check(x)', %i from 'x in bloom'" \
+ % (exists, contains)
+
if i % 5 == 0:
if exists:
false_positives += 1