From 2263792a3722bf580461e2b3f3843396bea73780 Mon Sep 17 00:00:00 2001 From: Xiangpeng Hao Date: Fri, 9 Aug 2024 16:29:17 +0800 Subject: [PATCH] streamline dependency --- .gitignore | 1 + Cargo.toml | 15 ++++---- src/base_node.rs | 12 +++--- src/key.rs | 30 +++++++-------- src/node_16.rs | 13 +++---- src/node_256.rs | 10 ++--- src/node_4.rs | 11 +++--- src/node_48.rs | 10 ++--- src/tests/scan.rs | 96 +++++++++++++++++++++++------------------------ src/tests/tree.rs | 24 ++++++------ src/tree.rs | 2 +- 11 files changed, 109 insertions(+), 115 deletions(-) diff --git a/.gitignore b/.gitignore index c640ca5..5cb8c46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target Cargo.lock .vscode +.idea diff --git a/Cargo.toml b/Cargo.toml index 8cf0105..177dbc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,18 +14,17 @@ license = "MIT" [dependencies] crossbeam-epoch = "0.9.18" rand = { version = "0.8.5", optional = true } -serde = { version = "1.0.196", features = ["derive"], optional = true } +serde = { version = "1.0.205", features = ["derive"], optional = true } [dev-dependencies] rand = "0.8.5" -shumai = "0.2.14" -serde = "1.0.196" -serde_json = "1.0.113" -flurry = "0.5.0" -mimalloc = { version = "0.1.39", default-features = false } +shumai = "0.2.15" +serde = "1.0.205" +serde_json = "1.0.122" +flurry = "0.5.1" +mimalloc = { version = "0.1.43", default-features = false } selfsimilar = "0.1.0" -static_assertions = "1.1.0" -shuttle = "0.7.0" +shuttle = "0.7.1" [[bench]] name = "basic" diff --git a/src/base_node.rs b/src/base_node.rs index f868869..27da0b8 100644 --- a/src/base_node.rs +++ b/src/base_node.rs @@ -104,13 +104,13 @@ pub(crate) struct NodeMeta { prefix: Prefix, } -#[cfg(all(test, not(feature = "shuttle")))] -mod const_assert { +#[cfg(not(feature = "shuttle"))] +mod layout_assertion { use super::*; - static_assertions::const_assert_eq!(std::mem::size_of::(), 16); - static_assertions::const_assert_eq!(std::mem::align_of::(), 4); - static_assertions::const_assert_eq!(std::mem::size_of::(), 24); - static_assertions::const_assert_eq!(std::mem::align_of::(), 8); + const _: () = assert!(std::mem::size_of::() == 16); + const _: () = assert!(std::mem::align_of::() == 4); + const _: () = assert!(std::mem::size_of::() == 24); + const _: () = assert!(std::mem::align_of::() == 8); } macro_rules! gen_method { diff --git a/src/key.rs b/src/key.rs index 854800f..b3e5350 100644 --- a/src/key.rs +++ b/src/key.rs @@ -10,17 +10,21 @@ pub trait RawKey: Eq + PartialEq + Default + PartialOrd + Ord { } #[derive(Clone)] -pub struct GeneralKey { +pub(crate) struct TestingKey { len: usize, stack_keys: [u8; STACK_KEY_LEN], } -impl RawKey for GeneralKey { +impl RawKey for TestingKey { fn len(&self) -> usize { self.len } - fn key_from(tid: usize) -> GeneralKey { + fn as_bytes(&self) -> &[u8] { + self.stack_keys[..self.len].as_ref() + } + + fn key_from(tid: usize) -> TestingKey { let mut stack_keys = [0; STACK_KEY_LEN]; let swapped = tid.swap_bytes(); @@ -29,17 +33,13 @@ impl RawKey for GeneralKey { stack_keys[i] = *v; } - GeneralKey { + TestingKey { len: std::mem::size_of::(), stack_keys, } } - - fn as_bytes(&self) -> &[u8] { - self.stack_keys[..self.len].as_ref() - } } -impl Ord for GeneralKey { +impl Ord for TestingKey { fn cmp(&self, other: &Self) -> std::cmp::Ordering { for i in 0..std::cmp::min(self.len(), other.len()) { if self.as_bytes()[i] > other.as_bytes()[i] { @@ -56,13 +56,13 @@ impl Ord for GeneralKey { } } -impl PartialOrd for GeneralKey { +impl PartialOrd for TestingKey { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl PartialEq for GeneralKey { +impl PartialEq for TestingKey { fn eq(&self, other: &Self) -> bool { if self.len != other.len { return false; @@ -76,17 +76,17 @@ impl PartialEq for GeneralKey { } } -impl Eq for GeneralKey {} +impl Eq for TestingKey {} -impl Default for GeneralKey { +impl Default for TestingKey { fn default() -> Self { Self::new() } } -impl GeneralKey { +impl TestingKey { fn new() -> Self { - GeneralKey { + TestingKey { len: 0, stack_keys: [0; STACK_KEY_LEN], } diff --git a/src/node_16.rs b/src/node_16.rs index e37ea4f..8c7c23b 100644 --- a/src/node_16.rs +++ b/src/node_16.rs @@ -4,19 +4,18 @@ use crate::{ }; #[repr(C)] -#[repr(align(8))] // Node 16 doesn't need to align to 64 bc it occupies 3 cachelines anyway +#[repr(align(8))] // Node 16 doesn't need to align to 64 bc it occupies 3 cache lines anyway pub(crate) struct Node16 { base: BaseNode, children: [NodePtr; 16], keys: [u8; 16], } -#[cfg(all(test, not(feature = "shuttle")))] -mod const_assert { - use super::*; - static_assertions::const_assert_eq!(std::mem::size_of::(), 168); - static_assertions::const_assert_eq!(std::mem::align_of::(), 8); -} +#[cfg(not(feature = "shuttle"))] +const _: () = assert!(std::mem::size_of::() == 168); + +#[cfg(not(feature = "shuttle"))] +const _: () = assert!(std::mem::align_of::() == 8); impl Node16 { fn flip_sign(val: u8) -> u8 { diff --git a/src/node_256.rs b/src/node_256.rs index 9c9bea0..ec97f41 100644 --- a/src/node_256.rs +++ b/src/node_256.rs @@ -11,12 +11,10 @@ pub(crate) struct Node256 { children: [NodePtr; 256], } -#[cfg(all(test, not(feature = "shuttle")))] -mod const_assert { - use super::*; - static_assertions::const_assert_eq!(std::mem::size_of::(), 2104); - static_assertions::const_assert_eq!(std::mem::align_of::(), 8); -} +#[cfg(not(feature = "shuttle"))] +const _: () = assert!(std::mem::size_of::() == 2104); +#[cfg(not(feature = "shuttle"))] +const _: () = assert!(std::mem::align_of::() == 8); impl Node256 { #[inline] diff --git a/src/node_4.rs b/src/node_4.rs index f5af369..b976417 100644 --- a/src/node_4.rs +++ b/src/node_4.rs @@ -11,12 +11,11 @@ pub(crate) struct Node4 { children: [NodePtr; 4], } -#[cfg(all(test, not(feature = "shuttle")))] -mod const_assert { - use super::*; - static_assertions::const_assert_eq!(std::mem::size_of::(), 64); - static_assertions::const_assert_eq!(std::mem::align_of::(), 64); -} +#[cfg(not(feature = "shuttle"))] +const _: () = assert!(std::mem::size_of::() == 64); + +#[cfg(not(feature = "shuttle"))] +const _: () = assert!(std::mem::align_of::() == 64); pub(crate) struct Node4Iter<'a> { start: u8, diff --git a/src/node_48.rs b/src/node_48.rs index 8fc2457..c10f27f 100644 --- a/src/node_48.rs +++ b/src/node_48.rs @@ -14,13 +14,11 @@ pub(crate) struct Node48 { next_empty: u8, children: [NodePtr; 48], } +#[cfg(not(feature = "shuttle"))] +const _: () = assert!(std::mem::size_of::() == 672); -#[cfg(all(test, not(feature = "shuttle")))] -mod const_assert { - use super::*; - static_assertions::const_assert_eq!(std::mem::size_of::(), 672); - static_assertions::const_assert_eq!(std::mem::align_of::(), 8); -} +#[cfg(not(feature = "shuttle"))] +const _: () = assert!(std::mem::align_of::() == 8); impl Node48 { pub(crate) fn init_empty(&mut self) { diff --git a/src/tests/scan.rs b/src/tests/scan.rs index 91c5fb8..5e96fb8 100644 --- a/src/tests/scan.rs +++ b/src/tests/scan.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use std::thread; -use crate::{key::GeneralKey, tree::RawTree, RawKey}; +use crate::{key::TestingKey, tree::RawTree, RawKey}; use rand::prelude::StdRng; use rand::seq::SliceRandom; @@ -14,13 +14,13 @@ fn small_scan() { let guard = crossbeam_epoch::pin(); for i in 0..key_cnt { - tree.insert(GeneralKey::key_from(i), i, &guard).unwrap(); + tree.insert(TestingKey::key_from(i), i, &guard).unwrap(); } let scan_cnt = 10; let low_v = 200; - let low_key = GeneralKey::key_from(low_v); - let high_key = GeneralKey::key_from(low_v + scan_cnt); + let low_key = TestingKey::key_from(low_v); + let high_key = TestingKey::key_from(low_v + scan_cnt); let mut results = [(0, 0); 20]; let scan_r = tree.range(&low_key, &high_key, &mut results, &guard); @@ -45,7 +45,7 @@ fn large_scan() { let guard = crossbeam_epoch::pin(); for v in key_space.iter() { - tree.insert(GeneralKey::key_from(*v), *v, &guard).unwrap(); + tree.insert(TestingKey::key_from(*v), *v, &guard).unwrap(); } let scan_counts = [3, 13, 65]; @@ -55,8 +55,8 @@ fn large_scan() { let scan_cnt = scan_counts.choose(&mut r).unwrap(); let low_key_v = r.gen_range(0..(key_cnt - scan_cnt)); - let low_key = GeneralKey::key_from(low_key_v); - let high_key = GeneralKey::key_from(low_key_v + scan_cnt); + let low_key = TestingKey::key_from(low_key_v); + let high_key = TestingKey::key_from(low_key_v + scan_cnt); let mut scan_results = vec![(0, 0); *scan_cnt]; @@ -73,8 +73,8 @@ fn large_scan() { let scan_cnt = scan_counts.choose(&mut r).unwrap(); let low_key_v = r.gen_range(key_cnt..2 * key_cnt); - let low_key = GeneralKey::key_from(low_key_v); - let high_key = GeneralKey::key_from(low_key_v + scan_cnt); + let low_key = TestingKey::key_from(low_key_v); + let high_key = TestingKey::key_from(low_key_v + scan_cnt); let mut scan_results = vec![(0, 0); *scan_cnt]; let r_found = tree.range(&low_key, &high_key, &mut scan_results, &guard); @@ -96,7 +96,7 @@ fn large_scan_small_buffer() { let guard = crossbeam_epoch::pin(); for v in key_space.iter() { - tree.insert(GeneralKey::key_from(*v), *v, &guard).unwrap(); + tree.insert(TestingKey::key_from(*v), *v, &guard).unwrap(); } let scan_counts = [3, 13, 65]; @@ -106,8 +106,8 @@ fn large_scan_small_buffer() { let scan_cnt = scan_counts.choose(&mut r).unwrap(); let low_key_v = r.gen_range(0..(key_cnt - scan_cnt)); - let low_key = GeneralKey::key_from(low_key_v); - let high_key = GeneralKey::key_from(low_key_v + scan_cnt * 5); + let low_key = TestingKey::key_from(low_key_v); + let high_key = TestingKey::key_from(low_key_v + scan_cnt * 5); let mut scan_results = vec![(0, 0); (*scan_cnt) / 2]; @@ -121,8 +121,8 @@ fn large_scan_small_buffer() { for _r in 0..16 { let scan_cnt = scan_counts.choose(&mut r).unwrap(); - let low_key = GeneralKey::key_from(0x6_0000); - let high_key = GeneralKey::key_from(0x6_ffff); + let low_key = TestingKey::key_from(0x6_0000); + let high_key = TestingKey::key_from(0x6_ffff); let mut scan_results = vec![(0, 0); *scan_cnt]; let r_found = tree.range(&low_key, &high_key, &mut scan_results, &guard); @@ -163,8 +163,8 @@ fn test_insert_and_scan() { let scan_cnt = scan_counts.choose(&mut r).unwrap(); let low_key_v = r.gen_range(0..(total_key - scan_cnt)); - let low_key = GeneralKey::key_from(low_key_v); - let high_key = GeneralKey::key_from(low_key_v + scan_cnt); + let low_key = TestingKey::key_from(low_key_v); + let high_key = TestingKey::key_from(low_key_v + scan_cnt); let mut scan_results = vec![(0, 0); *scan_cnt]; let _v = tree.range(&low_key, &high_key, &mut scan_results, &guard); @@ -180,7 +180,7 @@ fn test_insert_and_scan() { for i in 0..key_cnt_per_thread { let idx = t * key_cnt_per_thread + i; let val = key_space[idx]; - tree.insert(GeneralKey::key_from(val), val, &guard).unwrap(); + tree.insert(TestingKey::key_from(val), val, &guard).unwrap(); } })); } @@ -191,7 +191,7 @@ fn test_insert_and_scan() { let guard = crossbeam_epoch::pin(); for v in key_space.iter() { - let val = tree.get(&GeneralKey::key_from(*v), &guard).unwrap(); + let val = tree.get(&TestingKey::key_from(*v), &guard).unwrap(); assert_eq!(val, *v); } } @@ -201,11 +201,11 @@ fn fuzz_0() { let tree = RawTree::default(); let guard = crossbeam_epoch::pin(); - tree.insert(GeneralKey::key_from(54227), 54227, &guard) + tree.insert(TestingKey::key_from(54227), 54227, &guard) .unwrap(); - let low_key = GeneralKey::key_from(0); - let high_key = GeneralKey::key_from(0); + let low_key = TestingKey::key_from(0); + let high_key = TestingKey::key_from(0); let mut results = vec![(0, 0); 255]; let scanned = tree.range(&low_key, &high_key, &mut results, &guard); @@ -218,18 +218,18 @@ fn fuzz_1() { let guard = crossbeam_epoch::pin(); let key = 4294967179; - tree.insert(GeneralKey::key_from(key), key, &guard).unwrap(); + tree.insert(TestingKey::key_from(key), key, &guard).unwrap(); let scan_key = 1895772415; - let low_key = GeneralKey::key_from(scan_key); - let high_key = GeneralKey::key_from(scan_key + 255); + let low_key = TestingKey::key_from(scan_key); + let high_key = TestingKey::key_from(scan_key + 255); let mut results = vec![(0, 0); 256]; let scanned = tree.range(&low_key, &high_key, &mut results, &guard); assert_eq!(scanned, 0); - let low_key = GeneralKey::key_from(key); - let high_key = GeneralKey::key_from(key + 255); + let low_key = TestingKey::key_from(key); + let high_key = TestingKey::key_from(key + 255); let scanned = tree.range(&low_key, &high_key, &mut results, &guard); assert_eq!(scanned, 1); } @@ -239,14 +239,14 @@ fn fuzz_2() { let tree = RawTree::default(); let guard = crossbeam_epoch::pin(); - tree.insert(GeneralKey::key_from(4261390591), 4261390591, &guard) + tree.insert(TestingKey::key_from(4261390591), 4261390591, &guard) .unwrap(); - tree.insert(GeneralKey::key_from(4294944959), 4294944959, &guard) + tree.insert(TestingKey::key_from(4294944959), 4294944959, &guard) .unwrap(); let scan_key = 4261412863; - let low_key = GeneralKey::key_from(scan_key); - let high_key = GeneralKey::key_from(scan_key + 253); + let low_key = TestingKey::key_from(scan_key); + let high_key = TestingKey::key_from(scan_key + 253); let mut results = vec![(0, 0); 256]; let scanned = tree.range(&low_key, &high_key, &mut results, &guard); @@ -258,22 +258,22 @@ fn fuzz_3() { let tree = RawTree::default(); let guard = crossbeam_epoch::pin(); - tree.insert(GeneralKey::key_from(4294967295), 4294967295, &guard) + tree.insert(TestingKey::key_from(4294967295), 4294967295, &guard) .unwrap(); - tree.insert(GeneralKey::key_from(4294967247), 4294967247, &guard) + tree.insert(TestingKey::key_from(4294967247), 4294967247, &guard) .unwrap(); let scan_key = 4294967066; - let low_key = GeneralKey::key_from(scan_key); - let high_key = GeneralKey::key_from(scan_key + 253); + let low_key = TestingKey::key_from(scan_key); + let high_key = TestingKey::key_from(scan_key + 253); let mut results = vec![(0, 0); 256]; let scanned = tree.range(&low_key, &high_key, &mut results, &guard); assert_eq!(scanned, 2); let scan_key = 4294967000; - let low_key = GeneralKey::key_from(scan_key); - let high_key = GeneralKey::key_from(scan_key + 253); + let low_key = TestingKey::key_from(scan_key); + let high_key = TestingKey::key_from(scan_key + 253); let scanned = tree.range(&low_key, &high_key, &mut results, &guard); assert_eq!(scanned, 1); @@ -284,14 +284,14 @@ fn fuzz_4() { let tree = RawTree::default(); let guard = crossbeam_epoch::pin(); - tree.insert(GeneralKey::key_from(219021065), 219021065, &guard) + tree.insert(TestingKey::key_from(219021065), 219021065, &guard) .unwrap(); - tree.insert(GeneralKey::key_from(4279959551), 4279959551, &guard) + tree.insert(TestingKey::key_from(4279959551), 4279959551, &guard) .unwrap(); let scan_key = 4294967295; - let low_key = GeneralKey::key_from(scan_key); - let high_key = GeneralKey::key_from(scan_key + 253); + let low_key = TestingKey::key_from(scan_key); + let high_key = TestingKey::key_from(scan_key + 253); let mut results = vec![(0, 0); 256]; let scanned = tree.range(&low_key, &high_key, &mut results, &guard); @@ -303,14 +303,14 @@ fn fuzz_5() { let tree = RawTree::default(); let guard = crossbeam_epoch::pin(); - tree.insert(GeneralKey::key_from(4294967128), 429496, &guard) + tree.insert(TestingKey::key_from(4294967128), 429496, &guard) .unwrap(); - tree.insert(GeneralKey::key_from(4294940824), 40824, &guard) + tree.insert(TestingKey::key_from(4294940824), 40824, &guard) .unwrap(); let scan_key = 4294967039; - let low_key = GeneralKey::key_from(scan_key); - let high_key = GeneralKey::key_from(scan_key + 255); + let low_key = TestingKey::key_from(scan_key); + let high_key = TestingKey::key_from(scan_key + 255); let mut results = vec![(0, 0); 256]; let scanned = tree.range(&low_key, &high_key, &mut results, &guard); @@ -322,14 +322,14 @@ fn fuzz_6() { let tree = RawTree::default(); let guard = crossbeam_epoch::pin(); - tree.insert(GeneralKey::key_from(4278190080), 2734686207, &guard) + tree.insert(TestingKey::key_from(4278190080), 2734686207, &guard) .unwrap(); - tree.insert(GeneralKey::key_from(4278189917), 3638099967, &guard) + tree.insert(TestingKey::key_from(4278189917), 3638099967, &guard) .unwrap(); let scan_key = 4278190079; - let low_key = GeneralKey::key_from(scan_key); - let high_key = GeneralKey::key_from(scan_key + 255); + let low_key = TestingKey::key_from(scan_key); + let high_key = TestingKey::key_from(scan_key + 255); let mut results = vec![(0, 0); 256]; let scanned = tree.range(&low_key, &high_key, &mut results, &guard); diff --git a/src/tests/tree.rs b/src/tests/tree.rs index abb63fe..1bae478 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -4,7 +4,7 @@ use shuttle::thread; #[cfg(not(all(feature = "shuttle", test)))] use std::thread; -use crate::key::{GeneralKey, RawKey}; +use crate::key::{RawKey, TestingKey}; use crate::tree::RawTree; use std::sync::Arc; @@ -15,8 +15,8 @@ fn small_insert() { let guard = crossbeam_epoch::pin(); for k in 0..key_cnt { - tree.insert(GeneralKey::key_from(k), k, &guard).unwrap(); - let v = tree.get(&GeneralKey::key_from(k), &guard).unwrap(); + tree.insert(TestingKey::key_from(k), k, &guard).unwrap(); + let v = tree.get(&TestingKey::key_from(k), &guard).unwrap(); assert_eq!(v, k); } } @@ -32,24 +32,24 @@ fn test_sparse_keys() { let k = thread_rng().gen::() & 0x7fff_ffff_ffff_ffff; keys.push(k); - tree.insert(GeneralKey::key_from(k), k, &guard).unwrap(); + tree.insert(TestingKey::key_from(k), k, &guard).unwrap(); } let delete_cnt = key_cnt / 2; for i in keys.iter().take(delete_cnt) { let _rt = tree - .compute_if_present(&GeneralKey::key_from(*i), &mut |_v| None, &guard) + .compute_if_present(&TestingKey::key_from(*i), &mut |_v| None, &guard) .unwrap(); } for i in keys.iter().take(delete_cnt) { - let v = tree.get(&GeneralKey::key_from(*i), &guard); + let v = tree.get(&TestingKey::key_from(*i), &guard); assert!(v.is_none()); } for i in keys.iter().skip(delete_cnt) { - let v = tree.get(&GeneralKey::key_from(*i), &guard).unwrap(); + let v = tree.get(&TestingKey::key_from(*i), &guard).unwrap(); assert_eq!(v, *i); } @@ -86,7 +86,7 @@ fn test_concurrent_insert() { for i in 0..key_cnt_per_thread { let idx = t * key_cnt_per_thread + i; let val = key_space[idx]; - tree.insert(GeneralKey::key_from(val), val, &guard).unwrap(); + tree.insert(TestingKey::key_from(val), val, &guard).unwrap(); } })); } @@ -97,7 +97,7 @@ fn test_concurrent_insert() { let guard = crossbeam_epoch::pin(); for v in key_space.iter() { - let val = tree.get(&GeneralKey::key_from(*v), &guard).unwrap(); + let val = tree.get(&TestingKey::key_from(*v), &guard).unwrap(); assert_eq!(val, *v); } } @@ -141,7 +141,7 @@ fn test_concurrent_insert_read() { for i in 0..key_cnt_per_thread { let idx = t * key_cnt_per_thread + i; let val = key_space[idx]; - tree.insert(GeneralKey::key_from(val), val, &guard).unwrap(); + tree.insert(TestingKey::key_from(val), val, &guard).unwrap(); } })); } @@ -154,7 +154,7 @@ fn test_concurrent_insert_read() { let guard = crossbeam_epoch::pin(); for _i in 0..key_cnt_per_thread { let val = r.gen_range(0..(key_cnt_per_thread * w_thread)); - if let Some(v) = tree.get(&GeneralKey::key_from(val), &guard) { + if let Some(v) = tree.get(&TestingKey::key_from(val), &guard) { assert_eq!(v, val); } } @@ -167,7 +167,7 @@ fn test_concurrent_insert_read() { let guard = crossbeam_epoch::pin(); for v in key_space.iter() { - let val = tree.get(&GeneralKey::key_from(*v), &guard).unwrap(); + let val = tree.get(&TestingKey::key_from(*v), &guard).unwrap(); assert_eq!(val, *v); } } diff --git a/src/tree.rs b/src/tree.rs index 1006db0..c033b71 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -17,7 +17,7 @@ use crate::{ /// Raw interface to the ART tree. /// The `Art` is a wrapper around the `RawArt` that provides a safe interface. -/// Unlike `Art`, it support arbitrary `Key` types, see also `RawKey`. +/// Unlike `Art`, it supports arbitrary `Key` types, see also `RawKey`. pub(crate) struct RawTree { pub(crate) root: *const Node256, allocator: A,