diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5ea0c80d..c88deda8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -217,68 +217,58 @@ jobs:
         run: ci/sanitizer_generic.sh
         if: matrix.os != 'ubuntu-latest'
 
-  miri-tb-unsync:
-    name: miri-tb-unsync
-    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_unsync.sh
-        if: matrix.os == 'ubuntu-latest'
+  # miri-tb-unsync:
+  #   name: miri-tb-unsync
+  #   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_unsync.sh
+  #       if: matrix.os == 'ubuntu-latest'
 
-  miri-tb-swmr:
-    name: miri-tb-swmr
-    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.sh
-        if: matrix.os == 'ubuntu-latest'
-  
-  miri-tb-swmr-generic:
-    name: miri-tb-swmr-generic
+  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
@@ -295,7 +285,8 @@ jobs:
       - name: Install cargo-hack
         run: cargo install cargo-hack
       - name: Miri (Linux)
-        run: ci/miri_tb_swmr_generic.sh
+        run: |
+          bash ci/miri_tb_swmr.sh ${{ matrix.target }} ${{ matrix.features }}
         if: matrix.os == 'ubuntu-latest'
 
   # miri-sb:
diff --git a/Cargo.toml b/Cargo.toml
index 3dab90e9..515871a7 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 5a6c4c22..22095def 100755
--- a/ci/miri_tb.sh
+++ b/ci/miri_tb.sh
@@ -1,13 +1,30 @@
 #!/bin/bash
 set -e
 
+# Check if TARGET and FEATURES are provided, otherwise panic
+if [ -z "$1" ]; then
+  echo "Error: TARGET is not provided"
+  exit 1
+fi
+
+if [ -z "$2" ]; then
+  echo "Error: FEATURES are not provided"
+  exit 1
+fi
+
+TARGET=$1
+FEATURES=$2
+
 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 --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 6e6c9013..00000000
--- 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 4196fbbd..00000000
--- 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 770c91d6..00000000
--- 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 8a485ad1..00000000
--- 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 a6a5ae2f..e04cbba2 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::<u16>();
 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 b5891220..4d97a137 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 8cf51b03..4836cb4d 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::<Person, String>::new(p1bytes.len(), 0, p1bytes.as_ptr());
-  let ptr2 = Pointer::<Person, String>::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::<Person, String>::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::<Person, String>::new(p1bytes.len(), 0, p1bytes.as_ptr());
-  let ptr2 = Pointer::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  insert_to_full(&mut wal);
-}
-
-#[test]
-fn insert_to_full_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) -> Vec<Person> {
-  let people = (0..100)
-    .map(|_| {
-      let p = Person::random();
-      wal.insert(&p, &format!("My name is {}", p.name)).unwrap();
-      p
-    })
-    .collect::<Vec<_>>();
-
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  insert(&mut wal);
-}
-
-#[test]
-fn insert_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::map_mut(
-      &path,
-      Options::new(),
-      OpenOptions::new()
-        .create_new(Some(MB))
-        .write(true)
-        .read(true),
-    )
-    .unwrap();
-    insert(&mut wal)
-  };
-
-  let wal = unsafe { GenericOrderWal::<Person, String>::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<Person, String>,
-) -> Vec<(Vec<u8>, 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::<Vec<_>>();
-
-  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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) -> Vec<Person> {
-  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::<Vec<_>>();
-
-  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) -> Vec<Person> {
-  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::<Vec<_>>();
-
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  insert_bytes(&mut wal);
-}
-
-#[test]
-fn insert_bytes_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) -> 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::<Vec<_>>();
-
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  iter(&mut wal);
-}
-
-#[test]
-fn iter_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<BTreeMap<_, _>>();
-
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  range(&mut wal);
-}
-
-#[test]
-fn range_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<BTreeMap<_, _>>();
-
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  range(&mut wal);
-}
-
-#[test]
-fn range_ref_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<BTreeMap<_, _>>();
-
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  first(&mut wal);
-}
-
-#[test]
-fn first_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::map_mut(
-      &path,
-      Options::new(),
-      OpenOptions::new()
-        .create_new(Some(MB))
-        .write(true)
-        .read(true),
-    )
-    .unwrap()
-  };
-
-  first(&mut wal);
-}
-
-fn last(wal: &mut GenericOrderWal<Person, String>) {
-  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::<BTreeMap<_, _>>();
-
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  last(&mut wal);
-}
-
-#[test]
-fn last_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Vec<_>>();
-
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  get_or_insert(&mut wal);
-}
-
-#[test]
-fn get_or_insert_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Vec<_>>();
-
-  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Vec<_>>();
-
-  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Vec<_>>();
-
-  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Vec<_>>();
-
-  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Vec<_>>();
-
-  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
-  zero_reserved(&mut wal);
-}
-
-#[test]
-fn zero_reserved_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
-  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::<Person, String>::new(Options::new().with_capacity(MB).with_reserved(4))
-      .unwrap();
-  reserved(&mut wal);
-}
-
-#[test]
-fn reserved_map_anon() {
-  let mut wal =
-    GenericOrderWal::<Person, String>::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::<Person, String>::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<u32, [u8; 4]>) {
-  let readers = (0..100u32).map(|i| (i, w.reader())).collect::<Vec<_>>();
-
-  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::<u32, [u8; 4]>::new(Options::new().with_capacity(MB).with_reserved(4))
-    .unwrap();
-  concurrent_basic(wal);
-}
-
-#[test]
-fn concurrent_basic_map_anon() {
-  let wal =
-    GenericOrderWal::<u32, [u8; 4]>::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::<u32, [u8; 4]>::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::<u32, [u8; 4]>::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<u32, [u8; 4]>) {
-  let readers = (0..100u32).map(|i| (i, w.reader())).collect::<Vec<_>>();
-  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::<u32, [u8; 4]>::new(Options::new().with_capacity(MB).with_reserved(4))
-    .unwrap();
-  concurrent_one_key(wal);
-}
-
-#[test]
-fn concurrent_one_key_map_anon() {
-  let wal =
-    GenericOrderWal::<u32, [u8; 4]>::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::<u32, [u8; 4]>::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::<u32, [u8; 4]>::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 00000000..6ddd1b1c
--- /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::<Person, String>::new(p1bytes.len(), 0, p1bytes.as_ptr());
+  let ptr2 = Pointer::<Person, String>::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::<Person, String>::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::<Person, String>::new(p1bytes.len(), 0, p1bytes.as_ptr());
+  let ptr2 = Pointer::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  zero_reserved(&mut wal);
+}
+
+#[test]
+fn zero_reserved_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<Person, String>::new(Options::new().with_capacity(MB).with_reserved(4))
+      .unwrap();
+  reserved(&mut wal);
+}
+
+#[test]
+fn reserved_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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 00000000..c6df9581
--- /dev/null
+++ b/src/swmr/generic/tests/get.rs
@@ -0,0 +1,538 @@
+use super::*;
+
+fn first(wal: &mut GenericOrderWal<Person, String>) {
+  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::<BTreeMap<_, _>>();
+
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  first(&mut wal);
+}
+
+#[test]
+fn first_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::map_mut(
+      &path,
+      Options::new(),
+      OpenOptions::new()
+        .create_new(Some(MB))
+        .write(true)
+        .read(true),
+    )
+    .unwrap()
+  };
+
+  first(&mut wal);
+}
+
+fn last(wal: &mut GenericOrderWal<Person, String>) {
+  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::<BTreeMap<_, _>>();
+
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  last(&mut wal);
+}
+
+#[test]
+fn last_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<Vec<_>>();
+
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  get_or_insert(&mut wal);
+}
+
+#[test]
+fn get_or_insert_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<Vec<_>>();
+
+  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<Vec<_>>();
+
+  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<Vec<_>>();
+
+  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<Vec<_>>();
+
+  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<Vec<_>>();
+
+  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::<Person, String>::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::<Person, String>::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::<Person, String>::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 00000000..ced2c1d6
--- /dev/null
+++ b/src/swmr/generic/tests/insert.rs
@@ -0,0 +1,502 @@
+use super::*;
+
+fn insert_to_full(wal: &mut GenericOrderWal<Person, String>) {
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  insert_to_full(&mut wal);
+}
+
+#[test]
+fn insert_to_full_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) -> Vec<Person> {
+  let people = (0..100)
+    .map(|_| {
+      let p = Person::random();
+      wal.insert(&p, &format!("My name is {}", p.name)).unwrap();
+      p
+    })
+    .collect::<Vec<_>>();
+
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  insert(&mut wal);
+}
+
+#[test]
+fn insert_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::map_mut(
+      &path,
+      Options::new(),
+      OpenOptions::new()
+        .create_new(Some(MB))
+        .write(true)
+        .read(true),
+    )
+    .unwrap();
+    insert(&mut wal)
+  };
+
+  let wal = unsafe { GenericOrderWal::<Person, String>::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<Person, String>,
+) -> Vec<(Vec<u8>, 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::<Vec<_>>();
+
+  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::<Person, String>::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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) -> Vec<Person> {
+  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::<Vec<_>>();
+
+  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::<Person, String>::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::<Person, String>::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::<Person, String>::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<Person, String>) -> Vec<Person> {
+  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::<Vec<_>>();
+
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  insert_bytes(&mut wal);
+}
+
+#[test]
+fn insert_bytes_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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<u32, [u8; 4]>) {
+  let readers = (0..100u32).map(|i| (i, w.reader())).collect::<Vec<_>>();
+
+  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::<u32, [u8; 4]>::new(Options::new().with_capacity(MB).with_reserved(4))
+    .unwrap();
+  concurrent_basic(wal);
+}
+
+#[test]
+fn concurrent_basic_map_anon() {
+  let wal =
+    GenericOrderWal::<u32, [u8; 4]>::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::<u32, [u8; 4]>::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::<u32, [u8; 4]>::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<u32, [u8; 4]>) {
+  let readers = (0..100u32).map(|i| (i, w.reader())).collect::<Vec<_>>();
+  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::<u32, [u8; 4]>::new(Options::new().with_capacity(MB).with_reserved(4))
+    .unwrap();
+  concurrent_one_key(wal);
+}
+
+#[test]
+fn concurrent_one_key_map_anon() {
+  let wal =
+    GenericOrderWal::<u32, [u8; 4]>::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::<u32, [u8; 4]>::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::<u32, [u8; 4]>::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 00000000..33702369
--- /dev/null
+++ b/src/swmr/generic/tests/iters.rs
@@ -0,0 +1,223 @@
+use super::*;
+
+fn iter(wal: &mut GenericOrderWal<Person, String>) -> 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::<Vec<_>>();
+
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  iter(&mut wal);
+}
+
+#[test]
+fn iter_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<BTreeMap<_, _>>();
+
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  range(&mut wal);
+}
+
+#[test]
+fn range_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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<Person, String>) {
+  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::<BTreeMap<_, _>>();
+
+  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::<Person, String>::new(Options::new().with_capacity(MB)).unwrap();
+  range(&mut wal);
+}
+
+#[test]
+fn range_ref_map_anon() {
+  let mut wal =
+    GenericOrderWal::<Person, String>::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::<Person, String>::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 b0b10e06..2ea8ba1b 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<C, S> {
diff --git a/src/swmr/wal/tests.rs b/src/swmr/wal/tests.rs
index ee8b5ca0..ac8c4f63 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 00000000..03e864a3
--- /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 00000000..c9eefcf8
--- /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 00000000..6aacd454
--- /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 00000000..f20d78e8
--- /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 424dee32..cdd419b2 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::<OrderWal<Ascend, Crc32>>();
-      }
-
-      #[test]
-      fn test_construct_map_anon() {
-        construct_map_anon::<OrderWal<Ascend, Crc32>>();
-      }
-
-      #[test]
-      #[cfg_attr(miri, ignore)]
-      fn test_construct_map_file() {
-        construct_map_file::<OrderWal<Ascend, Crc32>>(stringify!($prefix));
-      }
-
-      #[test]
-      fn test_construct_with_small_capacity_inmemory() {
-        construct_with_small_capacity_inmemory::<OrderWal<Ascend, Crc32>>();
-      }
-
-      #[test]
-      fn test_construct_with_small_capacity_map_anon() {
-        construct_with_small_capacity_map_anon::<OrderWal<Ascend, Crc32>>();
-      }
-
-      #[test]
-      #[cfg_attr(miri, ignore)]
-      fn test_construct_with_small_capacity_map_file() {
-        construct_with_small_capacity_map_file::<OrderWal<Ascend, Crc32>>(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::<OrderWal<Ascend, Crc32>>();
+      }
+
+      #[test]
+      fn test_construct_map_anon() {
+        construct_map_anon::<OrderWal<Ascend, Crc32>>();
+      }
+
+      #[test]
+      #[cfg_attr(miri, ignore)]
+      fn test_construct_map_file() {
+        construct_map_file::<OrderWal<Ascend, Crc32>>(stringify!($prefix));
+      }
+
+      #[test]
+      fn test_construct_with_small_capacity_inmemory() {
+        construct_with_small_capacity_inmemory::<OrderWal<Ascend, Crc32>>();
+      }
+
+      #[test]
+      fn test_construct_with_small_capacity_map_anon() {
+        construct_with_small_capacity_map_anon::<OrderWal<Ascend, Crc32>>();
+      }
+
+      #[test]
+      #[cfg_attr(miri, ignore)]
+      fn test_construct_with_small_capacity_map_file() {
+        construct_with_small_capacity_map_file::<OrderWal<Ascend, Crc32>>(stringify!($prefix));
+      }
 
       #[test]
       fn test_zero_reserved_inmemory() {
diff --git a/src/unsync.rs b/src/unsync.rs
index a05fa6b6..5c80ae72 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 ee419731..96d3abab 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 00000000..03e864a3
--- /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 00000000..c9eefcf8
--- /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 00000000..6aacd454
--- /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 00000000..f20d78e8
--- /dev/null
+++ b/src/unsync/tests/iter.rs
@@ -0,0 +1,3 @@
+use super::*;
+
+common_unittests!(unsync::iters::OrderWal);