Skip to content

Commit 72a97a6

Browse files
authored
v0.5.8 - Updates (#146)
1 parent 119fe7d commit 72a97a6

16 files changed

Lines changed: 138 additions & 162 deletions

File tree

Cargo.toml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "concread"
3-
version = "0.5.7"
3+
version = "0.5.8"
44
authors = ["William Brown <william@blackhats.net.au>"]
55
edition = "2021"
66
description = "Concurrently Readable Data-Structures for Rust"
@@ -45,32 +45,32 @@ arcache-is-hashtrie = ["arcache"]
4545
simd_support = []
4646

4747
[dependencies]
48-
ahash = { version = "0.8", optional = true }
49-
foldhash = { version = "0.1.5", optional = true }
48+
ahash = { version = "0.8.12", optional = true }
49+
foldhash = { version = "0.2.0", optional = true }
5050
crossbeam-utils = { version = "0.8.21", optional = true }
51-
crossbeam-epoch = { version = "0.9.11", optional = true }
51+
crossbeam-epoch = { version = "0.9.18", optional = true }
5252
crossbeam-queue = { version = "0.3.12", optional = true }
5353
dhat = { version = "0.3.3", optional = true }
54-
lru = { version = "0.13", optional = true }
54+
lru = { version = "0.16.3", optional = true }
5555
serde = { version = "1.0", optional = true }
56-
smallvec = { version = "1.14", optional = true }
56+
smallvec = { version = "1.15.1", optional = true }
5757
sptr = "0.3"
58-
tokio = { version = "1", features = ["sync"], optional = true }
59-
tracing = "0.1"
58+
tokio = { version = "1.49.0", features = ["sync"], optional = true }
59+
tracing = "0.1.44"
6060

6161
[dev-dependencies]
62-
criterion = { version = "0.5", features = ["html_reports"] }
63-
rand = "0.9"
64-
tracing-subscriber = { version = "0.3", features = [
62+
criterion = { version = "0.8.1", features = ["html_reports"] }
63+
rand = "0.9.2"
64+
tracing-subscriber = { version = "0.3.22", features = [
6565
"env-filter",
6666
"std",
6767
"fmt",
6868
] }
69-
uuid = "1"
69+
uuid = ">=1.19.0"
7070
function_name = "0.3"
71-
serde_json = "1"
72-
tokio = { version = "1", features = ["rt", "macros"] }
73-
proptest = "1.0.0"
71+
serde_json = ">=1.0.149"
72+
tokio = { version = "1.49.0", features = ["rt", "macros"] }
73+
proptest = "1.9.0"
7474

7575
[[bench]]
7676
name = "hashmap_benchmark"

benches/arccache.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ where
5555
match self {
5656
AccessPattern::Random(min, max) => {
5757
let mut rng = thread_rng();
58-
rng.gen_range(min.clone()..max.clone())
58+
rng.gen_range(*min..*max)
5959
}
6060
}
6161
}
@@ -209,10 +209,10 @@ where
209209
.into_iter()
210210
.map(|cache| {
211211
// Build the threads.
212-
let back_set = backing_set.clone();
213-
let back_set_delay = backing_set_delay.clone();
214212
let pat = access_pattern.clone();
215-
thread::spawn(move || tlocal_multi_thread_worker(cache, back_set, back_set_delay, pat))
213+
thread::spawn(move || {
214+
tlocal_multi_thread_worker(cache, backing_set, backing_set_delay, pat)
215+
})
216216
})
217217
.collect();
218218

benches/hashmap_benchmark.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ extern crate criterion;
1919
extern crate rand;
2020

2121
use concread::hashmap::*;
22-
use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion};
23-
use rand::{thread_rng, Rng};
22+
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
23+
use rand::{rng, Rng};
24+
use std::hint::black_box;
2425

2526
// ranges of counts for different benchmarks (MINs are inclusive, MAXes exclusive):
2627
const INSERT_COUNT_MIN: usize = 120;
@@ -168,7 +169,7 @@ criterion_main!(insert, remove, search);
168169
fn insert_vec<V: Clone + Sync + Send + 'static>(
169170
map: &mut HashMap<u32, V>,
170171
list: Vec<(u32, V)>,
171-
) -> HashMapWriteTxn<u32, V> {
172+
) -> HashMapWriteTxn<'_, u32, V> {
172173
let mut write_txn = map.write();
173174
for (key, val) in list.into_iter() {
174175
write_txn.insert(key, val);
@@ -178,7 +179,7 @@ fn insert_vec<V: Clone + Sync + Send + 'static>(
178179

179180
fn remove_vec<'a, V: Clone + Sync + Send + 'static>(
180181
map: &'a mut HashMap<u32, V>,
181-
list: &Vec<u32>,
182+
list: &[u32],
182183
) -> HashMapWriteTxn<'a, u32, V> {
183184
let mut write_txn = map.write();
184185
for i in list.iter() {
@@ -187,7 +188,7 @@ fn remove_vec<'a, V: Clone + Sync + Send + 'static>(
187188
write_txn
188189
}
189190

190-
fn search_vec<V: Clone + Sync + Send + 'static>(map: &HashMap<u32, V>, list: &Vec<u32>) {
191+
fn search_vec<V: Clone + Sync + Send + 'static>(map: &HashMap<u32, V>, list: &[u32]) {
191192
let read_txn = map.read();
192193
for i in list.iter() {
193194
read_txn.get(black_box(i));
@@ -242,23 +243,23 @@ struct Struct {
242243
}
243244

244245
fn prepare_insert<V: Clone + Sync + Send + 'static>(value: V) -> (HashMap<u32, V>, Vec<(u32, V)>) {
245-
let mut rng = thread_rng();
246-
let count = rng.gen_range(INSERT_COUNT_MIN..INSERT_COUNT_MAX);
246+
let mut rng = rng();
247+
let count = rng.random_range(INSERT_COUNT_MIN..INSERT_COUNT_MAX);
247248
let mut list = Vec::with_capacity(count);
248249
for _ in 0..count {
249250
list.push((
250-
rng.gen_range(0..INSERT_COUNT_MAX << 8) as u32,
251-
value.clone(),
251+
rng.random_range(0..INSERT_COUNT_MAX << 8) as u32,
252+
value.to_owned(),
252253
));
253254
}
254255
(HashMap::new(), list)
255256
}
256257

257258
/// Prepares a remove benchmark with values in the HashMap being clones of the 'value' parameter
258259
fn prepare_remove<V: Clone + Sync + Send + 'static>(value: V) -> (HashMap<u32, V>, Vec<u32>) {
259-
let mut rng = thread_rng();
260-
let insert_count = rng.gen_range(INSERT_COUNT_FOR_REMOVE_MIN..INSERT_COUNT_FOR_REMOVE_MAX);
261-
let remove_count = rng.gen_range(REMOVE_COUNT_MIN..REMOVE_COUNT_MAX);
260+
let mut rng = rng();
261+
let insert_count = rng.random_range(INSERT_COUNT_FOR_REMOVE_MIN..INSERT_COUNT_FOR_REMOVE_MAX);
262+
let remove_count = rng.random_range(REMOVE_COUNT_MIN..REMOVE_COUNT_MAX);
262263
let map = HashMap::new();
263264
let mut write_txn = map.write();
264265
for i in random_order(insert_count, insert_count).iter() {
@@ -271,10 +272,10 @@ fn prepare_remove<V: Clone + Sync + Send + 'static>(value: V) -> (HashMap<u32, V
271272
}
272273

273274
fn prepare_search<V: Clone + Sync + Send + 'static>(value: V) -> (HashMap<u32, V>, Vec<u32>) {
274-
let mut rng = thread_rng();
275-
let insert_count = rng.gen_range(INSERT_COUNT_FOR_SEARCH_MIN..INSERT_COUNT_FOR_SEARCH_MAX);
275+
let mut rng = rng();
276+
let insert_count = rng.random_range(INSERT_COUNT_FOR_SEARCH_MIN..INSERT_COUNT_FOR_SEARCH_MAX);
276277
let search_limit = insert_count * SEARCH_SIZE_NUMERATOR / SEARCH_SIZE_DENOMINATOR;
277-
let search_count = rng.gen_range(SEARCH_COUNT_MIN..SEARCH_COUNT_MAX);
278+
let search_count = rng.random_range(SEARCH_COUNT_MIN..SEARCH_COUNT_MAX);
278279

279280
// Create a HashMap with elements 0 through insert_count(-1)
280281
let map = HashMap::new();
@@ -287,28 +288,28 @@ fn prepare_search<V: Clone + Sync + Send + 'static>(value: V) -> (HashMap<u32, V
287288
// Choose 'search_count' numbers from [0,search_limit) randomly to be searched in the created map.
288289
let mut list = Vec::with_capacity(search_count);
289290
for _ in 0..search_count {
290-
list.push(rng.gen_range(0..search_limit as u32));
291+
list.push(rng.random_range(0..search_limit as u32));
291292
}
292293
(map, list)
293294
}
294295

295296
/// Returns a Vec of n elements from the range [0,up_to) in random order without repetition
296297
fn random_order(up_to: usize, n: usize) -> Vec<u32> {
297-
let mut rng = thread_rng();
298+
let mut rng = rng();
298299
let mut order = Vec::with_capacity(n);
299300
let mut generated = vec![false; up_to];
300301
let mut remaining = n;
301302
let mut remaining_elems = up_to;
302303
while remaining > 0 {
303-
let mut r = rng.gen_range(0..remaining_elems);
304+
let mut r = rng.random_range(0..remaining_elems);
304305
// find the r-th yet nongenerated number:
305-
for i in 0..up_to {
306-
if generated[i] {
306+
for (i, value) in generated.iter_mut().enumerate().take(up_to) {
307+
if *value {
307308
continue;
308309
}
309310
if r == 0 {
310311
order.push(i as u32);
311-
generated[i] = true;
312+
*value = true;
312313
break;
313314
}
314315
r -= 1;

src/arcache/mod.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,7 @@ impl<
10941094
// * everything hit must be in main cache now, so bring these
10951095
// all to the relevant item heads.
10961096
// * Why do this last? Because the write is the "latest" we want all the fresh
1097-
// written items in the cache over the "read" hits, it gives us some aprox
1097+
// written items in the cache over the "read" hits, it gives us some appximation
10981098
// of time ordering, but not perfect.
10991099

11001100
// Find the item in the cache.
@@ -1261,7 +1261,7 @@ impl<
12611261
//
12621262
// keep removing from rec until == p OR delta == 0, and if delta remains, then remove from freq.
12631263
//
1264-
// Remember P is "the maximum size of recent" or "presure on recent". If P is max then
1264+
// Remember P is "the maximum size of recent" or "pressure on recent". If P is max then
12651265
// we are pressuring churning on recent but not freq, so evict in freq.
12661266
//
12671267
// If P is toward 0 that means all our pressure is in frequent and we evicted things we
@@ -1938,10 +1938,9 @@ impl<
19381938
}
19391939

19401940
#[cfg(test)]
1941-
pub(crate) fn peek_cache<Q: ?Sized>(&self, k: &Q) -> CacheState
1941+
pub(crate) fn peek_cache<Q: ?Sized + Hash + Eq + Ord>(&self, k: &Q) -> CacheState
19421942
where
19431943
K: Borrow<Q>,
1944-
Q: Hash + Eq + Ord,
19451944
{
19461945
if let Some(v) = self.cache.get(k) {
19471946
(*v).to_state()
@@ -3154,7 +3153,6 @@ mod tests {
31543153
}
31553154

31563155
#[allow(dead_code)]
3157-
31583156
pub static RUNNING: AtomicBool = AtomicBool::new(false);
31593157

31603158
#[cfg(test)]
@@ -3192,7 +3190,6 @@ mod tests {
31923190
RUNNING.store(true, Ordering::Relaxed);
31933191

31943192
let handles: Vec<_> = (0..thread_count)
3195-
.into_iter()
31963193
.map(|_| {
31973194
// Build the threads.
31983195
let cache = arc.clone();

src/arcache/stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::fmt::Debug;
33
/// Write statistics for ARCache
44
pub trait ARCacheWriteStat<K> {
55
// RW phase trackers
6-
/// Record that a cache clear event occured.
6+
/// Record that a cache clear event occurred.
77
///
88
/// Phase - write transaction open
99
fn cache_clear(&mut self) {}

src/hashmap/mod.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ mod tests {
264264
assert!(!snap.contains_key(&20));
265265
assert_eq!(snap.len(), 2);
266266
assert!(!snap.is_empty());
267-
assert!(snap.iter().find(|(_k, v)| **v == 10).is_some());
267+
assert!(snap.iter().any(|(_k, v)| *v == 10));
268268
assert_eq!(snap.values().count(), 2);
269269
assert_eq!(snap.keys().count(), 2);
270270
}
@@ -311,17 +311,17 @@ mod tests {
311311
fn test_hashmap_keys() {
312312
let hmap: HashMap<usize, usize> = vec![(10, 10), (15, 15), (20, 20)].into_iter().collect();
313313
let hmap_read = hmap.read();
314-
assert!(hmap_read.keys().find(|&&x| x == 10).is_some());
314+
assert!(hmap_read.keys().any(|&x| x == 10));
315315
let hmap_write = hmap.write();
316-
assert!(hmap_write.keys().find(|&&x| x == 10).is_some());
316+
assert!(hmap_write.keys().any(|&x| x == 10));
317317
}
318318
#[test]
319319
fn test_hashmap_values() {
320320
let hmap: HashMap<usize, usize> = vec![(10, 11), (15, 15), (20, 20)].into_iter().collect();
321321
let hmap_read = hmap.read();
322-
assert!(hmap_read.values().find(|&&x| x == 11).is_some());
322+
assert!(hmap_read.values().any(|&x| x == 11));
323323
let hmap_write = hmap.write();
324-
assert!(hmap_write.values().find(|&&x| x == 11).is_some());
324+
assert!(hmap_write.values().any(|&x| x == 11));
325325
}
326326

327327
#[test]
@@ -332,11 +332,11 @@ mod tests {
332332
assert!(!hmap_write_snapshot.is_empty());
333333
assert_eq!(hmap_write_snapshot.len(), 3);
334334
assert!(hmap_write_snapshot.contains_key(&10));
335-
assert!(hmap_write_snapshot.values().find(|&&x| x == 11).is_some());
336-
assert!(hmap_write_snapshot.values().find(|&&x| x == 10).is_none());
337-
assert!(hmap_write_snapshot.keys().find(|&&x| x == 10).is_some());
338-
assert!(hmap_write_snapshot.keys().find(|&&x| x == 11).is_none());
339-
assert!(hmap_write_snapshot.keys().find(|&&x| x == 10).is_some());
335+
assert!(hmap_write_snapshot.values().any(|&x| x == 11));
336+
assert!(hmap_write_snapshot.values().all(|&x| x != 10));
337+
assert!(hmap_write_snapshot.keys().any(|&x| x == 10));
338+
assert!(hmap_write_snapshot.keys().all(|&x| x != 11));
339+
assert!(hmap_write_snapshot.keys().any(|&x| x == 10));
340340
assert!(hmap_write_snapshot.iter().count() == 3);
341341
}
342342
}

src/hashtrie/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ mod tests {
224224
assert!(hmap_w1.is_empty());
225225
hmap_w1.insert(10, 10);
226226
// just coverage things
227-
hmap_w1.extend([(15, 15)].into_iter());
227+
hmap_w1.extend([(15, 15)]);
228228
assert!(!hmap_w1.is_empty());
229229
hmap_w1.commit();
230230

@@ -294,9 +294,9 @@ mod tests {
294294
fn test_hashtrie_keys() {
295295
let hmap: HashTrie<usize, usize> = vec![(10, 10), (15, 15), (20, 20)].into_iter().collect();
296296
let hmap_read = hmap.read();
297-
assert!(hmap_read.keys().find(|&&x| x == 10).is_some());
297+
assert!(hmap_read.keys().any(|&x| x == 10));
298298
let hmap_write = hmap.write();
299-
assert!(hmap_write.keys().find(|&&x| x == 10).is_some());
299+
assert!(hmap_write.keys().any(|&x| x == 10));
300300
}
301301

302302
#[test]

src/internals/bptree/cursor.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,7 @@ mod tests {
13001300
}
13011301

13021302
fn create_leaf_node_full(vbase: usize) -> *mut Node<usize, usize> {
1303-
assert!(vbase % 10 == 0);
1303+
assert!(vbase.is_multiple_of(10));
13041304
let node = Node::new_leaf(1);
13051305
{
13061306
let nmut = leaf_ref!(node, usize, usize);
@@ -2296,8 +2296,8 @@ mod tests {
22962296
#[test]
22972297
fn test_bptree2_cursor_remove_15() {
22982298
// Test leaf borrow right.
2299-
let lnode = create_leaf_node(10) as *mut Node<usize, usize>;
2300-
let rnode = create_leaf_node_full(20) as *mut Node<usize, usize>;
2299+
let lnode = create_leaf_node(10);
2300+
let rnode = create_leaf_node_full(20);
23012301
let root = Node::new_branch(0, lnode, rnode);
23022302
let sb = SuperBlock::new_test(1, root as *mut Node<usize, usize>);
23032303
let mut wcurs = sb.create_writer();
@@ -2647,7 +2647,6 @@ mod tests {
26472647
#[test]
26482648
fn test_bptree2_cursor_split_off_lt_clone_stress() {
26492649
// Can't proceed as the "fake" tree we make is invalid.
2650-
debug_assert!(L_CAPACITY >= 4);
26512650
let outer: [usize; 4] = [0, 100, 200, 300];
26522651
let inner: [usize; 4] = [0, 10, 20, 30];
26532652
for i in outer.iter() {
@@ -2663,7 +2662,6 @@ mod tests {
26632662
#[cfg(not(feature = "skinny"))]
26642663
#[test]
26652664
fn test_bptree2_cursor_split_off_lt_stress() {
2666-
debug_assert!(L_CAPACITY >= 4);
26672665
let outer: [usize; 4] = [0, 100, 200, 300];
26682666
let inner: [usize; 4] = [0, 10, 20, 30];
26692667
for i in outer.iter() {

src/internals/bptree/iter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ mod tests {
703703
use std::ops::Bound::*;
704704

705705
fn create_leaf_node_full(vbase: usize) -> *mut Node<usize, usize> {
706-
assert!(vbase % 10 == 0);
706+
assert!(vbase.is_multiple_of(10));
707707
let node = Node::new_leaf(0);
708708
{
709709
let nmut = leaf_ref!(node, usize, usize);

src/internals/bptree/mutiter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ mod tests {
8787
use crate::internals::lincowcell::LinCowCellCapable;
8888

8989
fn create_leaf_node_full(vbase: usize) -> *mut Node<usize, usize> {
90-
assert!(vbase % 10 == 0);
90+
assert!(vbase.is_multiple_of(10));
9191
let node = Node::new_leaf(0);
9292
{
9393
let nmut = leaf_ref!(node, usize, usize);
@@ -103,7 +103,7 @@ mod tests {
103103
fn test_bptree2_iter_mutrangeiter_1() {
104104
let node = create_leaf_node_full(10);
105105

106-
let sb = SuperBlock::new_test(1, node as *mut Node<usize, usize>);
106+
let sb = SuperBlock::new_test(1, node);
107107
let mut wcurs = sb.create_writer();
108108

109109
let bounds: (Bound<usize>, Bound<usize>) = (Unbounded, Unbounded);

0 commit comments

Comments
 (0)