pub struct BloomFilter<T: ?Sized> { /* private fields */ }Expand description
A space and time efficient Bloom Filter implementation.
This structure uses a Vec<u64> as a bit array for memory efficiency and
implements double-hashing to simulate k hash functions with only two
real hash computations.
§Type Parameters
T: The type of values to be stored. Must implementHash.
Implementations§
Source§impl<T: ?Sized + Hash> BloomFilter<T>
impl<T: ?Sized + Hash> BloomFilter<T>
Sourcepub fn new(expected_items: usize, params: impl Into<FilterParams>) -> Self
pub fn new(expected_items: usize, params: impl Into<FilterParams>) -> Self
Creates a new Bloom Filter optimized for the given expected item count and configuration (either false positive rate or hash count).
§Arguments
expected_items- The expected number of items to insert (n).params- Either af64(false positive rate) oru32(number of hashes).
§Examples
use bloomlib::BloomFilter;
// Initialize with a desired false positive rate
let mut bf1: BloomFilter<str> = BloomFilter::new(1000, 0.01);
// Initialize with a specific hash count
let mut bf2: BloomFilter<str> = BloomFilter::new(1000, 7u32);
// Insert an item
bf1.insert("seen");
// Check for an item
_ = bf1.contains("seen");
_ = bf1.contains("unseen");
// Clear the filter
bf1.clear();§Panics
Panics if expected_items is 0, or if configuration parameters are invalid
(e.g., rate <= 0.0, rate >= 1.0, or hashes == 0).
Examples found in repository?
3fn main() {
4 // Configuration
5 let expected_elements = 100_000;
6
7 // You can initialize with a false positive rate
8 let fp_rate = 0.01;
9 let mut filter = BloomFilter::new(expected_elements, fp_rate);
10
11 // OR initialize using a specific hash count (commented out example)
12 // let hashes = 7u32;
13 // let mut filter = BloomFilter::new(expected_elements, hashes);
14
15 println!("Initializing Bloom Filter...");
16 println!("Expected elements: {}", expected_elements);
17 println!("Target False Positive Rate: {}", fp_rate);
18 println!("Actual Hash Count (k): {}", filter.hash_count());
19
20 // Insert data
21 println!("Inserting values 0 to {}...", expected_elements);
22 for i in 0..expected_elements {
23 filter.insert(&i);
24 }
25
26 // Check true positives
27 println!("Checking 10 known values...");
28 let mut present_count = 0;
29 for i in 0..10 {
30 if filter.contains(&i) {
31 present_count += 1;
32 }
33 }
34 println!("Found {}/10 known values (Should be 10)", present_count);
35
36 // Check false positives
37 // We check numbers outside the inserted range.
38 let check_range_start = expected_elements;
39 let check_range_end = expected_elements + 10_000;
40 println!(
41 "Checking range {} to {} for false positives...",
42 check_range_start, check_range_end
43 );
44
45 let mut fp_count = 0;
46 for i in check_range_start..check_range_end {
47 if filter.contains(&i) {
48 fp_count += 1;
49 }
50 }
51
52 let actual_fp_rate = fp_count as f64 / 10_000.0;
53 println!("False Positives found: {}", fp_count);
54 println!(
55 "Actual FP Rate: {:.4} (Target: {})",
56 actual_fp_rate, actual_fp_rate
57 );
58}More examples
33fn run_benchmark(n: usize, fp_rate: f64) {
34 // --- Setup ---
35 let mut bf = BloomFilter::new(n, fp_rate);
36 let mut rng = Random::new(12345);
37
38 println!("\n---------- Bloom Filter Performance Benchmark -----------\n");
39 println!("Items: {}", n);
40 println!("Target FP Rate: {}", fp_rate);
41 println!("Hash Count: {}", bf.hash_count());
42 println!("\n---------------------------------------------------------\n");
43
44 // Generate data
45 let mut dataset = Vec::with_capacity(n);
46 for _ in 0..n {
47 dataset.push(rng.next_u64());
48 }
49
50 // --- Metric 1: Memory Usage ---
51 let ki = 1024.0;
52 let memory_bytes = bf.memory_usage_bytes();
53 let memory_mb = memory_bytes as f64 / ki / ki;
54 println!("[Memory Usage]");
55 println!(
56 "{:<22}{:.2} MB ({} bytes)",
57 "Bit Vector Size", memory_mb, memory_bytes
58 );
59 println!(
60 "{:<22}{:.2} bits",
61 "Bits per item",
62 (memory_bytes * 8) as f64 / n as f64
63 );
64
65 // --- Metric 2: Insert Performance ---
66 println!("\n[Insertion Performance]");
67 let start_insert = Instant::now();
68 for item in &dataset {
69 bf.insert(item);
70 }
71 let duration_insert = start_insert.elapsed();
72 print_timing(duration_insert, n);
73
74 // --- Metric 3: Worst Case Lookup (Seen Items) ---
75 // The worst case for Bloom Filter is when the item has been seen before.
76 // The algorithm MUST compute all k hashes and check k bits.
77 println!("\n[Lookup Performance - Worst Case (Seen Items)]");
78 let start_worst = Instant::now();
79 for item in &dataset {
80 // Assign the result to a volatile variable to prevent compiler optimization
81 let _ = std::hint::black_box(bf.contains(item));
82 }
83 let duration_worst = start_worst.elapsed();
84 print_timing(duration_worst, n);
85
86 // --- Metric 4: Average Case Lookup (Unseen Items) ---
87 // In a well-tuned Bloom Filter (50% bits set), an unseen item
88 // often fails on the 1st or 2nd bit check.
89 println!("\n[Lookup Performance - Average Case (Unseen Items)]");
90
91 // Generate new random items that are likely NOT in the set
92 let mut unseen_dataset = Vec::with_capacity(n);
93 for _ in 0..n {
94 unseen_dataset.push(rng.next_u64());
95 }
96
97 let start_avg = Instant::now();
98 for item in &unseen_dataset {
99 let _ = std::hint::black_box(bf.contains(item));
100 }
101 let duration_avg = start_avg.elapsed();
102 print_timing(duration_avg, n);
103
104 // --- Metric 5: Best Case Lookup (Empty Filter) ---
105 // The best case is checking against an empty filter; fails on the 1st bit.
106 println!("\n[Lookup Performance - Best Case (Empty Filter)]");
107 let empty_bf: BloomFilter<u64> = BloomFilter::new(n, fp_rate);
108
109 let start_best = Instant::now();
110 for item in &dataset {
111 let _ = std::hint::black_box(empty_bf.contains(item));
112 }
113 let duration_best = start_best.elapsed();
114 print_timing(duration_best, n);
115
116 println!("\n=========================================================\n");
117}Sourcepub fn insert(&mut self, item: &T)
pub fn insert(&mut self, item: &T)
Inserts an item into the Bloom Filter.
Examples found in repository?
3fn main() {
4 // Configuration
5 let expected_elements = 100_000;
6
7 // You can initialize with a false positive rate
8 let fp_rate = 0.01;
9 let mut filter = BloomFilter::new(expected_elements, fp_rate);
10
11 // OR initialize using a specific hash count (commented out example)
12 // let hashes = 7u32;
13 // let mut filter = BloomFilter::new(expected_elements, hashes);
14
15 println!("Initializing Bloom Filter...");
16 println!("Expected elements: {}", expected_elements);
17 println!("Target False Positive Rate: {}", fp_rate);
18 println!("Actual Hash Count (k): {}", filter.hash_count());
19
20 // Insert data
21 println!("Inserting values 0 to {}...", expected_elements);
22 for i in 0..expected_elements {
23 filter.insert(&i);
24 }
25
26 // Check true positives
27 println!("Checking 10 known values...");
28 let mut present_count = 0;
29 for i in 0..10 {
30 if filter.contains(&i) {
31 present_count += 1;
32 }
33 }
34 println!("Found {}/10 known values (Should be 10)", present_count);
35
36 // Check false positives
37 // We check numbers outside the inserted range.
38 let check_range_start = expected_elements;
39 let check_range_end = expected_elements + 10_000;
40 println!(
41 "Checking range {} to {} for false positives...",
42 check_range_start, check_range_end
43 );
44
45 let mut fp_count = 0;
46 for i in check_range_start..check_range_end {
47 if filter.contains(&i) {
48 fp_count += 1;
49 }
50 }
51
52 let actual_fp_rate = fp_count as f64 / 10_000.0;
53 println!("False Positives found: {}", fp_count);
54 println!(
55 "Actual FP Rate: {:.4} (Target: {})",
56 actual_fp_rate, actual_fp_rate
57 );
58}More examples
33fn run_benchmark(n: usize, fp_rate: f64) {
34 // --- Setup ---
35 let mut bf = BloomFilter::new(n, fp_rate);
36 let mut rng = Random::new(12345);
37
38 println!("\n---------- Bloom Filter Performance Benchmark -----------\n");
39 println!("Items: {}", n);
40 println!("Target FP Rate: {}", fp_rate);
41 println!("Hash Count: {}", bf.hash_count());
42 println!("\n---------------------------------------------------------\n");
43
44 // Generate data
45 let mut dataset = Vec::with_capacity(n);
46 for _ in 0..n {
47 dataset.push(rng.next_u64());
48 }
49
50 // --- Metric 1: Memory Usage ---
51 let ki = 1024.0;
52 let memory_bytes = bf.memory_usage_bytes();
53 let memory_mb = memory_bytes as f64 / ki / ki;
54 println!("[Memory Usage]");
55 println!(
56 "{:<22}{:.2} MB ({} bytes)",
57 "Bit Vector Size", memory_mb, memory_bytes
58 );
59 println!(
60 "{:<22}{:.2} bits",
61 "Bits per item",
62 (memory_bytes * 8) as f64 / n as f64
63 );
64
65 // --- Metric 2: Insert Performance ---
66 println!("\n[Insertion Performance]");
67 let start_insert = Instant::now();
68 for item in &dataset {
69 bf.insert(item);
70 }
71 let duration_insert = start_insert.elapsed();
72 print_timing(duration_insert, n);
73
74 // --- Metric 3: Worst Case Lookup (Seen Items) ---
75 // The worst case for Bloom Filter is when the item has been seen before.
76 // The algorithm MUST compute all k hashes and check k bits.
77 println!("\n[Lookup Performance - Worst Case (Seen Items)]");
78 let start_worst = Instant::now();
79 for item in &dataset {
80 // Assign the result to a volatile variable to prevent compiler optimization
81 let _ = std::hint::black_box(bf.contains(item));
82 }
83 let duration_worst = start_worst.elapsed();
84 print_timing(duration_worst, n);
85
86 // --- Metric 4: Average Case Lookup (Unseen Items) ---
87 // In a well-tuned Bloom Filter (50% bits set), an unseen item
88 // often fails on the 1st or 2nd bit check.
89 println!("\n[Lookup Performance - Average Case (Unseen Items)]");
90
91 // Generate new random items that are likely NOT in the set
92 let mut unseen_dataset = Vec::with_capacity(n);
93 for _ in 0..n {
94 unseen_dataset.push(rng.next_u64());
95 }
96
97 let start_avg = Instant::now();
98 for item in &unseen_dataset {
99 let _ = std::hint::black_box(bf.contains(item));
100 }
101 let duration_avg = start_avg.elapsed();
102 print_timing(duration_avg, n);
103
104 // --- Metric 5: Best Case Lookup (Empty Filter) ---
105 // The best case is checking against an empty filter; fails on the 1st bit.
106 println!("\n[Lookup Performance - Best Case (Empty Filter)]");
107 let empty_bf: BloomFilter<u64> = BloomFilter::new(n, fp_rate);
108
109 let start_best = Instant::now();
110 for item in &dataset {
111 let _ = std::hint::black_box(empty_bf.contains(item));
112 }
113 let duration_best = start_best.elapsed();
114 print_timing(duration_best, n);
115
116 println!("\n=========================================================\n");
117}Sourcepub fn contains(&self, item: &T) -> bool
pub fn contains(&self, item: &T) -> bool
Checks if an item might be in the Bloom Filter.
Returns true if the item might be present (with a probability of false positive).
Returns false if the item is definitely not present.
Examples found in repository?
3fn main() {
4 // Configuration
5 let expected_elements = 100_000;
6
7 // You can initialize with a false positive rate
8 let fp_rate = 0.01;
9 let mut filter = BloomFilter::new(expected_elements, fp_rate);
10
11 // OR initialize using a specific hash count (commented out example)
12 // let hashes = 7u32;
13 // let mut filter = BloomFilter::new(expected_elements, hashes);
14
15 println!("Initializing Bloom Filter...");
16 println!("Expected elements: {}", expected_elements);
17 println!("Target False Positive Rate: {}", fp_rate);
18 println!("Actual Hash Count (k): {}", filter.hash_count());
19
20 // Insert data
21 println!("Inserting values 0 to {}...", expected_elements);
22 for i in 0..expected_elements {
23 filter.insert(&i);
24 }
25
26 // Check true positives
27 println!("Checking 10 known values...");
28 let mut present_count = 0;
29 for i in 0..10 {
30 if filter.contains(&i) {
31 present_count += 1;
32 }
33 }
34 println!("Found {}/10 known values (Should be 10)", present_count);
35
36 // Check false positives
37 // We check numbers outside the inserted range.
38 let check_range_start = expected_elements;
39 let check_range_end = expected_elements + 10_000;
40 println!(
41 "Checking range {} to {} for false positives...",
42 check_range_start, check_range_end
43 );
44
45 let mut fp_count = 0;
46 for i in check_range_start..check_range_end {
47 if filter.contains(&i) {
48 fp_count += 1;
49 }
50 }
51
52 let actual_fp_rate = fp_count as f64 / 10_000.0;
53 println!("False Positives found: {}", fp_count);
54 println!(
55 "Actual FP Rate: {:.4} (Target: {})",
56 actual_fp_rate, actual_fp_rate
57 );
58}More examples
33fn run_benchmark(n: usize, fp_rate: f64) {
34 // --- Setup ---
35 let mut bf = BloomFilter::new(n, fp_rate);
36 let mut rng = Random::new(12345);
37
38 println!("\n---------- Bloom Filter Performance Benchmark -----------\n");
39 println!("Items: {}", n);
40 println!("Target FP Rate: {}", fp_rate);
41 println!("Hash Count: {}", bf.hash_count());
42 println!("\n---------------------------------------------------------\n");
43
44 // Generate data
45 let mut dataset = Vec::with_capacity(n);
46 for _ in 0..n {
47 dataset.push(rng.next_u64());
48 }
49
50 // --- Metric 1: Memory Usage ---
51 let ki = 1024.0;
52 let memory_bytes = bf.memory_usage_bytes();
53 let memory_mb = memory_bytes as f64 / ki / ki;
54 println!("[Memory Usage]");
55 println!(
56 "{:<22}{:.2} MB ({} bytes)",
57 "Bit Vector Size", memory_mb, memory_bytes
58 );
59 println!(
60 "{:<22}{:.2} bits",
61 "Bits per item",
62 (memory_bytes * 8) as f64 / n as f64
63 );
64
65 // --- Metric 2: Insert Performance ---
66 println!("\n[Insertion Performance]");
67 let start_insert = Instant::now();
68 for item in &dataset {
69 bf.insert(item);
70 }
71 let duration_insert = start_insert.elapsed();
72 print_timing(duration_insert, n);
73
74 // --- Metric 3: Worst Case Lookup (Seen Items) ---
75 // The worst case for Bloom Filter is when the item has been seen before.
76 // The algorithm MUST compute all k hashes and check k bits.
77 println!("\n[Lookup Performance - Worst Case (Seen Items)]");
78 let start_worst = Instant::now();
79 for item in &dataset {
80 // Assign the result to a volatile variable to prevent compiler optimization
81 let _ = std::hint::black_box(bf.contains(item));
82 }
83 let duration_worst = start_worst.elapsed();
84 print_timing(duration_worst, n);
85
86 // --- Metric 4: Average Case Lookup (Unseen Items) ---
87 // In a well-tuned Bloom Filter (50% bits set), an unseen item
88 // often fails on the 1st or 2nd bit check.
89 println!("\n[Lookup Performance - Average Case (Unseen Items)]");
90
91 // Generate new random items that are likely NOT in the set
92 let mut unseen_dataset = Vec::with_capacity(n);
93 for _ in 0..n {
94 unseen_dataset.push(rng.next_u64());
95 }
96
97 let start_avg = Instant::now();
98 for item in &unseen_dataset {
99 let _ = std::hint::black_box(bf.contains(item));
100 }
101 let duration_avg = start_avg.elapsed();
102 print_timing(duration_avg, n);
103
104 // --- Metric 5: Best Case Lookup (Empty Filter) ---
105 // The best case is checking against an empty filter; fails on the 1st bit.
106 println!("\n[Lookup Performance - Best Case (Empty Filter)]");
107 let empty_bf: BloomFilter<u64> = BloomFilter::new(n, fp_rate);
108
109 let start_best = Instant::now();
110 for item in &dataset {
111 let _ = std::hint::black_box(empty_bf.contains(item));
112 }
113 let duration_best = start_best.elapsed();
114 print_timing(duration_best, n);
115
116 println!("\n=========================================================\n");
117}Sourcepub fn memory_usage_bytes(&self) -> usize
pub fn memory_usage_bytes(&self) -> usize
Returns the approximate memory usage of the bit vector in bytes.
Examples found in repository?
33fn run_benchmark(n: usize, fp_rate: f64) {
34 // --- Setup ---
35 let mut bf = BloomFilter::new(n, fp_rate);
36 let mut rng = Random::new(12345);
37
38 println!("\n---------- Bloom Filter Performance Benchmark -----------\n");
39 println!("Items: {}", n);
40 println!("Target FP Rate: {}", fp_rate);
41 println!("Hash Count: {}", bf.hash_count());
42 println!("\n---------------------------------------------------------\n");
43
44 // Generate data
45 let mut dataset = Vec::with_capacity(n);
46 for _ in 0..n {
47 dataset.push(rng.next_u64());
48 }
49
50 // --- Metric 1: Memory Usage ---
51 let ki = 1024.0;
52 let memory_bytes = bf.memory_usage_bytes();
53 let memory_mb = memory_bytes as f64 / ki / ki;
54 println!("[Memory Usage]");
55 println!(
56 "{:<22}{:.2} MB ({} bytes)",
57 "Bit Vector Size", memory_mb, memory_bytes
58 );
59 println!(
60 "{:<22}{:.2} bits",
61 "Bits per item",
62 (memory_bytes * 8) as f64 / n as f64
63 );
64
65 // --- Metric 2: Insert Performance ---
66 println!("\n[Insertion Performance]");
67 let start_insert = Instant::now();
68 for item in &dataset {
69 bf.insert(item);
70 }
71 let duration_insert = start_insert.elapsed();
72 print_timing(duration_insert, n);
73
74 // --- Metric 3: Worst Case Lookup (Seen Items) ---
75 // The worst case for Bloom Filter is when the item has been seen before.
76 // The algorithm MUST compute all k hashes and check k bits.
77 println!("\n[Lookup Performance - Worst Case (Seen Items)]");
78 let start_worst = Instant::now();
79 for item in &dataset {
80 // Assign the result to a volatile variable to prevent compiler optimization
81 let _ = std::hint::black_box(bf.contains(item));
82 }
83 let duration_worst = start_worst.elapsed();
84 print_timing(duration_worst, n);
85
86 // --- Metric 4: Average Case Lookup (Unseen Items) ---
87 // In a well-tuned Bloom Filter (50% bits set), an unseen item
88 // often fails on the 1st or 2nd bit check.
89 println!("\n[Lookup Performance - Average Case (Unseen Items)]");
90
91 // Generate new random items that are likely NOT in the set
92 let mut unseen_dataset = Vec::with_capacity(n);
93 for _ in 0..n {
94 unseen_dataset.push(rng.next_u64());
95 }
96
97 let start_avg = Instant::now();
98 for item in &unseen_dataset {
99 let _ = std::hint::black_box(bf.contains(item));
100 }
101 let duration_avg = start_avg.elapsed();
102 print_timing(duration_avg, n);
103
104 // --- Metric 5: Best Case Lookup (Empty Filter) ---
105 // The best case is checking against an empty filter; fails on the 1st bit.
106 println!("\n[Lookup Performance - Best Case (Empty Filter)]");
107 let empty_bf: BloomFilter<u64> = BloomFilter::new(n, fp_rate);
108
109 let start_best = Instant::now();
110 for item in &dataset {
111 let _ = std::hint::black_box(empty_bf.contains(item));
112 }
113 let duration_best = start_best.elapsed();
114 print_timing(duration_best, n);
115
116 println!("\n=========================================================\n");
117}Sourcepub fn hash_count(&self) -> u32
pub fn hash_count(&self) -> u32
Returns the number of hash functions (k) being used.
Examples found in repository?
3fn main() {
4 // Configuration
5 let expected_elements = 100_000;
6
7 // You can initialize with a false positive rate
8 let fp_rate = 0.01;
9 let mut filter = BloomFilter::new(expected_elements, fp_rate);
10
11 // OR initialize using a specific hash count (commented out example)
12 // let hashes = 7u32;
13 // let mut filter = BloomFilter::new(expected_elements, hashes);
14
15 println!("Initializing Bloom Filter...");
16 println!("Expected elements: {}", expected_elements);
17 println!("Target False Positive Rate: {}", fp_rate);
18 println!("Actual Hash Count (k): {}", filter.hash_count());
19
20 // Insert data
21 println!("Inserting values 0 to {}...", expected_elements);
22 for i in 0..expected_elements {
23 filter.insert(&i);
24 }
25
26 // Check true positives
27 println!("Checking 10 known values...");
28 let mut present_count = 0;
29 for i in 0..10 {
30 if filter.contains(&i) {
31 present_count += 1;
32 }
33 }
34 println!("Found {}/10 known values (Should be 10)", present_count);
35
36 // Check false positives
37 // We check numbers outside the inserted range.
38 let check_range_start = expected_elements;
39 let check_range_end = expected_elements + 10_000;
40 println!(
41 "Checking range {} to {} for false positives...",
42 check_range_start, check_range_end
43 );
44
45 let mut fp_count = 0;
46 for i in check_range_start..check_range_end {
47 if filter.contains(&i) {
48 fp_count += 1;
49 }
50 }
51
52 let actual_fp_rate = fp_count as f64 / 10_000.0;
53 println!("False Positives found: {}", fp_count);
54 println!(
55 "Actual FP Rate: {:.4} (Target: {})",
56 actual_fp_rate, actual_fp_rate
57 );
58}More examples
33fn run_benchmark(n: usize, fp_rate: f64) {
34 // --- Setup ---
35 let mut bf = BloomFilter::new(n, fp_rate);
36 let mut rng = Random::new(12345);
37
38 println!("\n---------- Bloom Filter Performance Benchmark -----------\n");
39 println!("Items: {}", n);
40 println!("Target FP Rate: {}", fp_rate);
41 println!("Hash Count: {}", bf.hash_count());
42 println!("\n---------------------------------------------------------\n");
43
44 // Generate data
45 let mut dataset = Vec::with_capacity(n);
46 for _ in 0..n {
47 dataset.push(rng.next_u64());
48 }
49
50 // --- Metric 1: Memory Usage ---
51 let ki = 1024.0;
52 let memory_bytes = bf.memory_usage_bytes();
53 let memory_mb = memory_bytes as f64 / ki / ki;
54 println!("[Memory Usage]");
55 println!(
56 "{:<22}{:.2} MB ({} bytes)",
57 "Bit Vector Size", memory_mb, memory_bytes
58 );
59 println!(
60 "{:<22}{:.2} bits",
61 "Bits per item",
62 (memory_bytes * 8) as f64 / n as f64
63 );
64
65 // --- Metric 2: Insert Performance ---
66 println!("\n[Insertion Performance]");
67 let start_insert = Instant::now();
68 for item in &dataset {
69 bf.insert(item);
70 }
71 let duration_insert = start_insert.elapsed();
72 print_timing(duration_insert, n);
73
74 // --- Metric 3: Worst Case Lookup (Seen Items) ---
75 // The worst case for Bloom Filter is when the item has been seen before.
76 // The algorithm MUST compute all k hashes and check k bits.
77 println!("\n[Lookup Performance - Worst Case (Seen Items)]");
78 let start_worst = Instant::now();
79 for item in &dataset {
80 // Assign the result to a volatile variable to prevent compiler optimization
81 let _ = std::hint::black_box(bf.contains(item));
82 }
83 let duration_worst = start_worst.elapsed();
84 print_timing(duration_worst, n);
85
86 // --- Metric 4: Average Case Lookup (Unseen Items) ---
87 // In a well-tuned Bloom Filter (50% bits set), an unseen item
88 // often fails on the 1st or 2nd bit check.
89 println!("\n[Lookup Performance - Average Case (Unseen Items)]");
90
91 // Generate new random items that are likely NOT in the set
92 let mut unseen_dataset = Vec::with_capacity(n);
93 for _ in 0..n {
94 unseen_dataset.push(rng.next_u64());
95 }
96
97 let start_avg = Instant::now();
98 for item in &unseen_dataset {
99 let _ = std::hint::black_box(bf.contains(item));
100 }
101 let duration_avg = start_avg.elapsed();
102 print_timing(duration_avg, n);
103
104 // --- Metric 5: Best Case Lookup (Empty Filter) ---
105 // The best case is checking against an empty filter; fails on the 1st bit.
106 println!("\n[Lookup Performance - Best Case (Empty Filter)]");
107 let empty_bf: BloomFilter<u64> = BloomFilter::new(n, fp_rate);
108
109 let start_best = Instant::now();
110 for item in &dataset {
111 let _ = std::hint::black_box(empty_bf.contains(item));
112 }
113 let duration_best = start_best.elapsed();
114 print_timing(duration_best, n);
115
116 println!("\n=========================================================\n");
117}Trait Implementations§
Source§impl<T: Clone + ?Sized> Clone for BloomFilter<T>
impl<T: Clone + ?Sized> Clone for BloomFilter<T>
Source§fn clone(&self) -> BloomFilter<T>
fn clone(&self) -> BloomFilter<T>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more