Skip to content

Commit 2ac4e2e

Browse files
Merge #116
116: make most structures implement `Send` r=crepererum a=crepererum Co-authored-by: Marco Neumann <marco@crepererum.net>
2 parents b64bb6d + eeaa398 commit 2ac4e2e

File tree

7 files changed

+144
-7
lines changed

7 files changed

+144
-7
lines changed

src/countminsketch.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ use crate::hash_utils::HashIterBuilder;
3333
/// assert_eq!(cms.query_point(&"another super long string"), 0);
3434
/// ```
3535
///
36+
/// Note that the sketch is specific to `T`, so the following will not compile:
37+
///
38+
/// ```compile_fail
39+
/// use pdatastructs::countminsketch::CountMinSketch;
40+
///
41+
/// // set up filter
42+
/// let epsilon = 0.1; // error threshold
43+
/// let delta = 0.2; // epsilon is hit in (1 - 0.2) * 100% = 80%
44+
/// let mut cms1 = CountMinSketch::<u8, _>::with_point_query_properties(epsilon, delta);
45+
/// let cms2 = CountMinSketch::<i8, _>::with_point_query_properties(epsilon, delta);
46+
///
47+
/// cms1.merge(&cms2);
48+
/// ```
49+
///
3650
/// # Applications
3751
/// - when a lot of data is streamed in an approximative counter is good enough, e.g. for access
3852
/// counts in network filters
@@ -119,7 +133,7 @@ where
119133
w: usize,
120134
d: usize,
121135
builder: HashIterBuilder<B>,
122-
phantom: PhantomData<T>,
136+
phantom: PhantomData<fn() -> T>,
123137
}
124138

125139
impl<T, C> CountMinSketch<T, C>
@@ -307,7 +321,10 @@ where
307321
#[cfg(test)]
308322
mod tests {
309323
use super::CountMinSketch;
310-
use crate::hash_utils::BuildHasherSeeded;
324+
use crate::{
325+
hash_utils::BuildHasherSeeded,
326+
test_util::{assert_send, NotSend},
327+
};
311328

312329
#[test]
313330
fn getter() {
@@ -495,4 +512,10 @@ mod tests {
495512
assert_eq!(cms.query_point(&1), 2);
496513
assert_eq!(cms.query_point(&2), 0);
497514
}
515+
516+
#[test]
517+
fn send() {
518+
let cms = CountMinSketch::<NotSend>::with_params(10, 10);
519+
assert_send(&cms);
520+
}
498521
}

src/filters/bloomfilter.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,20 @@ use crate::hash_utils::HashIterBuilder;
3232
/// assert!(!filter.query(&"another super long string"));
3333
/// ```
3434
///
35+
/// Note that the filter is specific to `T`, so the following will not compile:
36+
///
37+
/// ```compile_fail
38+
/// use pdatastructs::filters::Filter;
39+
/// use pdatastructs::filters::bloomfilter::BloomFilter;
40+
///
41+
/// let false_positive_rate = 0.02; // = 2%
42+
/// let expected_elements = 1000;
43+
/// let mut filter1 = BloomFilter::<u8>::with_properties(expected_elements, false_positive_rate);
44+
/// let filter2 = BloomFilter::<i8>::with_properties(expected_elements, false_positive_rate);
45+
///
46+
/// filter1.union(&filter2);
47+
/// ```
48+
///
3549
/// # Applications
3650
/// - when a lot of data should be added to the set and a moderate false positive rate is
3751
/// acceptable, was used for spell checking
@@ -149,7 +163,7 @@ where
149163
bs: FixedBitSet,
150164
k: usize,
151165
builder: HashIterBuilder<B>,
152-
phantom: PhantomData<T>,
166+
phantom: PhantomData<fn() -> T>,
153167
}
154168

155169
impl<T> BloomFilter<T>
@@ -326,6 +340,7 @@ mod tests {
326340

327341
use crate::filters::Filter;
328342
use crate::hash_utils::BuildHasherSeeded;
343+
use crate::test_util::{assert_send, NotSend};
329344

330345
#[test]
331346
fn getter() {
@@ -508,4 +523,10 @@ mod tests {
508523
assert!(bf.query("test1"));
509524
assert!(!bf.query("test2"));
510525
}
526+
527+
#[test]
528+
fn send() {
529+
let bf = BloomFilter::<NotSend>::with_params(100, 2);
530+
assert_send(&bf);
531+
}
511532
}

src/filters/cuckoofilter.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,24 @@ pub struct CuckooFilterFull;
4242
/// assert!(!filter.query(&"another super long string"));
4343
/// ```
4444
///
45+
/// Note that the filter is specific to `T`, so the following will not compile:
46+
///
47+
/// ```compile_fail
48+
/// use pdatastructs::filters::Filter;
49+
/// use pdatastructs::filters::cuckoofilter::CuckooFilter;
50+
/// use pdatastructs::rand::SeedableRng;
51+
/// use rand_chacha::ChaChaRng;
52+
///
53+
/// // set up filter
54+
/// let false_positive_rate = 0.02; // = 2%
55+
/// let expected_elements = 1000;
56+
/// let rng = ChaChaRng::from_seed([0; 32]);
57+
/// let mut filter1 = CuckooFilter::<u8, _>::with_properties_8(false_positive_rate, expected_elements, rng);
58+
/// let filter2 = CuckooFilter::<i8, _>::with_properties_8(false_positive_rate, expected_elements, rng);
59+
///
60+
/// filter1.union(&filter2);
61+
/// ```
62+
///
4563
/// # Applications
4664
/// Same as BloomFilter.
4765
///
@@ -147,7 +165,7 @@ where
147165
n_buckets: usize,
148166
l_fingerprint: usize,
149167
rng: R,
150-
phantom: PhantomData<T>,
168+
phantom: PhantomData<fn() -> T>,
151169
}
152170

153171
impl<T, R> CuckooFilter<T, R>
@@ -581,7 +599,11 @@ where
581599
#[cfg(test)]
582600
mod tests {
583601
use super::CuckooFilter;
584-
use crate::{filters::Filter, hash_utils::BuildHasherSeeded};
602+
use crate::{
603+
filters::Filter,
604+
hash_utils::BuildHasherSeeded,
605+
test_util::{assert_send, NotSend},
606+
};
585607
use rand::SeedableRng;
586608
use rand_chacha::ChaChaRng;
587609

@@ -921,4 +943,10 @@ mod tests {
921943
assert!(cf.query("test1"));
922944
assert!(!cf.query("test2"));
923945
}
946+
947+
#[test]
948+
fn send() {
949+
let cf = CuckooFilter::<NotSend, _>::with_params(ChaChaRng::from_seed([0; 32]), 2, 16, 8);
950+
assert_send(&cf);
951+
}
924952
}

src/filters/quotientfilter.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,21 @@ impl ScanResult {
6161
/// assert!(!filter.query(&"another super long string"));
6262
/// ```
6363
///
64+
/// Note that the filter is specific to `T`, so the following will not compile:
65+
///
66+
/// ```compile_fail
67+
/// use pdatastructs::filters::Filter;
68+
/// use pdatastructs::filters::quotientfilter::QuotientFilter;
69+
///
70+
/// // set up filter
71+
/// let bits_quotient = 16;
72+
/// let bits_remainder = 5;
73+
/// let mut filter1 = QuotientFilter::<u8>::with_params(bits_quotient, bits_remainder);
74+
/// let filter2 = QuotientFilter::<i8>::with_params(bits_quotient, bits_remainder);
75+
///
76+
/// filter1.union(&filter2);
77+
/// ```
78+
///
6479
/// # Applications
6580
/// - when a lot of data should be added to the set and a moderate false positive rate is
6681
/// acceptable, was used for spell checking
@@ -250,7 +265,7 @@ where
250265
bits_quotient: usize,
251266
buildhasher: B,
252267
n_elements: usize,
253-
phantom: PhantomData<T>,
268+
phantom: PhantomData<fn() -> T>,
254269
}
255270

256271
impl<T> QuotientFilter<T>
@@ -615,6 +630,7 @@ mod tests {
615630
use super::QuotientFilter;
616631
use crate::filters::Filter;
617632
use crate::hash_utils::BuildHasherSeeded;
633+
use crate::test_util::{assert_send, NotSend};
618634

619635
#[test]
620636
#[should_panic(expected = "bits_quotient (0) must be greater than 0")]
@@ -828,4 +844,10 @@ mod tests {
828844
assert!(qf.query("test1"));
829845
assert!(!qf.query("test2"));
830846
}
847+
848+
#[test]
849+
fn send() {
850+
let qf = QuotientFilter::<NotSend>::with_params(3, 16);
851+
assert_send(&qf);
852+
}
831853
}

src/hyperloglog.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ use crate::hyperloglog_data::{
2929
/// assert_eq!(hll.count(), 2);
3030
/// ```
3131
///
32+
/// Note that the HyperLogLog is specific to `T`, so the following will not compile:
33+
///
34+
/// ```compile_fail
35+
/// use pdatastructs::hyperloglog::HyperLogLog;
36+
///
37+
/// // set up filter
38+
/// let address_bits = 4; // so we store 2^4 = 16 registers in total
39+
/// let mut hll1 = HyperLogLog::<u8>::new(address_bits);
40+
/// let hll2 = HyperLogLog::<i8>::new(address_bits);
41+
///
42+
/// hll1.merge(&hll2);
43+
/// ```
44+
///
3245
/// # Applications
3346
/// - an approximative `COUNT(DISTINCT x)` in SQL
3447
/// - count distinct elements in a data stream
@@ -75,7 +88,7 @@ where
7588
registers: Vec<u8>,
7689
b: usize,
7790
buildhasher: B,
78-
phantom: PhantomData<T>,
91+
phantom: PhantomData<fn() -> T>,
7992
}
8093

8194
impl<T> HyperLogLog<T>
@@ -351,6 +364,7 @@ mod tests {
351364
use super::HyperLogLog;
352365
use crate::hash_utils::BuildHasherSeeded;
353366
use crate::hyperloglog_data::{RAW_ESTIMATE_DATA_OFFSET, RAW_ESTIMATE_DATA_VEC};
367+
use crate::test_util::{assert_send, NotSend};
354368

355369
#[test]
356370
#[should_panic(expected = "b (3) must be larger or equal than 4 and smaller or equal than 18")]
@@ -691,4 +705,10 @@ mod tests {
691705
(Some(4), Some(4))
692706
);
693707
}
708+
709+
#[test]
710+
fn send() {
711+
let hll: HyperLogLog<NotSend> = HyperLogLog::new(4);
712+
assert_send(&hll);
713+
}
694714
}

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ mod hyperloglog_data;
3131
pub mod reservoirsampling;
3232
pub mod tdigest;
3333
pub mod topk;
34+
35+
#[cfg(test)]
36+
mod test_util;

src/test_util.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use std::hash::Hash;
2+
3+
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
4+
pub(crate) struct NotSend {
5+
_marker: *const u8,
6+
}
7+
8+
impl Default for NotSend {
9+
fn default() -> Self {
10+
Self {
11+
_marker: std::ptr::null(),
12+
}
13+
}
14+
}
15+
16+
pub(crate) fn assert_send<T>(_: &T)
17+
where
18+
T: Send,
19+
{
20+
}

0 commit comments

Comments
 (0)