TestBloomFilter.cpp (4303B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/Assertions.h" 8 #include "mozilla/BloomFilter.h" 9 #include "mozilla/UniquePtr.h" 10 11 #include <stddef.h> 12 #include <stdint.h> 13 14 using mozilla::BitBloomFilter; 15 using mozilla::CountingBloomFilter; 16 17 class FilterChecker { 18 public: 19 explicit FilterChecker(uint32_t aHash) : mHash(aHash) {} 20 21 uint32_t hash() const { return mHash; } 22 23 private: 24 uint32_t mHash; 25 }; 26 27 void testBitBloomFilter() { 28 const auto filter = mozilla::MakeUnique<BitBloomFilter<12, FilterChecker>>(); 29 MOZ_RELEASE_ASSERT(filter); 30 31 FilterChecker one(1); 32 FilterChecker two(0x20000); 33 34 filter->add(&one); 35 MOZ_RELEASE_ASSERT(filter->mightContain(&one), "Filter should contain 'one'"); 36 37 MOZ_RELEASE_ASSERT(!filter->mightContain(&two), 38 "Filter claims to contain 'two' when it should not"); 39 40 // Test multiple addition 41 filter->add(&two); 42 MOZ_RELEASE_ASSERT(filter->mightContain(&two), 43 "Filter should contain 'two' after 'two' is added"); 44 filter->add(&two); 45 MOZ_RELEASE_ASSERT(filter->mightContain(&two), 46 "Filter should contain 'two' after 'two' is added again"); 47 48 filter->clear(); 49 50 MOZ_RELEASE_ASSERT(!filter->mightContain(&one), "clear() failed to work"); 51 MOZ_RELEASE_ASSERT(!filter->mightContain(&two), "clear() failed to work"); 52 } 53 54 void testCountingBloomFilter() { 55 const auto filter = 56 mozilla::MakeUnique<CountingBloomFilter<12, FilterChecker>>(); 57 MOZ_RELEASE_ASSERT(filter); 58 59 FilterChecker one(1); 60 FilterChecker two(0x20000); 61 FilterChecker many(0x10000); 62 FilterChecker multiple(0x20001); 63 64 filter->add(&one); 65 MOZ_RELEASE_ASSERT(filter->mightContain(&one), "Filter should contain 'one'"); 66 67 MOZ_RELEASE_ASSERT(!filter->mightContain(&multiple), 68 "Filter claims to contain 'multiple' when it should not"); 69 70 MOZ_RELEASE_ASSERT(filter->mightContain(&many), 71 "Filter should contain 'many' (false positive)"); 72 73 filter->add(&two); 74 MOZ_RELEASE_ASSERT(filter->mightContain(&multiple), 75 "Filter should contain 'multiple' (false positive)"); 76 77 // Test basic removals 78 filter->remove(&two); 79 MOZ_RELEASE_ASSERT( 80 !filter->mightContain(&multiple), 81 "Filter claims to contain 'multiple' when it should not after two " 82 "was removed"); 83 84 // Test multiple addition/removal 85 const size_t FILTER_SIZE = 255; 86 for (size_t i = 0; i < FILTER_SIZE - 1; ++i) { 87 filter->add(&two); 88 } 89 MOZ_RELEASE_ASSERT( 90 filter->mightContain(&multiple), 91 "Filter should contain 'multiple' after 'two' added lots of times " 92 "(false positive)"); 93 94 for (size_t i = 0; i < FILTER_SIZE - 1; ++i) { 95 filter->remove(&two); 96 } 97 MOZ_RELEASE_ASSERT( 98 !filter->mightContain(&multiple), 99 "Filter claims to contain 'multiple' when it should not after two " 100 "was removed lots of times"); 101 102 // Test overflowing the filter buckets 103 for (size_t i = 0; i < FILTER_SIZE + 1; ++i) { 104 filter->add(&two); 105 } 106 MOZ_RELEASE_ASSERT( 107 filter->mightContain(&multiple), 108 "Filter should contain 'multiple' after 'two' added lots more " 109 "times (false positive)"); 110 111 for (size_t i = 0; i < FILTER_SIZE + 1; ++i) { 112 filter->remove(&two); 113 } 114 MOZ_RELEASE_ASSERT( 115 filter->mightContain(&multiple), 116 "Filter claims to not contain 'multiple' even though we should " 117 "have run out of space in the buckets (false positive)"); 118 MOZ_RELEASE_ASSERT( 119 filter->mightContain(&two), 120 "Filter claims to not contain 'two' even though we should have " 121 "run out of space in the buckets (false positive)"); 122 123 filter->remove(&one); 124 125 MOZ_RELEASE_ASSERT( 126 !filter->mightContain(&one), 127 "Filter should not contain 'one', because we didn't overflow its " 128 "bucket"); 129 130 filter->clear(); 131 132 MOZ_RELEASE_ASSERT(!filter->mightContain(&multiple), 133 "clear() failed to work"); 134 } 135 136 int main() { 137 testBitBloomFilter(); 138 testCountingBloomFilter(); 139 140 return 0; 141 }