From fb8b78840b825fef55ebf9520ad0dfef18726dba Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 29 Aug 2013 11:24:24 -0500 Subject: [PATCH] Fix bloom filter memory leaks. --- src/probabilistic/BloomFilter.cc | 10 +++ src/probabilistic/BloomFilter.h | 10 +++ testing/btest/core/leaks/bloomfilter.bro | 101 +++++++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 testing/btest/core/leaks/bloomfilter.bro diff --git a/src/probabilistic/BloomFilter.cc b/src/probabilistic/BloomFilter.cc index 4d5c5171ec..f6e4017626 100644 --- a/src/probabilistic/BloomFilter.cc +++ b/src/probabilistic/BloomFilter.cc @@ -125,6 +125,11 @@ BasicBloomFilter::BasicBloomFilter(const Hasher* hasher, size_t cells) bits = new BitVector(cells); } +BasicBloomFilter::~BasicBloomFilter() + { + delete bits; + } + IMPLEMENT_SERIAL(BasicBloomFilter, SER_BASICBLOOMFILTER) bool BasicBloomFilter::DoSerialize(SerialInfo* info) const @@ -173,6 +178,11 @@ CountingBloomFilter::CountingBloomFilter(const Hasher* hasher, cells = new CounterVector(width, arg_cells); } +CountingBloomFilter::~CountingBloomFilter() + { + delete cells; + } + bool CountingBloomFilter::Empty() const { return cells->AllZero(); diff --git a/src/probabilistic/BloomFilter.h b/src/probabilistic/BloomFilter.h index 65dda2396d..53b66c377e 100644 --- a/src/probabilistic/BloomFilter.h +++ b/src/probabilistic/BloomFilter.h @@ -124,6 +124,11 @@ public: */ BasicBloomFilter(const Hasher* hasher, size_t cells); + /** + * Destructor. + */ + ~BasicBloomFilter(); + /** * Computes the number of cells based on a given false positive rate * and capacity. In the literature, this parameter often has the name @@ -192,6 +197,11 @@ public: */ CountingBloomFilter(const Hasher* hasher, size_t cells, size_t width); + /** + * Destructor. + */ + ~CountingBloomFilter(); + // Overridden from BloomFilter. virtual bool Empty() const; virtual void Clear(); diff --git a/testing/btest/core/leaks/bloomfilter.bro b/testing/btest/core/leaks/bloomfilter.bro new file mode 100644 index 0000000000..6d9b74114e --- /dev/null +++ b/testing/btest/core/leaks/bloomfilter.bro @@ -0,0 +1,101 @@ +# Needs perftools support. +# +# @TEST-GROUP: leaks +# +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run bro bro -m -b -r $TRACES/wikipedia.trace %INPUT +# @TEST-EXEC: btest-bg-wait 15 + +function test_basic_bloom_filter() + { + # Basic usage with counts. + local bf_cnt = bloomfilter_basic_init(0.1, 1000); + bloomfilter_add(bf_cnt, 42); + bloomfilter_add(bf_cnt, 84); + bloomfilter_add(bf_cnt, 168); + print bloomfilter_lookup(bf_cnt, 0); + print bloomfilter_lookup(bf_cnt, 42); + print bloomfilter_lookup(bf_cnt, 168); + print bloomfilter_lookup(bf_cnt, 336); + bloomfilter_add(bf_cnt, 0.5); # Type mismatch + bloomfilter_add(bf_cnt, "foo"); # Type mismatch + + # Alternative constructor. + local bf_dbl = bloomfilter_basic_init2(4, 10); + bloomfilter_add(bf_dbl, 4.2); + bloomfilter_add(bf_dbl, 3.14); + print bloomfilter_lookup(bf_dbl, 4.2); + print bloomfilter_lookup(bf_dbl, 3.14); + + # Basic usage with strings. + local bf_str = bloomfilter_basic_init(0.9, 10); + bloomfilter_add(bf_str, "foo"); + bloomfilter_add(bf_str, "bar"); + print bloomfilter_lookup(bf_str, "foo"); + print bloomfilter_lookup(bf_str, "bar"); + print bloomfilter_lookup(bf_str, "bazzz"), "fp"; # FP + print bloomfilter_lookup(bf_str, "quuux"), "fp"; # FP + bloomfilter_add(bf_str, 0.5); # Type mismatch + bloomfilter_add(bf_str, 100); # Type mismatch + + # Edge cases. + local bf_edge0 = bloomfilter_basic_init(0.000000000001, 1); + local bf_edge1 = bloomfilter_basic_init(0.00000001, 100000000); + local bf_edge2 = bloomfilter_basic_init(0.9999999, 1); + local bf_edge3 = bloomfilter_basic_init(0.9999999, 100000000000); + + # Invalid parameters. + local bf_bug0 = bloomfilter_basic_init(-0.5, 42); + local bf_bug1 = bloomfilter_basic_init(1.1, 42); + + # Merging + local bf_cnt2 = bloomfilter_basic_init(0.1, 1000); + bloomfilter_add(bf_cnt2, 42); + bloomfilter_add(bf_cnt, 100); + local bf_merged = bloomfilter_merge(bf_cnt, bf_cnt2); + print bloomfilter_lookup(bf_merged, 42); + print bloomfilter_lookup(bf_merged, 84); + print bloomfilter_lookup(bf_merged, 100); + print bloomfilter_lookup(bf_merged, 168); + + #empty filter tests + local bf_empty = bloomfilter_basic_init(0.1, 1000); + local bf_empty_merged = bloomfilter_merge(bf_merged, bf_empty); + print bloomfilter_lookup(bf_empty_merged, 42); + } + +function test_counting_bloom_filter() + { + local bf = bloomfilter_counting_init(3, 32, 3); + bloomfilter_add(bf, "foo"); + print bloomfilter_lookup(bf, "foo"); # 1 + bloomfilter_add(bf, "foo"); + print bloomfilter_lookup(bf, "foo"); # 2 + bloomfilter_add(bf, "foo"); + print bloomfilter_lookup(bf, "foo"); # 3 + bloomfilter_add(bf, "foo"); + print bloomfilter_lookup(bf, "foo"); # still 3 + + + bloomfilter_add(bf, "bar"); + bloomfilter_add(bf, "bar"); + print bloomfilter_lookup(bf, "bar"); # 2 + print bloomfilter_lookup(bf, "foo"); # still 3 + + # Merging + local bf2 = bloomfilter_counting_init(3, 32, 3); + bloomfilter_add(bf2, "baz"); + bloomfilter_add(bf2, "baz"); + bloomfilter_add(bf2, "bar"); + local bf_merged = bloomfilter_merge(bf, bf2); + print bloomfilter_lookup(bf_merged, "foo"); + print bloomfilter_lookup(bf_merged, "bar"); + print bloomfilter_lookup(bf_merged, "baz"); + } + +event new_connection(c: connection) + { + test_basic_bloom_filter(); + test_counting_bloom_filter(); + }