diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ea0c80..1b5ac8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -244,14 +244,31 @@ jobs: run: ci/miri_tb_unsync.sh if: matrix.os == 'ubuntu-latest' - miri-tb-swmr: - name: miri-tb-swmr + miri-tb: + name: miri-tb-${{ matrix.os }}-${{ matrix.target }}-${{ matrix.features }} strategy: matrix: os: - ubuntu-latest # - macos-latest # - windows-latest + target: + - x86_64-unknown-linux-gnu + - i686-unknown-linux-gnu + - powerpc64-unknown-linux-gnu + features: + - test-unsync-insert + - test-unsync-iters + - test-unsync-get + - test-unsync-constructor + - test-swmr-insert + - test-swmr-iters + - test-swmr-get + - test-swmr-constructor + - test-swmr-generic-insert + - test-swmr-generic-iters + - test-swmr-generic-get + - test-swmr-generic-constructor runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 @@ -270,33 +287,6 @@ jobs: - name: Miri (Linux) run: ci/miri_tb_swmr.sh if: matrix.os == 'ubuntu-latest' - - miri-tb-swmr-generic: - name: miri-tb-swmr-generic - strategy: - matrix: - os: - - ubuntu-latest - # - macos-latest - # - windows-latest - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - name: Cache cargo build and registry - uses: actions/cache@v3 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-miri-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-miri- - - name: Install cargo-hack - run: cargo install cargo-hack - - name: Miri (Linux) - run: ci/miri_tb_swmr_generic.sh - if: matrix.os == 'ubuntu-latest' # miri-sb: # name: miri-sb diff --git a/Cargo.toml b/Cargo.toml index 3dab90e..515871a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,9 +24,21 @@ xxhash3 = ["dbutils/xxhash3", "std"] xxhash64 = ["dbutils/xxhash64", "std"] ## only for miri testing -test-unsync = ["std"] -test-swmr = ["std"] -test-swmr-generic = ["std"] +test-unsync-insert = ["std"] +test-unsync-iters = ["std"] +test-unsync-get = ["std"] +test-unsync-constructor = ["std"] + +test-swmr-insert = ["std"] +test-swmr-iters = ["std"] +test-swmr-get = ["std"] +test-swmr-constructor = ["std"] + +test-swmr-generic-insert = ["std"] +test-swmr-generic-iters = ["std"] +test-swmr-generic-get = ["std"] +test-swmr-generic-constructor = ["std"] + [dependencies] among = { version = "0.1", default-features = false, features = ["either"] } diff --git a/ci/miri_tb.sh b/ci/miri_tb.sh index 5a6c4c2..963a8ac 100755 --- a/ci/miri_tb.sh +++ b/ci/miri_tb.sh @@ -5,9 +5,15 @@ rustup toolchain install nightly --component miri rustup override set nightly cargo miri setup +# Default target platform and features if none are passed +TARGET=${1:-x86_64-unknown-linux-gnu} +FEATURES=${2:-test-swmr} + export MIRIFLAGS="-Zmiri-symbolic-alignment-check -Zmiri-disable-isolation -Zmiri-tree-borrows" -cargo miri test --tests --target x86_64-unknown-linux-gnu --all-features -# cargo miri test --tests --target aarch64-unknown-linux-gnu #crossbeam_utils has problem on this platform -cargo miri test --tests --target i686-unknown-linux-gnu --all-features -cargo miri test --tests --target powerpc64-unknown-linux-gnu --all-features +cargo miri test --tests --target $TARGET --features $FEATURES --lib + +# cargo miri test --tests --target x86_64-unknown-linux-gnu --all-features +# # cargo miri test --tests --target aarch64-unknown-linux-gnu #crossbeam_utils has problem on this platform +# cargo miri test --tests --target i686-unknown-linux-gnu --all-features +# cargo miri test --tests --target powerpc64-unknown-linux-gnu --all-features diff --git a/ci/miri_tb_generic.sh b/ci/miri_tb_generic.sh deleted file mode 100755 index 6e6c901..0000000 --- a/ci/miri_tb_generic.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -e - -rustup toolchain install nightly --component miri -rustup override set nightly -cargo miri setup - -export MIRIFLAGS="-Zmiri-symbolic-alignment-check -Zmiri-disable-isolation -Zmiri-tree-borrows" - -cargo miri test --tests --all-features diff --git a/ci/miri_tb_swmr.sh b/ci/miri_tb_swmr.sh deleted file mode 100755 index 4196fbb..0000000 --- a/ci/miri_tb_swmr.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -e - -rustup toolchain install nightly --component miri -rustup override set nightly -cargo miri setup - -export MIRIFLAGS="-Zmiri-symbolic-alignment-check -Zmiri-disable-isolation -Zmiri-tree-borrows -Zmiri-ignore-leaks" - -cargo miri test --tests --target x86_64-unknown-linux-gnu --features test-swmr --lib -# cargo miri test --tests --target aarch64-unknown-linux-gnu #crossbeam_utils has problem on this platform -cargo miri test --tests --target i686-unknown-linux-gnu --features test-swmr --lib -cargo miri test --tests --target powerpc64-unknown-linux-gnu --features test-swmr --lib diff --git a/ci/miri_tb_swmr_generic.sh b/ci/miri_tb_swmr_generic.sh deleted file mode 100755 index 770c91d..0000000 --- a/ci/miri_tb_swmr_generic.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -e - -rustup toolchain install nightly --component miri -rustup override set nightly -cargo miri setup - -export MIRIFLAGS="-Zmiri-symbolic-alignment-check -Zmiri-disable-isolation -Zmiri-tree-borrows -Zmiri-ignore-leaks" - -cargo miri test --tests --target x86_64-unknown-linux-gnu --features test-swmr-generic --lib -# cargo miri test --tests --target aarch64-unknown-linux-gnu #crossbeam_utils has problem on this platform -cargo miri test --tests --target i686-unknown-linux-gnu --features test-swmr-generic --lib -cargo miri test --tests --target powerpc64-unknown-linux-gnu --features test-swmr-generic --lib diff --git a/ci/miri_tb_unsync.sh b/ci/miri_tb_unsync.sh deleted file mode 100755 index 8a485ad..0000000 --- a/ci/miri_tb_unsync.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -e - -rustup toolchain install nightly --component miri -rustup override set nightly -cargo miri setup - -export MIRIFLAGS="-Zmiri-symbolic-alignment-check -Zmiri-disable-isolation -Zmiri-tree-borrows" - -cargo miri test --tests --target x86_64-unknown-linux-gnu --features test-unsync --lib -# cargo miri test --tests --target aarch64-unknown-linux-gnu #crossbeam_utils has problem on this platform -cargo miri test --tests --target i686-unknown-linux-gnu --features test-unsync --lib -cargo miri test --tests --target powerpc64-unknown-linux-gnu --features test-unsync --lib diff --git a/src/lib.rs b/src/lib.rs index a6a5ae2..e04cbba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,7 @@ const MAGIC_TEXT_SIZE: usize = MAGIC_TEXT.len(); const MAGIC_VERSION_SIZE: usize = mem::size_of::(); const HEADER_SIZE: usize = MAGIC_TEXT_SIZE + MAGIC_VERSION_SIZE; -#[cfg(all(test, any(feature = "test-swmr", feature = "test-unsync")))] +#[cfg(test)] #[macro_use] mod tests; diff --git a/src/swmr/generic.rs b/src/swmr/generic.rs index b589122..4d97a13 100644 --- a/src/swmr/generic.rs +++ b/src/swmr/generic.rs @@ -32,7 +32,7 @@ pub use reader::*; mod iter; pub use iter::*; -#[cfg(all(test, feature = "test-swmr-generic"))] +#[cfg(test)] mod tests; #[doc(hidden)] diff --git a/src/swmr/generic/tests.rs b/src/swmr/generic/tests.rs index 8cf51b0..4836cb4 100644 --- a/src/swmr/generic/tests.rs +++ b/src/swmr/generic/tests.rs @@ -8,6 +8,15 @@ use super::*; const MB: u32 = 1024 * 1024; +#[cfg(all(test, feature = "test-swmr-generic-constructor"))] +mod constructor; +#[cfg(all(test, feature = "test-swmr-generic-get"))] +mod get; +#[cfg(all(test, feature = "test-swmr-generic-insert"))] +mod insert; +#[cfg(all(test, feature = "test-swmr-generic-iters"))] +mod iters; + #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Arbitrary)] struct Person { id: u64, @@ -155,1584 +164,3 @@ impl<'a> TypeRef<'a> for PersonRef<'a> { PersonRef { id, name } } } - -#[test] -fn owned_comparable() { - let p1 = Person { - id: 3127022870678870148, - name: "enthusiastic-magic".into(), - }; - let p2 = Person { - id: 9872687799307360216, - name: "damaged-friend".into(), - }; - - let p1bytes = p1.to_vec(); - let p2bytes = p2.to_vec(); - - let ptr1 = Pointer::::new(p1bytes.len(), 0, p1bytes.as_ptr()); - let ptr2 = Pointer::::new(p2bytes.len(), 0, p2bytes.as_ptr()); - - let map = SkipSet::new(); - map.insert(ptr1); - map.insert(ptr2); - - assert!(map.contains(&Owned::new(&p1))); - assert!(map.get(&Owned::new(&p1)).is_some()); - - assert!(map.contains(&Owned::new(&p2))); - assert!(map.get(&Owned::new(&p2)).is_some()); - - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - wal.insert(&p1, &"My name is Alice!".to_string()).unwrap(); - wal.insert(&p2, &"My name is Bob!".to_string()).unwrap(); - - assert!(wal.contains_key(&p1)); - assert_eq!(wal.get(&p1).unwrap().value(), "My name is Alice!"); - - assert!(wal.contains_key(&p2)); - assert_eq!(wal.get(&p2).unwrap().value(), "My name is Bob!"); -} - -#[test] -fn ref_comparable() { - let p1 = PersonRef { - id: 3127022870678870148, - name: "enthusiastic-magic", - }; - let p2 = PersonRef { - id: 9872687799307360216, - name: "damaged-friend", - }; - - let p1bytes = p1.to_vec(); - let p2bytes = p2.to_vec(); - - let ptr1 = Pointer::::new(p1bytes.len(), 0, p1bytes.as_ptr()); - let ptr2 = Pointer::::new(p2bytes.len(), 0, p2bytes.as_ptr()); - - let map = SkipSet::new(); - map.insert(ptr1); - map.insert(ptr2); - - assert!(map.contains(&Owned::new(&p1))); - assert!(map.get(&Owned::new(&p1)).is_some()); - - assert!(map.contains(&Owned::new(&p2))); - assert!(map.get(&Owned::new(&p2)).is_some()); - - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - - unsafe { - wal - .insert_key_bytes_with_value(&p1bytes, &"My name is Alice!".to_string()) - .unwrap(); - wal - .insert_key_bytes_with_value(&p2bytes, &"My name is Bob!".to_string()) - .unwrap(); - } - - assert!(wal.contains_key(&p1)); - assert_eq!(wal.get(&p1).unwrap().value(), "My name is Alice!"); - - assert!(wal.contains_key(&p2)); - assert_eq!(wal.get(&p2).unwrap().value(), "My name is Bob!"); - - assert!(wal.contains_key_by_ref(&p1)); - assert_eq!(wal.get(&p1).unwrap().value(), "My name is Alice!"); - - assert!(wal.contains_key_by_ref(&p2)); - assert_eq!(wal.get(&p2).unwrap().value(), "My name is Bob!"); - - unsafe { - assert!(wal.contains_key_by_bytes(&p1bytes)); - assert_eq!(wal.get(&p1).unwrap().value(), "My name is Alice!"); - - assert!(wal.contains_key_by_bytes(&p2bytes)); - assert_eq!(wal.get(&p2).unwrap().value(), "My name is Bob!"); - } -} - -#[test] -fn construct_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - - let person = Person { - id: 1, - name: "Alice".to_string(), - }; - - assert!(wal.is_empty()); - - wal - .insert(&person, &"My name is Alice!".to_string()) - .unwrap(); - - let wal = wal.reader(); - - assert_eq!(wal.len(), 1); - assert!(!wal.is_empty()); -} - -#[test] -fn construct_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - - let person = Person { - id: 1, - name: "Alice".to_string(), - }; - - wal - .insert(&person, &"My name is Alice!".to_string()) - .unwrap(); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn construct_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_construct_map_file"); - - unsafe { - let mut wal = GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap(); - let person = Person { - id: 1, - name: "Alice".to_string(), - }; - - wal - .insert(&person, &"My name is Alice!".to_string()) - .unwrap(); - assert_eq!(wal.get(&person).unwrap().value(), "My name is Alice!"); - - assert_eq!(*wal.path().unwrap().as_ref(), path); - } - - let pr = PersonRef { - id: 1, - name: "Alice", - }; - - unsafe { - let wal = GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new().create(Some(MB)).write(true).read(true), - ) - .unwrap(); - assert_eq!(wal.get(&pr).unwrap().value(), "My name is Alice!"); - } - - let wal = unsafe { GenericOrderWal::::map(&path, Options::new()).unwrap() }; - assert_eq!(wal.get(&pr).unwrap().value(), "My name is Alice!"); -} - -#[test] -fn construct_with_small_capacity_inmemory() { - let wal = GenericOrderWal::::new(Options::new().with_capacity(1)); - - assert!(wal.is_err()); - match wal { - Err(e) => println!("error: {:?}", e), - _ => panic!("unexpected error"), - } -} - -#[test] -fn construct_with_small_capacity_map_anon() { - let wal = GenericOrderWal::::map_anon(Options::new().with_capacity(1)); - - assert!(wal.is_err()); - match wal { - Err(e) => println!("error: {:?}", e), - _ => panic!("unexpected error"), - } -} - -#[test] -fn construct_with_small_capacity_map_file() { - let dir = tempdir().unwrap(); - let path = dir - .path() - .join("generic_wal_construct_with_small_capacity_map_file"); - - let wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(1)) - .write(true) - .read(true), - ) - }; - - assert!(wal.is_err()); - match wal { - Err(e) => println!("{:?}", e), - _ => panic!("unexpected error"), - } -} - -fn insert_to_full(wal: &mut GenericOrderWal) { - let mut full = false; - for _ in 0u32.. { - let p = Person::random(); - match wal.insert(&p, &format!("My name is {}", p.name)) { - Ok(_) => {} - Err(e) => match e { - Among::Right(Error::InsufficientSpace { .. }) => { - full = true; - break; - } - _ => panic!("unexpected error"), - }, - } - } - assert!(full); -} - -#[test] -fn insert_to_full_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - insert_to_full(&mut wal); -} - -#[test] -fn insert_to_full_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - insert_to_full(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn insert_to_full_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_insert_to_full_map_file"); - - unsafe { - let mut wal = GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap(); - insert_to_full(&mut wal); - } -} - -fn insert(wal: &mut GenericOrderWal) -> Vec { - let people = (0..100) - .map(|_| { - let p = Person::random(); - wal.insert(&p, &format!("My name is {}", p.name)).unwrap(); - p - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for p in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - assert_eq!( - wal.get(p).unwrap().value(), - format!("My name is {}", p.name) - ); - } - - people -} - -#[test] -fn insert_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - insert(&mut wal); -} - -#[test] -fn insert_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - insert(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn insert_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_insert_map_file"); - - let people = unsafe { - let mut wal = GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap(); - insert(&mut wal) - }; - - let wal = unsafe { GenericOrderWal::::map(&path, Options::new()).unwrap() }; - - for p in people { - assert!(wal.contains_key(&p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - assert_eq!( - wal.get(&p).unwrap().value(), - format!("My name is {}", p.name) - ); - } -} - -fn insert_key_bytes_with_value( - wal: &mut GenericOrderWal, -) -> Vec<(Vec, Person)> { - let people = (0..100) - .map(|_| { - let p = Person::random(); - let pbytes = p.to_vec(); - unsafe { - wal - .insert_key_bytes_with_value(&pbytes, &format!("My name is {}", p.name)) - .unwrap(); - } - (pbytes, p) - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for (pbytes, p) in &people { - assert!(wal.contains_key(p)); - unsafe { - assert!(wal.contains_key_by_bytes(pbytes)); - } - assert_eq!( - wal.get(p).unwrap().value(), - format!("My name is {}", p.name) - ); - - assert_eq!( - unsafe { wal.get_by_bytes(pbytes).unwrap().value() }, - format!("My name is {}", p.name) - ); - } - - people -} - -#[test] -fn insert_key_bytes_with_value_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - insert_key_bytes_with_value(&mut wal); -} - -#[test] -fn insert_key_bytes_with_value_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - insert_key_bytes_with_value(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn insert_key_bytes_with_value_map_file() { - let dir = tempdir().unwrap(); - let path = dir - .path() - .join("generic_wal_insert_key_bytes_with_value_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - let people = insert_key_bytes_with_value(&mut wal); - - let wal = wal.reader(); - - for (pbytes, p) in &people { - assert!(wal.contains_key(p)); - unsafe { - assert!(wal.contains_key_by_bytes(pbytes)); - } - assert_eq!( - wal.get(p).unwrap().value(), - format!("My name is {}", p.name) - ); - assert_eq!( - unsafe { wal.get_by_bytes(pbytes).unwrap().value() }, - format!("My name is {}", p.name) - ); - } - - let wal = unsafe { GenericOrderWal::::map(&path, Options::new()).unwrap() }; - - for (pbytes, p) in people { - assert!(wal.contains_key(&p)); - unsafe { - assert!(wal.contains_key_by_bytes(&pbytes)); - } - assert_eq!( - wal.get(&p).unwrap().value(), - format!("My name is {}", p.name) - ); - assert_eq!( - unsafe { wal.get_by_bytes(&pbytes).unwrap().value() }, - format!("My name is {}", p.name) - ); - } -} - -fn insert_key_with_value_bytes(wal: &mut GenericOrderWal) -> Vec { - let people = (0..100) - .map(|_| { - let p = Person::random(); - unsafe { - wal - .insert_key_with_value_bytes(&p, format!("My name is {}", p.name).as_bytes()) - .unwrap(); - } - p - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for p in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - assert_eq!( - wal.get_by_ref(p).unwrap().value(), - format!("My name is {}", p.name) - ); - } - - people -} - -#[test] -fn insert_key_with_value_bytes_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - insert_key_with_value_bytes(&mut wal); -} - -#[test] -fn insert_key_with_value_bytes_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - insert_key_with_value_bytes(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn insert_key_with_value_bytes_map_file() { - let dir = tempdir().unwrap(); - let path = dir - .path() - .join("generic_wal_insert_key_with_value_bytes_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - let people = insert_key_with_value_bytes(&mut wal); - let wal = wal.reader(); - - for p in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - assert_eq!( - wal.get_by_ref(p).unwrap().value(), - format!("My name is {}", p.name) - ); - } -} - -fn insert_bytes(wal: &mut GenericOrderWal) -> Vec { - let people = (0..100) - .map(|_| { - let p = Person::random(); - let pbytes = p.to_vec(); - unsafe { - wal - .insert_bytes(&pbytes, format!("My name is {}", p.name).as_bytes()) - .unwrap(); - } - p - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for p in &people { - assert!(wal.contains_key(p)); - unsafe { - assert!(wal.contains_key_by_bytes(&p.to_vec())); - } - assert_eq!( - wal.get(p).unwrap().value(), - format!("My name is {}", p.name) - ); - } - - people -} - -#[test] -fn insert_bytes_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - insert_bytes(&mut wal); -} - -#[test] -fn insert_bytes_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - insert_bytes(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn insert_bytes_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_insert_bytes_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - let people = insert_bytes(&mut wal); - - let wal = wal.reader(); - - for p in &people { - assert!(wal.contains_key(p)); - unsafe { - assert!(wal.contains_key_by_bytes(&p.to_vec())); - } - assert_eq!( - wal.get(p).unwrap().value(), - format!("My name is {}", p.name) - ); - } -} - -fn iter(wal: &mut GenericOrderWal) -> Vec<(Person, String)> { - let mut people = (0..100) - .map(|_| { - let p = Person::random(); - let v = format!("My name is {}", p.name); - wal.insert(&p, &v).unwrap(); - (p, v) - }) - .collect::>(); - - people.sort_by(|a, b| a.0.cmp(&b.0)); - - let mut iter = wal.iter(); - - for (pwal, pvec) in people.iter().zip(iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } - - let mut rev_iter = wal.iter().rev(); - - for (pwal, pvec) in people.iter().rev().zip(rev_iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } - - people -} - -#[test] -fn iter_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - iter(&mut wal); -} - -#[test] -fn iter_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - iter(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn iter_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_iter_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - let people = iter(&mut wal); - - let wal = wal.reader(); - let mut iter = wal.iter(); - - for (pwal, pvec) in people.iter().zip(iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } -} - -fn range(wal: &mut GenericOrderWal) { - let mut mid = Person::random(); - let people = (0..100) - .map(|idx| { - let p = Person::random(); - let v = format!("My name is {}", p.name); - wal.insert(&p, &v).unwrap(); - - if idx == 500 { - mid = p.clone(); - } - (p, v) - }) - .collect::>(); - - let mut iter = wal.range(Bound::Included(&mid), Bound::Unbounded); - - for (pwal, pvec) in people.range(&mid..).zip(iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } - - assert!(iter.next().is_none()); - - let wal = wal.reader(); - let mut iter = wal.range(Bound::Included(&mid), Bound::Unbounded); - - for (pwal, pvec) in people.range(&mid..).zip(iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } - - let mut rev_iter = wal.range(Bound::Included(&mid), Bound::Unbounded).rev(); - - for (pwal, pvec) in people.range(&mid..).rev().zip(rev_iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } -} - -#[test] -fn range_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - range(&mut wal); -} - -#[test] -fn range_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - range(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn range_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_range_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - range(&mut wal); -} - -fn range_ref(wal: &mut GenericOrderWal) { - let mut mid = Person::random(); - let people = (0..100) - .map(|idx| { - let p = Person::random(); - let v = format!("My name is {}", p.name); - wal.insert(&p, &v).unwrap(); - - if idx == 500 { - mid = p.clone(); - } - (p, v) - }) - .collect::>(); - - let mid_ref = mid.as_ref(); - let mut iter = wal.range_by_ref(Bound::Included(&mid_ref), Bound::Unbounded); - - for (pwal, pvec) in people.range(&mid..).zip(iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } - - assert!(iter.next().is_none()); - - let wal = wal.reader(); - let mut iter = wal.range_by_ref(Bound::Included(&mid), Bound::Unbounded); - - for (pwal, pvec) in people.range(&mid..).zip(iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } - - let mut rev_iter = wal - .range_by_ref(Bound::Included(&mid), Bound::Unbounded) - .rev(); - - for (pwal, pvec) in people.range(&mid..).rev().zip(rev_iter.by_ref()) { - assert!(pwal.0.equivalent(&pvec.key())); - assert_eq!(pwal.1, pvec.value()); - } -} - -#[test] -fn range_ref_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - range(&mut wal); -} - -#[test] -fn range_ref_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - range_ref(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn range_ref_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_range_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - range_ref(&mut wal); -} - -fn first(wal: &mut GenericOrderWal) { - let people = (0..10) - .map(|_| { - let p = Person::random(); - let v = format!("My name is {}", p.name); - wal.insert(&p, &v).unwrap(); - - (p, v) - }) - .collect::>(); - - let ent = wal.first().unwrap(); - let (p, v) = people.first_key_value().unwrap(); - assert!(ent.key().equivalent(p)); - assert_eq!(ent.value(), v); - - let wal = wal.reader().clone(); - let ent = wal.first().unwrap(); - let (p, v) = people.first_key_value().unwrap(); - assert!(ent.key().equivalent(p)); - assert_eq!(ent.value(), v); -} - -#[test] -fn first_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - first(&mut wal); -} - -#[test] -fn first_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - first(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn first_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_first_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - first(&mut wal); -} - -fn last(wal: &mut GenericOrderWal) { - let people = (0..10) - .map(|_| { - let p = Person::random(); - let v = format!("My name is {}", p.name); - wal.insert(&p, &v).unwrap(); - - (p, v) - }) - .collect::>(); - - let ent = wal.last().unwrap(); - let (p, v) = people.last_key_value().unwrap(); - assert!(ent.key().equivalent(p)); - assert_eq!(ent.value(), v); - - let wal = wal.reader(); - let ent = wal.last().unwrap(); - assert!(ent.key().equivalent(p)); - assert_eq!(ent.value(), v); -} - -#[test] -fn last_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - last(&mut wal); -} - -#[test] -fn last_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - last(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn last_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_last_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - last(&mut wal); -} - -fn get_or_insert(wal: &mut GenericOrderWal) { - let people = (0..100) - .map(|_| { - let p = Person::random(); - let v = format!("My name is {}", p.name); - wal.get_or_insert(&p, &v).unwrap_right().unwrap(); - (p, v) - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for (p, pv) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - assert_eq!( - wal - .get_or_insert(p, &format!("Hello! {}!", p.name)) - .unwrap_left() - .value(), - pv - ); - } - - for (p, _) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - } -} - -#[test] -fn get_or_insert_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - get_or_insert(&mut wal); -} - -#[test] -fn get_or_insert_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - get_or_insert(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn get_or_insert_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_get_or_insert_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - get_or_insert(&mut wal); -} - -fn get_or_insert_with(wal: &mut GenericOrderWal) { - let people = (0..100) - .map(|_| { - let p = Person::random(); - let v = format!("My name is {}", p.name); - wal - .get_or_insert_with(&p, || v.clone()) - .unwrap_right() - .unwrap(); - (p, v) - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for (p, pv) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - assert_eq!( - wal - .get_or_insert_with(p, || format!("Hello! {}!", p.name)) - .unwrap_left() - .value(), - pv - ); - } - - for (p, _) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - } -} - -#[test] -fn get_or_insert_with_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - get_or_insert_with(&mut wal); -} - -#[test] -fn get_or_insert_with_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - get_or_insert_with(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn get_or_insert_with_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_get_or_insert_with_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - get_or_insert_with(&mut wal); -} - -fn get_or_insert_key_with_value_bytes(wal: &mut GenericOrderWal) { - let people = (0..100) - .map(|_| { - let p = Person::random(); - let pvec = p.to_vec(); - let v = format!("My name is {}", p.name); - unsafe { - wal - .get_by_bytes_or_insert(pvec.as_ref(), &v) - .unwrap_right() - .unwrap(); - } - (p, v) - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for (p, pv) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - assert_eq!( - wal - .get_or_insert(p, &format!("Hello! {}!", p.name)) - .unwrap_left() - .value(), - pv - ); - } - - for (p, _) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - } -} - -#[test] -fn get_or_insert_key_with_value_bytes_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - get_or_insert_key_with_value_bytes(&mut wal); -} - -#[test] -fn get_or_insert_key_with_value_bytes_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - get_or_insert_key_with_value_bytes(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn get_or_insert_key_with_value_bytes_map_file() { - let dir = tempdir().unwrap(); - let path = dir - .path() - .join("generic_wal_get_or_insert_key_with_value_bytes_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - get_or_insert_key_with_value_bytes(&mut wal); -} - -fn get_or_insert_value_bytes(wal: &mut GenericOrderWal) { - let people = (0..100) - .map(|_| { - let p = Person::random(); - let v = format!("My name is {}", p.name); - unsafe { - wal - .get_or_insert_bytes(&p, v.as_bytes()) - .unwrap_right() - .unwrap(); - } - (p, v) - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for (p, pv) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - unsafe { - assert_eq!( - wal - .get_or_insert_bytes(p, pv.as_bytes()) - .unwrap_left() - .value(), - pv - ); - } - } - - for (p, _) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - } -} - -#[test] -fn get_or_insert_value_bytes_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - get_or_insert_value_bytes(&mut wal); -} - -#[test] -fn get_or_insert_value_bytes_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - get_or_insert_value_bytes(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn get_or_insert_value_bytes_map_file() { - let dir = tempdir().unwrap(); - let path = dir - .path() - .join("generic_wal_get_or_insert_value_bytes_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - get_or_insert_value_bytes(&mut wal); -} - -fn get_by_bytes_or_insert_with(wal: &mut GenericOrderWal) { - let people = (0..100) - .map(|_| { - let p = Person::random(); - let pvec = p.to_vec(); - let v = format!("My name is {}", p.name); - unsafe { - wal - .get_by_bytes_or_insert_with(pvec.as_ref(), || v.clone()) - .unwrap_right() - .unwrap(); - } - (p, pvec, v) - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for (p, pvec, pv) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - unsafe { - assert_eq!( - wal - .get_by_bytes_or_insert_with(pvec, || format!("Hello! {}!", p.name)) - .unwrap_left() - .value(), - pv - ); - } - } - - for (p, _, _) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - } -} - -#[test] -fn get_by_bytes_or_insert_with_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - get_by_bytes_or_insert_with(&mut wal); -} - -#[test] -fn get_by_bytes_or_insert_with_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - get_by_bytes_or_insert_with(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn get_by_bytes_or_insert_with_map_file() { - let dir = tempdir().unwrap(); - let path = dir - .path() - .join("generic_wal_get_by_bytes_or_insert_with_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - get_by_bytes_or_insert_with(&mut wal); -} - -fn get_by_bytes_or_insert_bytes(wal: &mut GenericOrderWal) { - let people = (0..100) - .map(|_| { - let p = Person::random(); - let pvec = p.to_vec(); - let v = format!("My name is {}", p.name); - unsafe { - wal - .get_by_bytes_or_insert_bytes(pvec.as_ref(), v.as_bytes()) - .unwrap_right() - .unwrap(); - } - (p, pvec, v) - }) - .collect::>(); - - assert_eq!(wal.len(), 100); - - for (p, pvec, pv) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - unsafe { - assert_eq!( - wal - .get_by_bytes_or_insert_bytes(pvec, pv.as_bytes()) - .unwrap_left() - .value(), - pv - ); - } - } - - for (p, _, _) in &people { - assert!(wal.contains_key(p)); - assert!(wal.contains_key_by_ref(&p.as_ref())); - } -} - -#[test] -fn get_by_bytes_or_insert_bytes_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - get_by_bytes_or_insert_bytes(&mut wal); -} - -#[test] -fn get_by_bytes_or_insert_bytes_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - get_by_bytes_or_insert_bytes(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn get_by_bytes_or_insert_bytes_map_file() { - let dir = tempdir().unwrap(); - let path = dir - .path() - .join("generic_wal_get_by_bytes_or_insert_bytes_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - get_by_bytes_or_insert_bytes(&mut wal); -} - -fn zero_reserved(wal: &mut GenericOrderWal) { - unsafe { - assert_eq!(wal.reserved_slice(), &[]); - assert_eq!(wal.reserved_slice_mut(), &mut []); - - let wal = wal.reader(); - assert_eq!(wal.reserved_slice(), &[]); - } -} - -#[test] -fn zero_reserved_inmemory() { - let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); - zero_reserved(&mut wal); -} - -#[test] -fn zero_reserved_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); - zero_reserved(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn zero_reserved_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_zero_reserved_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new(), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - zero_reserved(&mut wal); -} - -fn reserved(wal: &mut GenericOrderWal) { - unsafe { - let buf = wal.reserved_slice_mut(); - buf.copy_from_slice(b"al8n"); - assert_eq!(wal.reserved_slice(), b"al8n"); - assert_eq!(wal.reserved_slice_mut(), b"al8n"); - - let wal = wal.reader(); - assert_eq!(wal.reserved_slice(), b"al8n"); - } -} - -#[test] -fn reserved_inmemory() { - let mut wal = - GenericOrderWal::::new(Options::new().with_capacity(MB).with_reserved(4)) - .unwrap(); - reserved(&mut wal); -} - -#[test] -fn reserved_map_anon() { - let mut wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB).with_reserved(4)) - .unwrap(); - reserved(&mut wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn reserved_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_reserved_map_file"); - - let mut wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new().with_reserved(4), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - reserved(&mut wal); -} - -fn concurrent_basic(mut w: GenericOrderWal) { - let readers = (0..100u32).map(|i| (i, w.reader())).collect::>(); - - let handles = readers.into_iter().map(|(i, reader)| { - spawn(move || loop { - if let Some(p) = reader.get(&i) { - assert_eq!(p.key(), i); - assert_eq!(p.value(), i.to_le_bytes()); - break; - } - }) - }); - - spawn(move || { - for i in 0..100u32 { - w.insert(&i, &i.to_le_bytes()).unwrap(); - } - }); - - for handle in handles { - handle.join().unwrap(); - } -} - -#[test] -fn concurrent_basic_inmemory() { - let wal = GenericOrderWal::::new(Options::new().with_capacity(MB).with_reserved(4)) - .unwrap(); - concurrent_basic(wal); -} - -#[test] -fn concurrent_basic_map_anon() { - let wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB).with_reserved(4)) - .unwrap(); - concurrent_basic(wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn concurrent_basic_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_concurrent_basic_map_file"); - - let wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new().with_reserved(4), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - concurrent_basic(wal); - - let wal = - unsafe { GenericOrderWal::::map(path, Options::new().with_reserved(4)).unwrap() }; - - for i in 0..100u32 { - assert!(wal.contains_key(&i)); - } -} - -fn concurrent_one_key(mut w: GenericOrderWal) { - let readers = (0..100u32).map(|i| (i, w.reader())).collect::>(); - let handles = readers.into_iter().map(|(_, reader)| { - spawn(move || loop { - if let Some(p) = reader.get(&1) { - assert_eq!(p.key(), 1); - assert_eq!(p.value(), 1u32.to_le_bytes()); - break; - } - }) - }); - - w.insert(&1, &1u32.to_le_bytes()).unwrap(); - - for handle in handles { - handle.join().unwrap(); - } -} - -#[test] -fn concurrent_one_key_inmemory() { - let wal = GenericOrderWal::::new(Options::new().with_capacity(MB).with_reserved(4)) - .unwrap(); - concurrent_one_key(wal); -} - -#[test] -fn concurrent_one_key_map_anon() { - let wal = - GenericOrderWal::::map_anon(Options::new().with_capacity(MB).with_reserved(4)) - .unwrap(); - concurrent_one_key(wal); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn concurrent_one_key_map_file() { - let dir = tempdir().unwrap(); - let path = dir.path().join("generic_wal_concurrent_basic_map_file"); - - let wal = unsafe { - GenericOrderWal::::map_mut( - &path, - Options::new().with_reserved(4), - OpenOptions::new() - .create_new(Some(MB)) - .write(true) - .read(true), - ) - .unwrap() - }; - - concurrent_one_key(wal); - - let wal = - unsafe { GenericOrderWal::::map(path, Options::new().with_reserved(4)).unwrap() }; - - assert!(wal.contains_key(&1)); -} diff --git a/src/swmr/generic/tests/constructor.rs b/src/swmr/generic/tests/constructor.rs new file mode 100644 index 0000000..6ddd1b1 --- /dev/null +++ b/src/swmr/generic/tests/constructor.rs @@ -0,0 +1,322 @@ +use super::*; + +#[test] +fn owned_comparable() { + let p1 = Person { + id: 3127022870678870148, + name: "enthusiastic-magic".into(), + }; + let p2 = Person { + id: 9872687799307360216, + name: "damaged-friend".into(), + }; + + let p1bytes = p1.to_vec(); + let p2bytes = p2.to_vec(); + + let ptr1 = Pointer::::new(p1bytes.len(), 0, p1bytes.as_ptr()); + let ptr2 = Pointer::::new(p2bytes.len(), 0, p2bytes.as_ptr()); + + let map = SkipSet::new(); + map.insert(ptr1); + map.insert(ptr2); + + assert!(map.contains(&Owned::new(&p1))); + assert!(map.get(&Owned::new(&p1)).is_some()); + + assert!(map.contains(&Owned::new(&p2))); + assert!(map.get(&Owned::new(&p2)).is_some()); + + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + wal.insert(&p1, &"My name is Alice!".to_string()).unwrap(); + wal.insert(&p2, &"My name is Bob!".to_string()).unwrap(); + + assert!(wal.contains_key(&p1)); + assert_eq!(wal.get(&p1).unwrap().value(), "My name is Alice!"); + + assert!(wal.contains_key(&p2)); + assert_eq!(wal.get(&p2).unwrap().value(), "My name is Bob!"); +} + +#[test] +fn ref_comparable() { + let p1 = PersonRef { + id: 3127022870678870148, + name: "enthusiastic-magic", + }; + let p2 = PersonRef { + id: 9872687799307360216, + name: "damaged-friend", + }; + + let p1bytes = p1.to_vec(); + let p2bytes = p2.to_vec(); + + let ptr1 = Pointer::::new(p1bytes.len(), 0, p1bytes.as_ptr()); + let ptr2 = Pointer::::new(p2bytes.len(), 0, p2bytes.as_ptr()); + + let map = SkipSet::new(); + map.insert(ptr1); + map.insert(ptr2); + + assert!(map.contains(&Owned::new(&p1))); + assert!(map.get(&Owned::new(&p1)).is_some()); + + assert!(map.contains(&Owned::new(&p2))); + assert!(map.get(&Owned::new(&p2)).is_some()); + + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + + unsafe { + wal + .insert_key_bytes_with_value(&p1bytes, &"My name is Alice!".to_string()) + .unwrap(); + wal + .insert_key_bytes_with_value(&p2bytes, &"My name is Bob!".to_string()) + .unwrap(); + } + + assert!(wal.contains_key(&p1)); + assert_eq!(wal.get(&p1).unwrap().value(), "My name is Alice!"); + + assert!(wal.contains_key(&p2)); + assert_eq!(wal.get(&p2).unwrap().value(), "My name is Bob!"); + + assert!(wal.contains_key_by_ref(&p1)); + assert_eq!(wal.get(&p1).unwrap().value(), "My name is Alice!"); + + assert!(wal.contains_key_by_ref(&p2)); + assert_eq!(wal.get(&p2).unwrap().value(), "My name is Bob!"); + + unsafe { + assert!(wal.contains_key_by_bytes(&p1bytes)); + assert_eq!(wal.get(&p1).unwrap().value(), "My name is Alice!"); + + assert!(wal.contains_key_by_bytes(&p2bytes)); + assert_eq!(wal.get(&p2).unwrap().value(), "My name is Bob!"); + } +} + +#[test] +fn construct_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + + let person = Person { + id: 1, + name: "Alice".to_string(), + }; + + assert!(wal.is_empty()); + + wal + .insert(&person, &"My name is Alice!".to_string()) + .unwrap(); + + let wal = wal.reader(); + + assert_eq!(wal.len(), 1); + assert!(!wal.is_empty()); +} + +#[test] +fn construct_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + + let person = Person { + id: 1, + name: "Alice".to_string(), + }; + + wal + .insert(&person, &"My name is Alice!".to_string()) + .unwrap(); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn construct_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_construct_map_file"); + + unsafe { + let mut wal = GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap(); + let person = Person { + id: 1, + name: "Alice".to_string(), + }; + + wal + .insert(&person, &"My name is Alice!".to_string()) + .unwrap(); + assert_eq!(wal.get(&person).unwrap().value(), "My name is Alice!"); + + assert_eq!(*wal.path().unwrap().as_ref(), path); + } + + let pr = PersonRef { + id: 1, + name: "Alice", + }; + + unsafe { + let wal = GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new().create(Some(MB)).write(true).read(true), + ) + .unwrap(); + assert_eq!(wal.get(&pr).unwrap().value(), "My name is Alice!"); + } + + let wal = unsafe { GenericOrderWal::::map(&path, Options::new()).unwrap() }; + assert_eq!(wal.get(&pr).unwrap().value(), "My name is Alice!"); +} + +#[test] +fn construct_with_small_capacity_inmemory() { + let wal = GenericOrderWal::::new(Options::new().with_capacity(1)); + + assert!(wal.is_err()); + match wal { + Err(e) => println!("error: {:?}", e), + _ => panic!("unexpected error"), + } +} + +#[test] +fn construct_with_small_capacity_map_anon() { + let wal = GenericOrderWal::::map_anon(Options::new().with_capacity(1)); + + assert!(wal.is_err()); + match wal { + Err(e) => println!("error: {:?}", e), + _ => panic!("unexpected error"), + } +} + +#[test] +fn construct_with_small_capacity_map_file() { + let dir = tempdir().unwrap(); + let path = dir + .path() + .join("generic_wal_construct_with_small_capacity_map_file"); + + let wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(1)) + .write(true) + .read(true), + ) + }; + + assert!(wal.is_err()); + match wal { + Err(e) => println!("{:?}", e), + _ => panic!("unexpected error"), + } +} + +fn zero_reserved(wal: &mut GenericOrderWal) { + unsafe { + assert_eq!(wal.reserved_slice(), &[]); + assert_eq!(wal.reserved_slice_mut(), &mut []); + + let wal = wal.reader(); + assert_eq!(wal.reserved_slice(), &[]); + } +} + +#[test] +fn zero_reserved_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + zero_reserved(&mut wal); +} + +#[test] +fn zero_reserved_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + zero_reserved(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn zero_reserved_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_zero_reserved_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + zero_reserved(&mut wal); +} + +fn reserved(wal: &mut GenericOrderWal) { + unsafe { + let buf = wal.reserved_slice_mut(); + buf.copy_from_slice(b"al8n"); + assert_eq!(wal.reserved_slice(), b"al8n"); + assert_eq!(wal.reserved_slice_mut(), b"al8n"); + + let wal = wal.reader(); + assert_eq!(wal.reserved_slice(), b"al8n"); + } +} + +#[test] +fn reserved_inmemory() { + let mut wal = + GenericOrderWal::::new(Options::new().with_capacity(MB).with_reserved(4)) + .unwrap(); + reserved(&mut wal); +} + +#[test] +fn reserved_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB).with_reserved(4)) + .unwrap(); + reserved(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn reserved_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_reserved_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new().with_reserved(4), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + reserved(&mut wal); +} diff --git a/src/swmr/generic/tests/get.rs b/src/swmr/generic/tests/get.rs new file mode 100644 index 0000000..c6df958 --- /dev/null +++ b/src/swmr/generic/tests/get.rs @@ -0,0 +1,538 @@ +use super::*; + +fn first(wal: &mut GenericOrderWal) { + let people = (0..10) + .map(|_| { + let p = Person::random(); + let v = format!("My name is {}", p.name); + wal.insert(&p, &v).unwrap(); + + (p, v) + }) + .collect::>(); + + let ent = wal.first().unwrap(); + let (p, v) = people.first_key_value().unwrap(); + assert!(ent.key().equivalent(p)); + assert_eq!(ent.value(), v); + + let wal = wal.reader().clone(); + let ent = wal.first().unwrap(); + let (p, v) = people.first_key_value().unwrap(); + assert!(ent.key().equivalent(p)); + assert_eq!(ent.value(), v); +} + +#[test] +fn first_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + first(&mut wal); +} + +#[test] +fn first_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + first(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn first_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_first_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + first(&mut wal); +} + +fn last(wal: &mut GenericOrderWal) { + let people = (0..10) + .map(|_| { + let p = Person::random(); + let v = format!("My name is {}", p.name); + wal.insert(&p, &v).unwrap(); + + (p, v) + }) + .collect::>(); + + let ent = wal.last().unwrap(); + let (p, v) = people.last_key_value().unwrap(); + assert!(ent.key().equivalent(p)); + assert_eq!(ent.value(), v); + + let wal = wal.reader(); + let ent = wal.last().unwrap(); + assert!(ent.key().equivalent(p)); + assert_eq!(ent.value(), v); +} + +#[test] +fn last_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + last(&mut wal); +} + +#[test] +fn last_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + last(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn last_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_last_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + last(&mut wal); +} + +fn get_or_insert(wal: &mut GenericOrderWal) { + let people = (0..100) + .map(|_| { + let p = Person::random(); + let v = format!("My name is {}", p.name); + wal.get_or_insert(&p, &v).unwrap_right().unwrap(); + (p, v) + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for (p, pv) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + assert_eq!( + wal + .get_or_insert(p, &format!("Hello! {}!", p.name)) + .unwrap_left() + .value(), + pv + ); + } + + for (p, _) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + } +} + +#[test] +fn get_or_insert_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + get_or_insert(&mut wal); +} + +#[test] +fn get_or_insert_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + get_or_insert(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn get_or_insert_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_get_or_insert_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + get_or_insert(&mut wal); +} + +fn get_or_insert_with(wal: &mut GenericOrderWal) { + let people = (0..100) + .map(|_| { + let p = Person::random(); + let v = format!("My name is {}", p.name); + wal + .get_or_insert_with(&p, || v.clone()) + .unwrap_right() + .unwrap(); + (p, v) + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for (p, pv) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + assert_eq!( + wal + .get_or_insert_with(p, || format!("Hello! {}!", p.name)) + .unwrap_left() + .value(), + pv + ); + } + + for (p, _) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + } +} + +#[test] +fn get_or_insert_with_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + get_or_insert_with(&mut wal); +} + +#[test] +fn get_or_insert_with_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + get_or_insert_with(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn get_or_insert_with_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_get_or_insert_with_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + get_or_insert_with(&mut wal); +} + +fn get_or_insert_key_with_value_bytes(wal: &mut GenericOrderWal) { + let people = (0..100) + .map(|_| { + let p = Person::random(); + let pvec = p.to_vec(); + let v = format!("My name is {}", p.name); + unsafe { + wal + .get_by_bytes_or_insert(pvec.as_ref(), &v) + .unwrap_right() + .unwrap(); + } + (p, v) + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for (p, pv) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + assert_eq!( + wal + .get_or_insert(p, &format!("Hello! {}!", p.name)) + .unwrap_left() + .value(), + pv + ); + } + + for (p, _) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + } +} + +#[test] +fn get_or_insert_key_with_value_bytes_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + get_or_insert_key_with_value_bytes(&mut wal); +} + +#[test] +fn get_or_insert_key_with_value_bytes_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + get_or_insert_key_with_value_bytes(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn get_or_insert_key_with_value_bytes_map_file() { + let dir = tempdir().unwrap(); + let path = dir + .path() + .join("generic_wal_get_or_insert_key_with_value_bytes_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + get_or_insert_key_with_value_bytes(&mut wal); +} + +fn get_or_insert_value_bytes(wal: &mut GenericOrderWal) { + let people = (0..100) + .map(|_| { + let p = Person::random(); + let v = format!("My name is {}", p.name); + unsafe { + wal + .get_or_insert_bytes(&p, v.as_bytes()) + .unwrap_right() + .unwrap(); + } + (p, v) + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for (p, pv) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + unsafe { + assert_eq!( + wal + .get_or_insert_bytes(p, pv.as_bytes()) + .unwrap_left() + .value(), + pv + ); + } + } + + for (p, _) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + } +} + +#[test] +fn get_or_insert_value_bytes_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + get_or_insert_value_bytes(&mut wal); +} + +#[test] +fn get_or_insert_value_bytes_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + get_or_insert_value_bytes(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn get_or_insert_value_bytes_map_file() { + let dir = tempdir().unwrap(); + let path = dir + .path() + .join("generic_wal_get_or_insert_value_bytes_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + get_or_insert_value_bytes(&mut wal); +} + +fn get_by_bytes_or_insert_with(wal: &mut GenericOrderWal) { + let people = (0..100) + .map(|_| { + let p = Person::random(); + let pvec = p.to_vec(); + let v = format!("My name is {}", p.name); + unsafe { + wal + .get_by_bytes_or_insert_with(pvec.as_ref(), || v.clone()) + .unwrap_right() + .unwrap(); + } + (p, pvec, v) + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for (p, pvec, pv) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + unsafe { + assert_eq!( + wal + .get_by_bytes_or_insert_with(pvec, || format!("Hello! {}!", p.name)) + .unwrap_left() + .value(), + pv + ); + } + } + + for (p, _, _) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + } +} + +#[test] +fn get_by_bytes_or_insert_with_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + get_by_bytes_or_insert_with(&mut wal); +} + +#[test] +fn get_by_bytes_or_insert_with_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + get_by_bytes_or_insert_with(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn get_by_bytes_or_insert_with_map_file() { + let dir = tempdir().unwrap(); + let path = dir + .path() + .join("generic_wal_get_by_bytes_or_insert_with_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + get_by_bytes_or_insert_with(&mut wal); +} + +fn get_by_bytes_or_insert_bytes(wal: &mut GenericOrderWal) { + let people = (0..100) + .map(|_| { + let p = Person::random(); + let pvec = p.to_vec(); + let v = format!("My name is {}", p.name); + unsafe { + wal + .get_by_bytes_or_insert_bytes(pvec.as_ref(), v.as_bytes()) + .unwrap_right() + .unwrap(); + } + (p, pvec, v) + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for (p, pvec, pv) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + unsafe { + assert_eq!( + wal + .get_by_bytes_or_insert_bytes(pvec, pv.as_bytes()) + .unwrap_left() + .value(), + pv + ); + } + } + + for (p, _, _) in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + } +} + +#[test] +fn get_by_bytes_or_insert_bytes_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + get_by_bytes_or_insert_bytes(&mut wal); +} + +#[test] +fn get_by_bytes_or_insert_bytes_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + get_by_bytes_or_insert_bytes(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn get_by_bytes_or_insert_bytes_map_file() { + let dir = tempdir().unwrap(); + let path = dir + .path() + .join("generic_wal_get_by_bytes_or_insert_bytes_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + get_by_bytes_or_insert_bytes(&mut wal); +} diff --git a/src/swmr/generic/tests/insert.rs b/src/swmr/generic/tests/insert.rs new file mode 100644 index 0000000..ced2c1d --- /dev/null +++ b/src/swmr/generic/tests/insert.rs @@ -0,0 +1,502 @@ +use super::*; + +fn insert_to_full(wal: &mut GenericOrderWal) { + let mut full = false; + for _ in 0u32.. { + let p = Person::random(); + match wal.insert(&p, &format!("My name is {}", p.name)) { + Ok(_) => {} + Err(e) => match e { + Among::Right(Error::InsufficientSpace { .. }) => { + full = true; + break; + } + _ => panic!("unexpected error"), + }, + } + } + assert!(full); +} + +#[test] +fn insert_to_full_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + insert_to_full(&mut wal); +} + +#[test] +fn insert_to_full_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + insert_to_full(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn insert_to_full_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_insert_to_full_map_file"); + + unsafe { + let mut wal = GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap(); + insert_to_full(&mut wal); + } +} + +fn insert(wal: &mut GenericOrderWal) -> Vec { + let people = (0..100) + .map(|_| { + let p = Person::random(); + wal.insert(&p, &format!("My name is {}", p.name)).unwrap(); + p + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for p in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + assert_eq!( + wal.get(p).unwrap().value(), + format!("My name is {}", p.name) + ); + } + + people +} + +#[test] +fn insert_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + insert(&mut wal); +} + +#[test] +fn insert_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + insert(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn insert_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_insert_map_file"); + + let people = unsafe { + let mut wal = GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap(); + insert(&mut wal) + }; + + let wal = unsafe { GenericOrderWal::::map(&path, Options::new()).unwrap() }; + + for p in people { + assert!(wal.contains_key(&p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + assert_eq!( + wal.get(&p).unwrap().value(), + format!("My name is {}", p.name) + ); + } +} + +fn insert_key_bytes_with_value( + wal: &mut GenericOrderWal, +) -> Vec<(Vec, Person)> { + let people = (0..100) + .map(|_| { + let p = Person::random(); + let pbytes = p.to_vec(); + unsafe { + wal + .insert_key_bytes_with_value(&pbytes, &format!("My name is {}", p.name)) + .unwrap(); + } + (pbytes, p) + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for (pbytes, p) in &people { + assert!(wal.contains_key(p)); + unsafe { + assert!(wal.contains_key_by_bytes(pbytes)); + } + assert_eq!( + wal.get(p).unwrap().value(), + format!("My name is {}", p.name) + ); + + assert_eq!( + unsafe { wal.get_by_bytes(pbytes).unwrap().value() }, + format!("My name is {}", p.name) + ); + } + + people +} + +#[test] +fn insert_key_bytes_with_value_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + insert_key_bytes_with_value(&mut wal); +} + +#[test] +fn insert_key_bytes_with_value_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + insert_key_bytes_with_value(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn insert_key_bytes_with_value_map_file() { + let dir = tempdir().unwrap(); + let path = dir + .path() + .join("generic_wal_insert_key_bytes_with_value_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + let people = insert_key_bytes_with_value(&mut wal); + + let wal = wal.reader(); + + for (pbytes, p) in &people { + assert!(wal.contains_key(p)); + unsafe { + assert!(wal.contains_key_by_bytes(pbytes)); + } + assert_eq!( + wal.get(p).unwrap().value(), + format!("My name is {}", p.name) + ); + assert_eq!( + unsafe { wal.get_by_bytes(pbytes).unwrap().value() }, + format!("My name is {}", p.name) + ); + } + + let wal = unsafe { GenericOrderWal::::map(&path, Options::new()).unwrap() }; + + for (pbytes, p) in people { + assert!(wal.contains_key(&p)); + unsafe { + assert!(wal.contains_key_by_bytes(&pbytes)); + } + assert_eq!( + wal.get(&p).unwrap().value(), + format!("My name is {}", p.name) + ); + assert_eq!( + unsafe { wal.get_by_bytes(&pbytes).unwrap().value() }, + format!("My name is {}", p.name) + ); + } +} + +fn insert_key_with_value_bytes(wal: &mut GenericOrderWal) -> Vec { + let people = (0..100) + .map(|_| { + let p = Person::random(); + unsafe { + wal + .insert_key_with_value_bytes(&p, format!("My name is {}", p.name).as_bytes()) + .unwrap(); + } + p + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for p in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + assert_eq!( + wal.get_by_ref(p).unwrap().value(), + format!("My name is {}", p.name) + ); + } + + people +} + +#[test] +fn insert_key_with_value_bytes_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + insert_key_with_value_bytes(&mut wal); +} + +#[test] +fn insert_key_with_value_bytes_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + insert_key_with_value_bytes(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn insert_key_with_value_bytes_map_file() { + let dir = tempdir().unwrap(); + let path = dir + .path() + .join("generic_wal_insert_key_with_value_bytes_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + let people = insert_key_with_value_bytes(&mut wal); + let wal = wal.reader(); + + for p in &people { + assert!(wal.contains_key(p)); + assert!(wal.contains_key_by_ref(&p.as_ref())); + assert_eq!( + wal.get_by_ref(p).unwrap().value(), + format!("My name is {}", p.name) + ); + } +} + +fn insert_bytes(wal: &mut GenericOrderWal) -> Vec { + let people = (0..100) + .map(|_| { + let p = Person::random(); + let pbytes = p.to_vec(); + unsafe { + wal + .insert_bytes(&pbytes, format!("My name is {}", p.name).as_bytes()) + .unwrap(); + } + p + }) + .collect::>(); + + assert_eq!(wal.len(), 100); + + for p in &people { + assert!(wal.contains_key(p)); + unsafe { + assert!(wal.contains_key_by_bytes(&p.to_vec())); + } + assert_eq!( + wal.get(p).unwrap().value(), + format!("My name is {}", p.name) + ); + } + + people +} + +#[test] +fn insert_bytes_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + insert_bytes(&mut wal); +} + +#[test] +fn insert_bytes_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + insert_bytes(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn insert_bytes_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_insert_bytes_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + let people = insert_bytes(&mut wal); + + let wal = wal.reader(); + + for p in &people { + assert!(wal.contains_key(p)); + unsafe { + assert!(wal.contains_key_by_bytes(&p.to_vec())); + } + assert_eq!( + wal.get(p).unwrap().value(), + format!("My name is {}", p.name) + ); + } +} + +fn concurrent_basic(mut w: GenericOrderWal) { + let readers = (0..100u32).map(|i| (i, w.reader())).collect::>(); + + let handles = readers.into_iter().map(|(i, reader)| { + spawn(move || loop { + if let Some(p) = reader.get(&i) { + assert_eq!(p.key(), i); + assert_eq!(p.value(), i.to_le_bytes()); + break; + } + }) + }); + + spawn(move || { + for i in 0..100u32 { + w.insert(&i, &i.to_le_bytes()).unwrap(); + } + }); + + for handle in handles { + handle.join().unwrap(); + } +} + +#[test] +fn concurrent_basic_inmemory() { + let wal = GenericOrderWal::::new(Options::new().with_capacity(MB).with_reserved(4)) + .unwrap(); + concurrent_basic(wal); +} + +#[test] +fn concurrent_basic_map_anon() { + let wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB).with_reserved(4)) + .unwrap(); + concurrent_basic(wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn concurrent_basic_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_concurrent_basic_map_file"); + + let wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new().with_reserved(4), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + concurrent_basic(wal); + + let wal = + unsafe { GenericOrderWal::::map(path, Options::new().with_reserved(4)).unwrap() }; + + for i in 0..100u32 { + assert!(wal.contains_key(&i)); + } +} + +fn concurrent_one_key(mut w: GenericOrderWal) { + let readers = (0..100u32).map(|i| (i, w.reader())).collect::>(); + let handles = readers.into_iter().map(|(_, reader)| { + spawn(move || loop { + if let Some(p) = reader.get(&1) { + assert_eq!(p.key(), 1); + assert_eq!(p.value(), 1u32.to_le_bytes()); + break; + } + }) + }); + + w.insert(&1, &1u32.to_le_bytes()).unwrap(); + + for handle in handles { + handle.join().unwrap(); + } +} + +#[test] +fn concurrent_one_key_inmemory() { + let wal = GenericOrderWal::::new(Options::new().with_capacity(MB).with_reserved(4)) + .unwrap(); + concurrent_one_key(wal); +} + +#[test] +fn concurrent_one_key_map_anon() { + let wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB).with_reserved(4)) + .unwrap(); + concurrent_one_key(wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn concurrent_one_key_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_concurrent_basic_map_file"); + + let wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new().with_reserved(4), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + concurrent_one_key(wal); + + let wal = + unsafe { GenericOrderWal::::map(path, Options::new().with_reserved(4)).unwrap() }; + + assert!(wal.contains_key(&1)); +} diff --git a/src/swmr/generic/tests/iters.rs b/src/swmr/generic/tests/iters.rs new file mode 100644 index 0000000..3370236 --- /dev/null +++ b/src/swmr/generic/tests/iters.rs @@ -0,0 +1,223 @@ +use super::*; + +fn iter(wal: &mut GenericOrderWal) -> Vec<(Person, String)> { + let mut people = (0..100) + .map(|_| { + let p = Person::random(); + let v = format!("My name is {}", p.name); + wal.insert(&p, &v).unwrap(); + (p, v) + }) + .collect::>(); + + people.sort_by(|a, b| a.0.cmp(&b.0)); + + let mut iter = wal.iter(); + + for (pwal, pvec) in people.iter().zip(iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } + + let mut rev_iter = wal.iter().rev(); + + for (pwal, pvec) in people.iter().rev().zip(rev_iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } + + people +} + +#[test] +fn iter_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + iter(&mut wal); +} + +#[test] +fn iter_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + iter(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn iter_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_iter_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + let people = iter(&mut wal); + + let wal = wal.reader(); + let mut iter = wal.iter(); + + for (pwal, pvec) in people.iter().zip(iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } +} + +fn range(wal: &mut GenericOrderWal) { + let mut mid = Person::random(); + let people = (0..100) + .map(|idx| { + let p = Person::random(); + let v = format!("My name is {}", p.name); + wal.insert(&p, &v).unwrap(); + + if idx == 500 { + mid = p.clone(); + } + (p, v) + }) + .collect::>(); + + let mut iter = wal.range(Bound::Included(&mid), Bound::Unbounded); + + for (pwal, pvec) in people.range(&mid..).zip(iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } + + assert!(iter.next().is_none()); + + let wal = wal.reader(); + let mut iter = wal.range(Bound::Included(&mid), Bound::Unbounded); + + for (pwal, pvec) in people.range(&mid..).zip(iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } + + let mut rev_iter = wal.range(Bound::Included(&mid), Bound::Unbounded).rev(); + + for (pwal, pvec) in people.range(&mid..).rev().zip(rev_iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } +} + +#[test] +fn range_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + range(&mut wal); +} + +#[test] +fn range_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + range(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn range_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_range_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + range(&mut wal); +} + +fn range_ref(wal: &mut GenericOrderWal) { + let mut mid = Person::random(); + let people = (0..100) + .map(|idx| { + let p = Person::random(); + let v = format!("My name is {}", p.name); + wal.insert(&p, &v).unwrap(); + + if idx == 500 { + mid = p.clone(); + } + (p, v) + }) + .collect::>(); + + let mid_ref = mid.as_ref(); + let mut iter = wal.range_by_ref(Bound::Included(&mid_ref), Bound::Unbounded); + + for (pwal, pvec) in people.range(&mid..).zip(iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } + + assert!(iter.next().is_none()); + + let wal = wal.reader(); + let mut iter = wal.range_by_ref(Bound::Included(&mid), Bound::Unbounded); + + for (pwal, pvec) in people.range(&mid..).zip(iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } + + let mut rev_iter = wal + .range_by_ref(Bound::Included(&mid), Bound::Unbounded) + .rev(); + + for (pwal, pvec) in people.range(&mid..).rev().zip(rev_iter.by_ref()) { + assert!(pwal.0.equivalent(&pvec.key())); + assert_eq!(pwal.1, pvec.value()); + } +} + +#[test] +fn range_ref_inmemory() { + let mut wal = GenericOrderWal::::new(Options::new().with_capacity(MB)).unwrap(); + range(&mut wal); +} + +#[test] +fn range_ref_map_anon() { + let mut wal = + GenericOrderWal::::map_anon(Options::new().with_capacity(MB)).unwrap(); + range_ref(&mut wal); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn range_ref_map_file() { + let dir = tempdir().unwrap(); + let path = dir.path().join("generic_wal_range_map_file"); + + let mut wal = unsafe { + GenericOrderWal::::map_mut( + &path, + Options::new(), + OpenOptions::new() + .create_new(Some(MB)) + .write(true) + .read(true), + ) + .unwrap() + }; + + range_ref(&mut wal); +} diff --git a/src/swmr/wal.rs b/src/swmr/wal.rs index b0b10e0..2ea8ba1 100644 --- a/src/swmr/wal.rs +++ b/src/swmr/wal.rs @@ -18,7 +18,7 @@ pub use reader::*; mod iter; pub use iter::*; -#[cfg(all(test, feature = "test-swmr"))] +#[cfg(test)] mod tests; pub struct OrderWalCore { diff --git a/src/swmr/wal/tests.rs b/src/swmr/wal/tests.rs index ee8b5ca..ac8c4f6 100644 --- a/src/swmr/wal/tests.rs +++ b/src/swmr/wal/tests.rs @@ -4,6 +4,16 @@ use crate::tests::*; use super::*; -const MB: u32 = 1024 * 1024; +#[cfg(all(test, feature = "test-swmr-constructor"))] +mod constructor; + +#[cfg(all(test, feature = "test-swmr-insert"))] +mod insert; + +#[cfg(all(test, feature = "test-swmr-iters"))] +mod iter; -common_unittests!(swmr::OrderWal); +#[cfg(all(test, feature = "test-swmr-get"))] +mod get; + +const MB: u32 = 1024 * 1024; diff --git a/src/swmr/wal/tests/constructor.rs b/src/swmr/wal/tests/constructor.rs new file mode 100644 index 0000000..03e864a --- /dev/null +++ b/src/swmr/wal/tests/constructor.rs @@ -0,0 +1,3 @@ +use super::*; + +common_unittests!(unsync::constructor::OrderWal); diff --git a/src/swmr/wal/tests/get.rs b/src/swmr/wal/tests/get.rs new file mode 100644 index 0000000..c9eefcf --- /dev/null +++ b/src/swmr/wal/tests/get.rs @@ -0,0 +1,3 @@ +use super::*; + +common_unittests!(unsync::get::OrderWal); diff --git a/src/swmr/wal/tests/insert.rs b/src/swmr/wal/tests/insert.rs new file mode 100644 index 0000000..6aacd45 --- /dev/null +++ b/src/swmr/wal/tests/insert.rs @@ -0,0 +1,3 @@ +use super::*; + +common_unittests!(unsync::insert::OrderWal); diff --git a/src/swmr/wal/tests/iter.rs b/src/swmr/wal/tests/iter.rs new file mode 100644 index 0000000..f20d78e --- /dev/null +++ b/src/swmr/wal/tests/iter.rs @@ -0,0 +1,3 @@ +use super::*; + +common_unittests!(unsync::iters::OrderWal); diff --git a/src/tests.rs b/src/tests.rs index 424dee3..cdd419b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -7,40 +7,8 @@ use wal::ImmutableWal; const MB: usize = 1024 * 1024; macro_rules! common_unittests { - ($prefix:ident::$wal:ident) => { + ($prefix:ident::insert::$wal:ident) => { paste::paste! { - #[test] - fn test_construct_inmemory() { - construct_inmemory::>(); - } - - #[test] - fn test_construct_map_anon() { - construct_map_anon::>(); - } - - #[test] - #[cfg_attr(miri, ignore)] - fn test_construct_map_file() { - construct_map_file::>(stringify!($prefix)); - } - - #[test] - fn test_construct_with_small_capacity_inmemory() { - construct_with_small_capacity_inmemory::>(); - } - - #[test] - fn test_construct_with_small_capacity_map_anon() { - construct_with_small_capacity_map_anon::>(); - } - - #[test] - #[cfg_attr(miri, ignore)] - fn test_construct_with_small_capacity_map_file() { - construct_with_small_capacity_map_file::>(stringify!($prefix)); - } - #[test] fn test_insert_to_full_inmemory() { insert_to_full(&mut OrderWal::new(Builder::new().with_capacity(MB)).unwrap()); @@ -175,7 +143,10 @@ macro_rules! common_unittests { .unwrap() }, ); } - + } + }; + ($prefix:ident::iters::$wal:ident) => { + paste::paste! { #[test] fn test_iter_inmemory() { iter(&mut OrderWal::new(Builder::new().with_capacity(MB)).unwrap()); @@ -337,7 +308,10 @@ macro_rules! common_unittests { .unwrap() }, ); } - + } + }; + ($prefix:ident::get::$wal:ident) => { + paste::paste! { #[test] fn test_first_inmemory() { first(&mut OrderWal::new(Builder::new().with_capacity(MB)).unwrap()); @@ -456,6 +430,41 @@ macro_rules! common_unittests { assert_eq!(wal.path().unwrap(), path); } + } + }; + ($prefix:ident::constructor::$wal:ident) => { + paste::paste! { + #[test] + fn test_construct_inmemory() { + construct_inmemory::>(); + } + + #[test] + fn test_construct_map_anon() { + construct_map_anon::>(); + } + + #[test] + #[cfg_attr(miri, ignore)] + fn test_construct_map_file() { + construct_map_file::>(stringify!($prefix)); + } + + #[test] + fn test_construct_with_small_capacity_inmemory() { + construct_with_small_capacity_inmemory::>(); + } + + #[test] + fn test_construct_with_small_capacity_map_anon() { + construct_with_small_capacity_map_anon::>(); + } + + #[test] + #[cfg_attr(miri, ignore)] + fn test_construct_with_small_capacity_map_file() { + construct_with_small_capacity_map_file::>(stringify!($prefix)); + } #[test] fn test_zero_reserved_inmemory() { diff --git a/src/unsync.rs b/src/unsync.rs index a05fa6b..5c80ae7 100644 --- a/src/unsync.rs +++ b/src/unsync.rs @@ -19,7 +19,7 @@ use iter::*; mod c; use c::*; -#[cfg(all(test, feature = "test-unsync"))] +#[cfg(test)] mod tests; /// An ordered write-ahead log implementation for single thread environments. diff --git a/src/unsync/tests.rs b/src/unsync/tests.rs index ee41973..96d3aba 100644 --- a/src/unsync/tests.rs +++ b/src/unsync/tests.rs @@ -4,6 +4,16 @@ use crate::tests::*; use super::*; -const MB: u32 = 1024 * 1024; +#[cfg(all(test, feature = "test-unsync-constructor"))] +mod constructor; + +#[cfg(all(test, feature = "test-unsync-insert"))] +mod insert; + +#[cfg(all(test, feature = "test-unsync-iters"))] +mod iter; -common_unittests!(unsync::OrderWal); +#[cfg(all(test, feature = "test-unsync-get"))] +mod get; + +const MB: u32 = 1024 * 1024; diff --git a/src/unsync/tests/constructor.rs b/src/unsync/tests/constructor.rs new file mode 100644 index 0000000..03e864a --- /dev/null +++ b/src/unsync/tests/constructor.rs @@ -0,0 +1,3 @@ +use super::*; + +common_unittests!(unsync::constructor::OrderWal); diff --git a/src/unsync/tests/get.rs b/src/unsync/tests/get.rs new file mode 100644 index 0000000..c9eefcf --- /dev/null +++ b/src/unsync/tests/get.rs @@ -0,0 +1,3 @@ +use super::*; + +common_unittests!(unsync::get::OrderWal); diff --git a/src/unsync/tests/insert.rs b/src/unsync/tests/insert.rs new file mode 100644 index 0000000..6aacd45 --- /dev/null +++ b/src/unsync/tests/insert.rs @@ -0,0 +1,3 @@ +use super::*; + +common_unittests!(unsync::insert::OrderWal); diff --git a/src/unsync/tests/iter.rs b/src/unsync/tests/iter.rs new file mode 100644 index 0000000..f20d78e --- /dev/null +++ b/src/unsync/tests/iter.rs @@ -0,0 +1,3 @@ +use super::*; + +common_unittests!(unsync::iters::OrderWal);