BloomFilter

Struct BloomFilter 

Source
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 implement Hash.

Implementations§

Source§

impl<T: ?Sized + Hash> BloomFilter<T>

Source

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 a f64 (false positive rate) or u32 (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?
examples/simple.rs (line 9)
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
Hide additional examples
examples/benchmark.rs (line 35)
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}
Source

pub fn insert(&mut self, item: &T)

Inserts an item into the Bloom Filter.

Examples found in repository?
examples/simple.rs (line 23)
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
Hide additional examples
examples/benchmark.rs (line 69)
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}
Source

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?
examples/simple.rs (line 30)
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
Hide additional examples
examples/benchmark.rs (line 81)
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}
Source

pub fn clear(&mut self)

Clears all bits in the filter.

Source

pub fn memory_usage_bytes(&self) -> usize

Returns the approximate memory usage of the bit vector in bytes.

Examples found in repository?
examples/benchmark.rs (line 52)
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}
Source

pub fn hash_count(&self) -> u32

Returns the number of hash functions (k) being used.

Examples found in repository?
examples/simple.rs (line 18)
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
Hide additional examples
examples/benchmark.rs (line 41)
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>

Source§

fn clone(&self) -> BloomFilter<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + ?Sized> Debug for BloomFilter<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for BloomFilter<T>
where T: ?Sized,

§

impl<T> RefUnwindSafe for BloomFilter<T>
where T: RefUnwindSafe + ?Sized,

§

impl<T> Send for BloomFilter<T>
where T: Send + ?Sized,

§

impl<T> Sync for BloomFilter<T>
where T: Sync + ?Sized,

§

impl<T> Unpin for BloomFilter<T>
where T: Unpin + ?Sized,

§

impl<T> UnwindSafe for BloomFilter<T>
where T: UnwindSafe + ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.