From b916b98e852956adeb040f4415a322d436640e5f Mon Sep 17 00:00:00 2001 From: Al Liu Date: Thu, 28 Nov 2024 00:38:41 +0800 Subject: [PATCH] 0.21.0 (#52) --- CHANGELOG.md | 4 + Cargo.toml | 2 +- README.md | 4 +- src/dynamic.rs | 66 +- src/dynamic/list.rs | 136 ++-- src/dynamic/list/api.rs | 66 +- src/dynamic/list/api/update.rs | 40 +- src/dynamic/list/entry.rs | 184 ++---- src/dynamic/list/iterator.rs | 695 ++++++++++++++++++++- src/dynamic/list/iterator/all_versions.rs | 692 --------------------- src/dynamic/list/iterator/iter.rs | 162 ----- src/dynamic/multiple_version.rs | 131 ++-- src/dynamic/unique.rs | 94 ++- src/generic.rs | 106 +++- src/generic/list.rs | 111 ++-- src/generic/list/api.rs | 60 +- src/generic/list/api/update.rs | 42 +- src/generic/list/entry.rs | 193 ++---- src/generic/list/iterator.rs | 702 ++++++++++++++++++++- src/generic/list/iterator/all_versions.rs | 717 ---------------------- src/generic/list/iterator/iter.rs | 188 ------ src/generic/multiple_version.rs | 134 ++-- src/generic/unique.rs | 112 +++- src/tests/generic/multiple_version.rs | 2 +- 24 files changed, 2189 insertions(+), 2454 deletions(-) delete mode 100644 src/dynamic/list/iterator/all_versions.rs delete mode 100644 src/dynamic/list/iterator/iter.rs delete mode 100644 src/generic/list/iterator/all_versions.rs delete mode 100644 src/generic/list/iterator/iter.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 52011a6..263a2ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 0.21.0 + +- Use state pattern for `EntryRef` + ## 0.20.0 - Add dynamic `SkipMap`s diff --git a/Cargo.toml b/Cargo.toml index 726288b..071cc8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "skl" -version = "0.20.2" +version = "0.21.0" edition = "2021" rust-version = "1.81.0" repository = "https://github.com/al8n/skl" diff --git a/README.md b/README.md index 662cda9..6b3e7b7 100644 --- a/README.md +++ b/README.md @@ -28,14 +28,14 @@ ```toml [dependencies] - skl = "0.20" + skl = "0.21" ``` - Enable memory map backend ```toml [dependencies] - skl = { version = "0.20", features = ["memmap"] } + skl = { version = "0.21", features = ["memmap"] } ``` ## Features diff --git a/src/dynamic.rs b/src/dynamic.rs index f5ddb18..a498208 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -1,5 +1,3 @@ -#![allow(single_use_lifetimes)] - mod list; /// Dynamic key-value `SkipMap` implementation with multiple versions support. @@ -13,12 +11,72 @@ pub use builder::Builder; /// Iterators for the skipmaps. pub mod iter { - pub use super::list::iterator::{Iter, IterAll}; + pub use super::list::iterator::Iter; } /// Entry references for the skipmaps. pub mod entry { - pub use super::list::{EntryRef, VersionedEntryRef}; + pub use super::list::EntryRef; } pub use dbutils::equivalentor::*; + +/// Value that can be converted from a byte slice. +pub trait Value<'a>: sealed::Sealed<'a> {} + +impl<'a, T> Value<'a> for T where T: sealed::Sealed<'a> {} + +mod sealed { + pub trait Sealed<'a> { + type Ref; + + fn as_ref(&self) -> Self::Ref; + + fn from_value_bytes(src: Option<&'a [u8]>) -> Self + where + Self: 'a; + + fn is_removed(&self) -> bool; + } + + impl<'a> Sealed<'a> for Option<&'a [u8]> { + type Ref = Option<&'a [u8]>; + + #[inline] + fn as_ref(&self) -> Self::Ref { + self.as_ref().copied() + } + + #[inline] + fn from_value_bytes(src: Option<&'a [u8]>) -> Self { + src + } + + #[inline] + fn is_removed(&self) -> bool { + self.is_none() + } + } + + impl<'a> Sealed<'a> for &'a [u8] { + type Ref = Self; + + #[inline] + fn as_ref(&self) -> Self::Ref { + self + } + + #[inline] + fn from_value_bytes(src: Option<&'a [u8]>) -> Self { + match src { + Some(v) => v, + None => panic!("cannot convert None to Value"), + } + } + + #[inline] + fn is_removed(&self) -> bool { + false + } + } +} diff --git a/src/dynamic/list.rs b/src/dynamic/list.rs index 429b1e9..6063aab 100644 --- a/src/dynamic/list.rs +++ b/src/dynamic/list.rs @@ -10,6 +10,7 @@ use rarena_allocator::Allocator as _; use crate::{ allocator::{Allocator, Deallocator, Meta, Node, NodePointer, Pointer, ValuePointer}, + dynamic::Value, encode_key_size_and_height, error::Error, internal::RefMeta, @@ -22,14 +23,14 @@ use crate::{ }; mod entry; -pub use entry::{EntryRef, VersionedEntryRef}; +pub use entry::EntryRef; mod api; pub(super) mod iterator; type UpdateOk<'a, 'b, A, RC, C> = Either< - Option>, - Result, VersionedEntryRef<'a, A, RC, C>>, + Option, C, A, RC>>, + Result, C, A, RC>, EntryRef<'a, Option<&'a [u8]>, C, A, RC>>, >; /// A fast, cocnurrent map implementation based on skiplist that supports forward @@ -314,12 +315,15 @@ where C: Comparator, R: RefCounter, { - unsafe fn move_to_prev<'a>( + unsafe fn move_to_prev<'a, V>( &'a self, nd: &mut ::Pointer, version: Version, contains_key: impl Fn(&[u8]) -> bool, - ) -> Option> { + ) -> Option> + where + V: Value<'a> + 'a, + { loop { unsafe { if nd.is_null() || nd.offset() == self.head.offset() { @@ -334,9 +338,10 @@ where let nk = nd.get_key(&self.arena); if contains_key(nk) { let pointer = nd.get_value_pointer::(); - let ent = - VersionedEntryRef::from_node_with_pointer(version, *nd, self, pointer, Some(nk)); - return Some(ent); + let value = + nd.get_value_by_value_offset(&self.arena, pointer.value_offset, pointer.value_len); + let ent = EntryRef::from_node_with_pointer(version, *nd, self, Some(nk), value); + return Some(ent.map()); } *nd = self.get_prev(*nd, 0); @@ -344,12 +349,15 @@ where } } - unsafe fn move_to_prev_maximum_version<'a>( + unsafe fn move_to_prev_maximum_version<'a, V>( &'a self, nd: &mut ::Pointer, version: Version, contains_key: impl Fn(&[u8]) -> bool, - ) -> Option> { + ) -> Option> + where + V: Value<'a> + 'a, + { loop { unsafe { if nd.is_null() || nd.offset() == self.head.offset() { @@ -371,9 +379,10 @@ where if contains_key(nk) { let pointer = nd.get_value_pointer::(); - let ent = - VersionedEntryRef::from_node_with_pointer(version, *nd, self, pointer, Some(nk)); - return Some(ent); + let value = + nd.get_value_by_value_offset(&self.arena, pointer.value_offset, pointer.value_len); + let ent = EntryRef::from_node_with_pointer(version, *nd, self, Some(nk), value); + return Some(ent.map()); } } @@ -388,9 +397,10 @@ where if !nd.is_removed() && contains_key(nk) { let pointer = nd.get_value_pointer::(); - let ent = - VersionedEntryRef::from_node_with_pointer(version, *nd, self, pointer, Some(nk)); - return Some(ent); + let value = + nd.get_value_by_value_offset(&self.arena, pointer.value_offset, pointer.value_len); + let ent = EntryRef::from_node_with_pointer(version, *nd, self, Some(nk), value); + return Some(ent.map()); } } @@ -399,12 +409,15 @@ where } } - unsafe fn move_to_next<'a>( + unsafe fn move_to_next<'a, V>( &'a self, nd: &mut ::Pointer, version: Version, contains_key: impl Fn(&[u8]) -> bool, - ) -> Option> { + ) -> Option> + where + V: Value<'a> + 'a, + { loop { unsafe { if nd.is_null() || nd.offset() == self.tail.offset() { @@ -419,9 +432,10 @@ where let nk = nd.get_key(&self.arena); if contains_key(nk) { let pointer = nd.get_value_pointer::(); - let ent = - VersionedEntryRef::from_node_with_pointer(version, *nd, self, pointer, Some(nk)); - return Some(ent); + let value = + nd.get_value_by_value_offset(&self.arena, pointer.value_offset, pointer.value_len); + let ent = EntryRef::from_node_with_pointer(version, *nd, self, Some(nk), value); + return Some(ent.map()); } *nd = self.get_next(*nd, 0); @@ -429,12 +443,15 @@ where } } - unsafe fn move_to_next_maximum_version<'a>( + unsafe fn move_to_next_maximum_version<'a, V>( &'a self, nd: &mut ::Pointer, version: Version, contains_key: impl Fn(&[u8]) -> bool, - ) -> Option> { + ) -> Option> + where + V: Value<'a> + 'a, + { loop { unsafe { if nd.is_null() || nd.offset() == self.tail.offset() { @@ -472,9 +489,10 @@ where let nk = nd.get_key(&self.arena); if contains_key(nk) { let pointer = nd.get_value_pointer::(); - let ent = - VersionedEntryRef::from_node_with_pointer(version, *nd, self, pointer, Some(nk)); - return Some(ent); + let value = + nd.get_value_by_value_offset(&self.arena, pointer.value_offset, pointer.value_len); + let ent = EntryRef::from_node_with_pointer(version, *nd, self, Some(nk), value); + return Some(ent.map()); } *nd = self.get_next(*nd, 0); @@ -584,10 +602,10 @@ where /// /// ## Safety: /// - All of splices in the inserter must be contains node ptrs are allocated by the current skip map. - unsafe fn find_splice<'a, 'b: 'a>( + unsafe fn find_splice<'a>( &'a self, version: Version, - key: Either<&'a [u8], &'b [u8]>, + key: Either<&'a [u8], &'a [u8]>, ins: &mut Inserter<'a, ::Pointer>, returned_when_found: bool, ) -> (bool, Option, Option<::Pointer>) { @@ -660,10 +678,10 @@ where /// ## Safety /// - `level` is less than `MAX_HEIGHT`. /// - `start` must be allocated by self's arena. - unsafe fn find_splice_for_level<'a, 'b: 'a>( + unsafe fn find_splice_for_level<'a>( &'a self, version: Version, - key: Either<&'a [u8], &'b [u8]>, + key: Either<&'a [u8], &'a [u8]>, level: usize, start: ::Pointer, ) -> FindResult<::Pointer> { @@ -728,11 +746,11 @@ where } } - fn try_get_pointer<'a, 'b: 'a>( + fn try_get_pointer<'a>( &'a self, next_node: &::Pointer, next_key: &[u8], - key: Either<&'a [u8], &'b [u8]>, + key: Either<&'a [u8], &'a [u8]>, ) -> Option { match key { Either::Left(key) | Either::Right(key) => match self.arena.options().compression_policy() { @@ -764,11 +782,11 @@ where /// ## Safety /// - The caller must ensure that the node is allocated by the arena. /// - The caller must ensure that the node is not null. - unsafe fn key_is_after_node<'a, 'b: 'a>( + unsafe fn key_is_after_node<'a>( &'a self, nd: ::Pointer, version: Version, - key: Either<&'a [u8], &'b [u8]>, + key: Either<&'a [u8], &'a [u8]>, ) -> bool { let nd_key = self .arena @@ -841,7 +859,8 @@ where if found { let node_ptr = ptr.expect("the NodePtr cannot be `None` when we found"); let k = found_key.expect("the key cannot be `None` when we found"); - let old = VersionedEntryRef::from_node(version, node_ptr, self, None); + let (value, _) = node_ptr.get_value_with_pointer(&self.arena); + let old = EntryRef::from_node(version, node_ptr, self, None, value); if upsert { return self.upsert( @@ -1015,7 +1034,8 @@ where let node_ptr = fr .curr .expect("the current should not be `None` when we found"); - let old = VersionedEntryRef::from_node(version, node_ptr, self, None); + let (value, _) = node_ptr.get_value_with_pointer(&self.arena); + let old = EntryRef::from_node(version, node_ptr, self, None, value); if upsert { // let curr = nd.as_ref(&self.arena); @@ -1092,7 +1112,7 @@ where unsafe fn upsert_value<'a, 'b: 'a>( &'a self, version: Version, - old: VersionedEntryRef<'a, A, R, C>, + old: EntryRef<'a, Option<&'a [u8]>, C, A, R>, old_node: ::Pointer, key: &Key<'a, 'b, A>, value_offset: u32, @@ -1113,15 +1133,17 @@ where Key::Remove(_) | Key::RemoveVacant { .. } | Key::RemovePointer { .. } => { match old_node.clear_value(&self.arena, success, failure) { Ok(_) => Ok(Either::Left(None)), - Err((offset, len)) => Ok(Either::Right(Err( - VersionedEntryRef::from_node_with_pointer( - version, - old_node, - self, - ValuePointerType::new(offset, len), - None, - ), - ))), + Err((offset, len)) => { + let pointer = ValuePointerType::new(offset, len); + let value = old_node.get_value_by_value_offset( + &self.arena, + pointer.value_offset, + pointer.value_len, + ); + Ok(Either::Right(Err(EntryRef::from_node_with_pointer( + version, old_node, self, None, value, + )))) + } } } } @@ -1131,7 +1153,7 @@ where unsafe fn upsert<'a, 'b: 'a, E>( &'a self, version: Version, - old: VersionedEntryRef<'a, A, R, C>, + old: EntryRef<'a, Option<&'a [u8]>, C, A, R>, old_node: ::Pointer, key: &Key<'a, 'b, A>, value_builder: Option) -> Result>>, @@ -1146,15 +1168,17 @@ where Key::Remove(_) | Key::RemoveVacant { .. } | Key::RemovePointer { .. } => { match old_node.clear_value(&self.arena, success, failure) { Ok(_) => Ok(Either::Left(None)), - Err((offset, len)) => Ok(Either::Right(Err( - VersionedEntryRef::from_node_with_pointer( - version, - old_node, - self, - ValuePointerType::new(offset, len), - None, - ), - ))), + Err((offset, len)) => { + let pointer = ValuePointerType::new(offset, len); + let value = old_node.get_value_by_value_offset( + &self.arena, + pointer.value_offset, + pointer.value_len, + ); + Ok(Either::Right(Err(EntryRef::from_node_with_pointer( + version, old_node, self, None, value, + )))) + } } } } diff --git a/src/dynamic/list/api.rs b/src/dynamic/list/api.rs index 8e2ce7d..f378f95 100644 --- a/src/dynamic/list/api.rs +++ b/src/dynamic/list/api.rs @@ -15,7 +15,7 @@ use crate::{ Header, Version, }; -use super::{iterator, EntryRef, RefCounter, SkipList, VersionedEntryRef}; +use super::{iterator, EntryRef, RefCounter, SkipList}; mod update; @@ -174,22 +174,22 @@ where } /// Returns the first entry in the map. - pub fn first(&self, version: Version) -> Option> { + pub fn first(&self, version: Version) -> Option> { self.iter(version).next() } /// Returns the last entry in the map. - pub fn last(&self, version: Version) -> Option> { + pub fn last(&self, version: Version) -> Option> { self.iter(version).last() } /// Returns the first entry in the map. - pub fn first_versioned(&self, version: Version) -> Option> { + pub fn first_versioned(&self, version: Version) -> Option, C, A, RC>> { self.iter_all_versions(version).next() } /// Returns the last entry in the map. - pub fn last_versioned(&self, version: Version) -> Option> { + pub fn last_versioned(&self, version: Version) -> Option, C, A, RC>> { self.iter_all_versions(version).last() } @@ -197,22 +197,16 @@ where /// /// This method will return `None` if the entry is marked as removed. If you want to get the entry even if it is marked as removed, /// you can use [`get_versioned`](SkipList::get_versioned). - pub fn get(&self, version: Version, key: &[u8]) -> Option> { + pub fn get(&self, version: Version, key: &[u8]) -> Option> { unsafe { let (n, eq) = self.find_near(version, key, false, true); // findLessOrEqual. let node = n?; let raw_node_key = node.get_key(&self.arena); - let (value, pointer) = node.get_value_with_pointer(&self.arena); + let (value, _) = node.get_value_with_pointer(&self.arena); if eq { - return value.map(|_| { - EntryRef(VersionedEntryRef::from_node_with_pointer( - version, - node, - self, - pointer, - Some(raw_node_key), - )) + return value.map(|value| { + EntryRef::from_node_with_pointer(version, node, self, Some(raw_node_key), value) }); } @@ -224,14 +218,8 @@ where return None; } - value.map(|_| { - EntryRef(VersionedEntryRef::from_node_with_pointer( - version, - node, - self, - pointer, - Some(raw_node_key), - )) + value.map(|value| { + EntryRef::from_node_with_pointer(version, node, self, Some(raw_node_key), value) }) } } @@ -243,20 +231,20 @@ where &self, version: Version, key: &[u8], - ) -> Option> { + ) -> Option, C, A, RC>> { unsafe { let (n, eq) = self.find_near(version, key, false, true); // findLessOrEqual. let node = n?; let raw_node_key = node.get_key(&self.arena); - let (_, pointer) = node.get_value_with_pointer(&self.arena); + let (value, _) = node.get_value_with_pointer(&self.arena); if eq { - return Some(VersionedEntryRef::from_node_with_pointer( + return Some(EntryRef::from_node_with_pointer( version, node, self, - pointer, Some(raw_node_key), + value, )); } @@ -268,12 +256,12 @@ where return None; } - Some(VersionedEntryRef::from_node_with_pointer( + Some(EntryRef::from_node_with_pointer( version, node, self, - pointer, Some(raw_node_key), + value, )) } } @@ -284,7 +272,7 @@ where &self, version: Version, upper: Bound<&[u8]>, - ) -> Option> { + ) -> Option> { self.iter(version).seek_upper_bound(upper) } @@ -294,30 +282,30 @@ where &self, version: Version, lower: Bound<&[u8]>, - ) -> Option> { + ) -> Option> { self.iter(version).seek_lower_bound(lower) } /// Returns a new iterator, this iterator will yield the latest version of all entries in the map less or equal to the given version. #[inline] - pub fn iter(&self, version: Version) -> iterator::Iter<'_, A, RC, C> { - iterator::Iter::new(version, self) + pub fn iter(&self, version: Version) -> iterator::Iter<'_, &[u8], A, RC, C> { + iterator::Iter::new(version, self, false) } /// Returns a new iterator, this iterator will yield all versions for all entries in the map less or equal to the given version. #[inline] - pub fn iter_all_versions(&self, version: Version) -> iterator::IterAll<'_, A, RC, C> { - iterator::IterAll::new(version, self, true) + pub fn iter_all_versions(&self, version: Version) -> iterator::Iter<'_, Option<&[u8]>, A, RC, C> { + iterator::Iter::new(version, self, true) } /// Returns a iterator that within the range, this iterator will yield the latest version of all entries in the range less or equal to the given version. #[inline] - pub fn range(&self, version: Version, range: R) -> iterator::Iter<'_, A, RC, C, Q, R> + pub fn range(&self, version: Version, range: R) -> iterator::Iter<'_, &[u8], A, RC, C, Q, R> where Q: ?Sized + Borrow<[u8]>, R: RangeBounds, { - iterator::Iter::range(version, self, range) + iterator::Iter::range(version, self, range, false) } /// Returns a iterator that within the range, this iterator will yield all versions for all entries in the range less or equal to the given version. @@ -326,11 +314,11 @@ where &self, version: Version, range: R, - ) -> iterator::IterAll<'_, A, RC, C, Q, R> + ) -> iterator::Iter<'_, Option<&[u8]>, A, RC, C, Q, R> where Q: ?Sized + Borrow<[u8]>, R: RangeBounds, { - iterator::IterAll::range(version, self, range, true) + iterator::Iter::range(version, self, range, true) } } diff --git a/src/dynamic/list/api/update.rs b/src/dynamic/list/api/update.rs index bb5f50c..2d7aea9 100644 --- a/src/dynamic/list/api/update.rs +++ b/src/dynamic/list/api/update.rs @@ -25,7 +25,7 @@ where version: Version, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result>, Error> { self.insert_at_height(version, self.random_height(), key, value) } @@ -40,7 +40,7 @@ where height: Height, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result>, Error> { self.validate(height, key.len(), value.len())?; let val_len = value.len(); @@ -65,7 +65,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -90,7 +90,7 @@ where height: Height, key: &'b [u8], value_builder: ValueBuilder) -> Result>, - ) -> Result>, Either> { + ) -> Result>, Either> { self .validate(height, key.len(), value_builder.size()) .map_err(Either::Right)?; @@ -111,7 +111,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -129,7 +129,7 @@ where height: Height, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result>, Error> { self.validate(height, key.len(), value.len())?; let val_len = value.len(); @@ -154,7 +154,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -180,7 +180,7 @@ where height: Height, key: &'b [u8], value_builder: ValueBuilder) -> Result>, - ) -> Result>, Either> { + ) -> Result>, Either> { self .validate(height, key.len(), value_builder.size()) .map_err(Either::Right)?; @@ -201,7 +201,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -224,7 +224,7 @@ where height: Height, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> { + ) -> Result>, Among> { self .validate(height, key_builder.size(), value_builder.size()) .map_err(Among::Right)?; @@ -251,7 +251,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -273,7 +273,7 @@ where height: Height, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> { + ) -> Result>, Among> { self .validate(height, key_builder.size(), value_builder.size()) .map_err(Among::Right)?; @@ -300,7 +300,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -323,7 +323,7 @@ where key: &'b [u8], success: Ordering, failure: Ordering, - ) -> Result>, Error> { + ) -> Result>, Error> { self.validate(height, key.len(), 0)?; self @@ -344,14 +344,14 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } } Err(current) => { if current.is_removed() { None } else { - Some(EntryRef(current)) + Some(current.map()) } } }, @@ -370,7 +370,7 @@ where version: Version, height: Height, key: &'b [u8], - ) -> Result>, Error> { + ) -> Result>, Error> { self.validate(height, key.len(), 0)?; self @@ -390,7 +390,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } } None => None, @@ -416,7 +416,7 @@ where version: Version, height: Height, key_builder: KeyBuilder) -> Result>, - ) -> Result>, Either> { + ) -> Result>, Either> { self .validate(height, key_builder.size(), 0) .map_err(Either::Right)?; @@ -441,7 +441,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } } None => None, diff --git a/src/dynamic/list/entry.rs b/src/dynamic/list/entry.rs index 81e1dc1..fe7a2c2 100644 --- a/src/dynamic/list/entry.rs +++ b/src/dynamic/list/entry.rs @@ -1,60 +1,89 @@ use crate::{ allocator::{Allocator, Node, NodePointer, WithVersion}, - dynamic::list::SkipList, + dynamic::{list::SkipList, Value}, ref_counter::RefCounter, - types::internal::ValuePointer, Version, }; use dbutils::equivalentor::Comparator; -/// A versioned entry reference of the skipmap. -/// -/// Compared to the [`EntryRef`], this one's value can be `None` which means the entry is removed. -pub struct VersionedEntryRef<'a, A, R, C> +/// An entry reference of the `SkipMap`. +pub struct EntryRef<'a, V, C, A, R> where A: Allocator, R: RefCounter, { pub(super) list: &'a SkipList, pub(super) key: &'a [u8], - pub(super) value: Option<&'a [u8]>, + pub(super) value: V, pub(super) version: Version, pub(super) query_version: Version, pub(super) ptr: ::Pointer, } -impl core::fmt::Debug for VersionedEntryRef<'_, A, R, C> +impl core::fmt::Debug for EntryRef<'_, V, C, A, R> where A: Allocator, R: RefCounter, + V: core::fmt::Debug, { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("VersionedEntryRef") + f.debug_struct("EntryRef") .field("key", &self.key()) - .field("value", &self.value()) + .field("value", &self.value) .field("version", &self.version) .finish() } } -impl Clone for VersionedEntryRef<'_, A, R, C> +impl Clone for EntryRef<'_, V, C, A, R> where A: Allocator, R: RefCounter, + V: Clone, { + #[inline] fn clone(&self) -> Self { - *self + Self { + list: self.list, + key: self.key, + value: self.value.clone(), + version: self.version, + query_version: self.query_version, + ptr: self.ptr, + } } } -impl Copy for VersionedEntryRef<'_, A, R, C> +impl Copy for EntryRef<'_, V, C, A, R> where A: Allocator, R: RefCounter, + V: Copy, { } -impl<'a, A, R, C> VersionedEntryRef<'a, A, R, C> +impl<'a, A, R, C> EntryRef<'a, Option<&'a [u8]>, C, A, R> +where + A: Allocator, + R: RefCounter, +{ + #[inline] + pub(super) fn map(self) -> EntryRef<'a, NV, C, A, R> + where + NV: Value<'a> + 'a, + { + EntryRef { + list: self.list, + key: self.key, + value: NV::from_value_bytes(self.value), + version: self.version, + query_version: self.query_version, + ptr: self.ptr, + } + } +} + +impl<'a, V, C, A, R> EntryRef<'a, V, C, A, R> where A: Allocator, R: RefCounter, @@ -73,22 +102,29 @@ where /// Returns the reference to the value, `None` means the entry is removed. #[inline] - pub const fn value(&self) -> Option<&'a [u8]> { - self.value + pub fn value(&self) -> V::Ref + where + V: Value<'a>, + { + self.value.as_ref() } /// Returns if the entry is marked as removed #[inline] - pub fn is_removed(&self) -> bool { - self.value().is_none() + pub fn is_removed(&self) -> bool + where + V: Value<'a>, + { + self.value.is_removed() } } -impl VersionedEntryRef<'_, A, R, C> +impl<'a, V, C, A, R> EntryRef<'a, V, C, A, R> where C: Comparator, A: Allocator, R: RefCounter, + V: Value<'a> + 'a, { /// Returns the next entry in the map. #[inline] @@ -110,6 +146,7 @@ where self .list .move_to_next(&mut nd, self.query_version, |_| true) + .map(|ent| ent.map()) } } else { unsafe { @@ -117,6 +154,7 @@ where self .list .move_to_next_maximum_version(&mut nd, self.query_version, |_| true) + .map(|ent| ent.map()) } } } @@ -136,12 +174,13 @@ where self .list .move_to_prev_maximum_version(&mut nd, self.query_version, |_| true) + .map(|ent| ent.map()) } } } } -impl VersionedEntryRef<'_, A, R, C> +impl EntryRef<'_, V, C, A, R> where A: Allocator, A::Node: WithVersion, @@ -154,7 +193,7 @@ where } } -impl<'a, A, R, C> VersionedEntryRef<'a, A, R, C> +impl<'a, V, C, A, R> EntryRef<'a, V, C, A, R> where A: Allocator, R: RefCounter, @@ -165,10 +204,9 @@ where node: ::Pointer, list: &'a SkipList, key: Option<&'a [u8]>, + value: V, ) -> Self { unsafe { - let (value, _) = node.get_value_with_pointer(&list.arena); - let key = match key { Some(key) => key, None => node.get_key(&list.arena), @@ -190,13 +228,10 @@ where query_version: Version, node: ::Pointer, list: &'a SkipList, - pointer: ValuePointer, key: Option<&'a [u8]>, + value: V, ) -> Self { unsafe { - let value = - node.get_value_by_value_offset(&list.arena, pointer.value_offset, pointer.value_len); - let key = match key { Some(key) => key, None => node.get_key(&list.arena), @@ -213,98 +248,3 @@ where } } } - -/// An entry reference to the skipmap's entry. -/// -/// Compared to the [`VersionedEntryRef`], this one's value cannot be `None`. -pub struct EntryRef<'a, A, R, C>(pub(crate) VersionedEntryRef<'a, A, R, C>) -where - A: Allocator, - R: RefCounter; - -impl core::fmt::Debug for EntryRef<'_, A, R, C> -where - A: Allocator, - R: RefCounter, -{ - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("EntryRef") - .field("key", &self.key()) - .field("value", &self.value()) - .finish() - } -} - -impl Clone for EntryRef<'_, A, R, C> -where - A: Allocator, - R: RefCounter, -{ - #[inline] - fn clone(&self) -> Self { - *self - } -} - -impl Copy for EntryRef<'_, A, R, C> -where - A: Allocator, - R: RefCounter, -{ -} - -impl EntryRef<'_, A, R, C> -where - C: Comparator, - A: Allocator, - R: RefCounter, -{ - /// Returns the next entry in the map. - #[inline] - pub fn next(&self) -> Option { - self.0.next_in(false).map(Self) - } - - /// Returns the previous entry in the map. - #[inline] - pub fn prev(&self) -> Option { - self.0.prev_in(false).map(Self) - } -} - -impl EntryRef<'_, A, R, C> -where - A: Allocator, - A::Node: WithVersion, - R: RefCounter, -{ - /// Returns the version of the entry - #[inline] - pub const fn version(&self) -> Version { - self.0.version() - } -} - -impl<'a, A, R, C> EntryRef<'a, A, R, C> -where - A: Allocator, - R: RefCounter, -{ - /// Returns the comparator. - #[inline] - pub const fn comparator(&self) -> &C { - self.0.comparator() - } - - /// Returns the reference to the key - #[inline] - pub fn key(&self) -> &'a [u8] { - self.0.key() - } - - /// Returns the reference to the value - #[inline] - pub fn value(&self) -> &'a [u8] { - self.0.value().expect("EntryRef's value cannot be `None`") - } -} diff --git a/src/dynamic/list/iterator.rs b/src/dynamic/list/iterator.rs index da39ae8..cb9fb0a 100644 --- a/src/dynamic/list/iterator.rs +++ b/src/dynamic/list/iterator.rs @@ -1,5 +1,692 @@ -mod all_versions; -pub use all_versions::*; +use super::{Allocator, EntryRef, NodePointer, RefCounter, SkipList, Value, Version}; +use crate::allocator::Node; +use core::{ + borrow::Borrow, + ops::{Bound, RangeBounds}, +}; +use dbutils::equivalentor::{Comparator, RangeComparator}; -mod iter; -pub use iter::*; +/// An iterator over the skipmap (this iterator will yields all versions). The current state of the iterator can be cloned by +/// simply value copying the struct. +pub struct Iter<'a, V, A, RC, C, Q = [u8], R = core::ops::RangeFull> +where + A: Allocator, + RC: RefCounter, + Q: ?Sized, +{ + pub(super) map: &'a SkipList, + pub(super) version: Version, + pub(super) range: Option, + pub(super) all_versions: bool, + pub(super) head: Option>, + pub(super) tail: Option>, + pub(super) _phantom: core::marker::PhantomData, +} + +impl Clone for Iter<'_, V, A, RC, C, Q, R> +where + A: Allocator, + RC: RefCounter, + Q: ?Sized, + R: Clone, + V: Clone, +{ + fn clone(&self) -> Self { + Self { + map: self.map, + head: self.head.clone(), + tail: self.tail.clone(), + version: self.version, + range: self.range.clone(), + all_versions: self.all_versions, + _phantom: core::marker::PhantomData, + } + } +} + +impl Copy for Iter<'_, V, A, RC, C, Q, R> +where + A: Allocator, + RC: RefCounter, + Q: ?Sized, + R: Copy, + V: Copy, +{ +} + +impl<'a, V, A, RC, C> Iter<'a, V, A, RC, C> +where + A: Allocator, + RC: RefCounter, +{ + #[inline] + pub(crate) const fn new( + version: Version, + map: &'a SkipList, + all_versions: bool, + ) -> Self { + Self { + map, + head: None, + tail: None, + version, + range: None, + all_versions, + _phantom: core::marker::PhantomData, + } + } +} + +impl<'a, V, A, RC, C, Q, R> Iter<'a, V, A, RC, C, Q, R> +where + A: Allocator, + RC: RefCounter, + Q: ?Sized, +{ + #[inline] + pub(crate) fn range( + version: Version, + map: &'a SkipList, + r: R, + all_versions: bool, + ) -> Self { + Self { + map, + head: None, + tail: None, + version, + range: Some(r), + all_versions, + _phantom: core::marker::PhantomData, + } + } +} + +impl<'a, V, A, RC, C, Q, R> Iter<'a, V, A, RC, C, Q, R> +where + A: Allocator, + RC: RefCounter, + R: RangeBounds, + Q: ?Sized, +{ + /// Returns the start bound of the iterator. + #[inline] + pub fn start_bound(&self) -> Bound<&Q> { + self + .range + .as_ref() + .map(|r| r.start_bound()) + .unwrap_or(Bound::Unbounded) + } + + /// Returns the end bound of the iterator. + #[inline] + pub fn end_bound(&self) -> Bound<&Q> { + self + .range + .as_ref() + .map(|r| r.end_bound()) + .unwrap_or(Bound::Unbounded) + } + + /// Returns the entry at the current head position of the iterator. + #[inline] + pub const fn head(&self) -> Option<&EntryRef<'a, V, C, A, RC>> { + self.head.as_ref() + } + + /// Returns the entry at the current tail position of the iterator. + #[inline] + pub const fn tail(&self) -> Option<&EntryRef<'a, V, C, A, RC>> { + self.tail.as_ref() + } +} + +impl<'a, V, A, RC, C, Q, R> Iter<'a, V, A, RC, C, Q, R> +where + A: Allocator, + C: Comparator, + RC: RefCounter, + Q: ?Sized + Borrow<[u8]>, + R: RangeBounds, + V: Value<'a> + 'a + Copy, +{ + /// Advances to the next position. Returns the key and value if the + /// iterator is pointing at a valid entry, and `None` otherwise. + fn next_in(&mut self) -> Option> { + unsafe { + let mut next_head = match self.head.as_ref() { + Some(head) => self.map.get_next(head.ptr, 0), + None => self.map.get_next(self.map.head, 0), + }; + + let next_head = if self.all_versions { + self + .map + .move_to_next(&mut next_head, self.version, |nk| self.check_bounds(nk)) + } else { + self + .map + .move_to_next_maximum_version(&mut next_head, self.version, |nk| { + if let Some(ref head) = self.head { + head.key().ne(nk) && self.check_bounds(nk) + } else { + self.check_bounds(nk) + } + }) + }; + + match (&next_head, &self.tail) { + (Some(next), Some(t)) + if next + .key() + .cmp(t.key()) + .then_with(|| t.version.cmp(&next.version)) + .is_ge() => + { + self.head = next_head; + None + } + (Some(_), _) => { + self.head = next_head; + next_head + } + (None, _) => { + self.head = next_head; + None + } + } + } + } + + /// Advances to the prev position. Returns the key and value if the + /// iterator is pointing at a valid entry, and `None` otherwise. + fn prev(&mut self) -> Option> { + unsafe { + let mut next_tail = match self.tail.as_ref() { + Some(tail) => self.map.get_prev(tail.ptr, 0), + None => self.map.get_prev(self.map.tail, 0), + }; + + let next_tail = if self.all_versions { + self + .map + .move_to_prev(&mut next_tail, self.version, |nk| self.check_bounds(nk)) + } else { + self + .map + .move_to_prev_maximum_version(&mut next_tail, self.version, |nk| { + if let Some(ref tail) = self.tail { + tail.key().ne(nk) && self.check_bounds(nk) + } else { + self.check_bounds(nk) + } + }) + }; + + match (&self.head, &next_tail) { + // The prev key is smaller than the latest head key we observed with this iterator. + (Some(h), Some(next)) + if h + .key() + .cmp(next.key()) + .then_with(|| h.version.cmp(&next.version)) + .is_ge() => + { + self.tail = next_tail; + None + } + (_, Some(_)) => { + self.tail = next_tail; + next_tail + } + (_, None) => { + self.tail = next_tail; + None + } + } + } + } + + fn range_next_in(&mut self) -> Option> { + unsafe { + let mut next_head = match self.head.as_ref() { + Some(head) => self.map.get_next(head.ptr, 0), + None => match self.range.as_ref().unwrap().start_bound() { + Bound::Included(key) => self + .map + .find_near(self.version, key.borrow(), false, true) + .0 + .unwrap_or(::Pointer::NULL), + Bound::Excluded(key) => self + .map + .find_near(Version::MIN, key.borrow(), false, false) + .0 + .unwrap_or(::Pointer::NULL), + Bound::Unbounded => self.map.get_next(self.map.head, 0), + }, + }; + + self.head = if self.all_versions { + self + .map + .move_to_next(&mut next_head, self.version, |nk| self.check_bounds(nk)) + } else { + self + .map + .move_to_next_maximum_version(&mut next_head, self.version, |nk| { + if let Some(ref head) = self.head { + head.key().ne(nk) && self.check_bounds(nk) + } else { + self.check_bounds(nk) + } + }) + }; + + if let Some(ref h) = self.head { + match &self.tail { + Some(t) => { + let bound = Bound::Excluded(t.key()); + if !below_upper_bound(&self.map.cmp, bound, h.key()) { + self.head = None; + self.tail = None; + } + } + None => { + let bound = self.range.as_ref().unwrap().end_bound().map(|b| b.borrow()); + if !below_upper_bound_compare(&self.map.cmp, bound, h.key()) { + self.head = None; + self.tail = None; + } + } + } + } + + self.head + } + } + + fn range_prev(&mut self) -> Option> { + unsafe { + let mut next_tail = match self.tail.as_ref() { + Some(tail) => self.map.get_prev(tail.ptr, 0), + None => match self.range.as_ref().unwrap().end_bound() { + Bound::Included(key) => self + .map + .find_near(Version::MIN, key.borrow(), true, true) + .0 + .unwrap_or(::Pointer::NULL), + Bound::Excluded(key) => self + .map + .find_near(self.version, key.borrow(), true, false) + .0 + .unwrap_or(::Pointer::NULL), + Bound::Unbounded => self.map.get_prev(self.map.tail, 0), + }, + }; + + self.tail = if self.all_versions { + self + .map + .move_to_prev(&mut next_tail, self.version, |nk| self.check_bounds(nk)) + } else { + self + .map + .move_to_prev_maximum_version(&mut next_tail, self.version, |nk| { + if let Some(ref tail) = self.tail { + tail.key().ne(nk) && self.check_bounds(nk) + } else { + self.check_bounds(nk) + } + }) + }; + + if let Some(ref t) = self.tail { + match &self.head { + Some(h) => { + let bound = Bound::Excluded(h.key()); + if !above_lower_bound(&self.map.cmp, bound, t.key()) { + self.head = None; + self.tail = None; + } + } + None => { + let bound = self + .range + .as_ref() + .unwrap() + .start_bound() + .map(|b| b.borrow()); + if !above_lower_bound_compare(&self.map.cmp, bound, t.key()) { + self.head = None; + self.tail = None; + } + } + } + } + + self.tail + } + } +} + +impl<'a, V, A, RC, C, Q, R> Iter<'a, V, A, RC, C, Q, R> +where + A: Allocator, + C: Comparator, + RC: RefCounter, + Q: ?Sized + Borrow<[u8]>, + R: RangeBounds, + V: Value<'a> + Copy + 'a, +{ + /// Moves the iterator to the highest element whose key is below the given bound. + /// If no such element is found then `None` is returned. + /// + /// **Note:** This method will clear the current state of the iterator. + pub fn seek_upper_bound(&mut self, upper: Bound<&QR>) -> Option> + where + QR: ?Sized + Borrow<[u8]>, + { + self.head = None; + self.tail = None; + + match upper { + Bound::Included(key) => self.seek_le(key).inspect(|ent| { + self.head = Some(*ent); + }), + Bound::Excluded(key) => self.seek_lt(key).inspect(|ent| { + self.head = Some(*ent); + }), + Bound::Unbounded => self.last(), + } + } + + /// Moves the iterator to the lowest element whose key is above the given bound. + /// If no such element is found then `None` is returned. + /// + /// **Note:** This method will clear the current state of the iterator. + pub fn seek_lower_bound(&mut self, lower: Bound<&QR>) -> Option> + where + QR: ?Sized + Borrow<[u8]>, + { + self.head = None; + self.tail = None; + + match lower { + Bound::Included(key) => self.seek_ge(key).inspect(|ent| { + self.head = Some(*ent); + }), + Bound::Excluded(key) => self.seek_gt(key).inspect(|ent| { + self.head = Some(*ent); + }), + Bound::Unbounded => self.first(), + } + } + + /// Moves the iterator to the first entry whose key is greater than or + /// equal to the given key. Returns the key and value if the iterator is + /// pointing at a valid entry, and `None` otherwise. + fn seek_ge(&self, key: &QR) -> Option> + where + QR: ?Sized + Borrow<[u8]>, + { + unsafe { + let (n, _) = self.map.find_near(self.version, key.borrow(), false, true); + + let mut n = n?; + if n.is_null() || n.offset() == self.map.tail.offset() { + return None; + } + + if self.all_versions { + self.map.move_to_next(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + self.map.cmp.compare_contains(range, nk) + } else { + true + } + }) + } else { + self + .map + .move_to_next_maximum_version(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + self.map.cmp.compare_contains(range, nk) + } else { + true + } + }) + } + } + } + + /// Moves the iterator to the first entry whose key is greater than + /// the given key. Returns the key and value if the iterator is + /// pointing at a valid entry, and `None` otherwise. + fn seek_gt(&self, key: &QR) -> Option> + where + QR: ?Sized + Borrow<[u8]>, + { + unsafe { + let (n, _) = self.map.find_near(Version::MIN, key.borrow(), false, false); + + let mut n = n?; + if n.is_null() || n.offset() == self.map.tail.offset() { + return None; + } + + if self.all_versions { + self.map.move_to_next(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + self.map.cmp.compare_contains(range, nk) + } else { + true + } + }) + } else { + self + .map + .move_to_next_maximum_version(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + self.map.cmp.compare_contains(range, nk) + } else { + true + } + }) + } + } + } + + /// Moves the iterator to the first entry whose key is less than or + /// equal to the given key. Returns the key and value if the iterator is + /// pointing at a valid entry, and `None` otherwise. + fn seek_le(&self, key: &QR) -> Option> + where + QR: ?Sized + Borrow<[u8]>, + { + unsafe { + let (n, _) = self.map.find_near(Version::MIN, key.borrow(), true, true); // find less or equal. + + let mut n = n?; + if n.is_null() || n.offset() == self.map.head.offset() { + return None; + } + + if self.all_versions { + self.map.move_to_prev(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + self.map.cmp.compare_contains(range, nk) + } else { + true + } + }) + } else { + self + .map + .move_to_prev_maximum_version(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + self.map.cmp.compare_contains(range, nk) + } else { + true + } + }) + } + } + } + + /// Moves the iterator to the last entry whose key is less than the given + /// key. Returns the key and value if the iterator is pointing at a valid entry, + /// and `None` otherwise. + fn seek_lt(&self, key: &QR) -> Option> + where + QR: ?Sized + Borrow<[u8]>, + { + unsafe { + let (n, _) = self.map.find_near(self.version, key.borrow(), true, false); // find less or equal. + + let mut n = n?; + if n.is_null() || n.offset() == self.map.head.offset() { + return None; + } + + if self.all_versions { + self.map.move_to_prev(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + self.map.cmp.compare_contains(range, nk) + } else { + true + } + }) + } else { + self + .map + .move_to_prev_maximum_version(&mut n, self.version, |nk| self.check_bounds(nk)) + } + } + } + + #[inline] + fn first(&mut self) -> Option> { + self.head = None; + self.tail = None; + self.next() + } + + #[inline] + fn last(&mut self) -> Option> { + self.tail = None; + self.head = None; + self.prev() + } + + #[inline] + fn check_bounds(&self, nk: &[u8]) -> bool { + if let Some(ref range) = self.range { + self.map.cmp.compare_contains(range, nk) + } else { + true + } + } +} + +impl<'a, V, A, RC, C, Q, R> Iterator for Iter<'a, V, A, RC, C, Q, R> +where + A: Allocator, + C: Comparator, + RC: RefCounter, + Q: ?Sized + Borrow<[u8]>, + R: RangeBounds, + V: Value<'a> + Copy + 'a, +{ + type Item = EntryRef<'a, V, C, A, RC>; + + #[inline] + fn next(&mut self) -> Option { + if self.range.is_some() { + self.range_next_in() + } else { + self.next_in() + } + } + + #[inline] + fn last(mut self) -> Option + where + Self: Sized, + { + Iter::last(&mut self) + } + + #[inline] + fn max(self) -> Option + where + Self: Sized, + Self::Item: Ord, + { + self.last() + } + + #[inline] + fn min(mut self) -> Option + where + Self: Sized, + Self::Item: Ord, + { + self.first() + } +} + +impl<'a, V, A, RC, C, Q, R> DoubleEndedIterator for Iter<'a, V, A, RC, C, Q, R> +where + A: Allocator, + C: Comparator, + RC: RefCounter, + Q: ?Sized + Borrow<[u8]>, + R: RangeBounds, + V: Value<'a> + Copy + 'a, +{ + #[inline] + fn next_back(&mut self) -> Option { + if self.range.is_some() { + self.range_prev() + } else { + self.prev() + } + } +} + +/// Helper function to check if a value is above a lower bound +fn above_lower_bound_compare(cmp: &C, bound: Bound<&[u8]>, other: &[u8]) -> bool { + match bound { + Bound::Unbounded => true, + Bound::Included(key) => cmp.compare(key, other).is_le(), + Bound::Excluded(key) => cmp.compare(key, other).is_lt(), + } +} + +/// Helper function to check if a value is above a lower bound +fn above_lower_bound(cmp: &C, bound: Bound<&[u8]>, other: &[u8]) -> bool { + match bound { + Bound::Unbounded => true, + Bound::Included(key) => cmp.compare(key, other).is_le(), + Bound::Excluded(key) => cmp.compare(key, other).is_lt(), + } +} + +/// Helper function to check if a value is below an upper bound +fn below_upper_bound_compare(cmp: &C, bound: Bound<&[u8]>, other: &[u8]) -> bool { + match bound { + Bound::Unbounded => true, + Bound::Included(key) => cmp.compare(key, other).is_ge(), + Bound::Excluded(key) => cmp.compare(key, other).is_gt(), + } +} + +/// Helper function to check if a value is below an upper bound +fn below_upper_bound(cmp: &C, bound: Bound<&[u8]>, other: &[u8]) -> bool { + match bound { + Bound::Unbounded => true, + Bound::Included(key) => cmp.compare(key, other).is_ge(), + Bound::Excluded(key) => cmp.compare(key, other).is_gt(), + } +} diff --git a/src/dynamic/list/iterator/all_versions.rs b/src/dynamic/list/iterator/all_versions.rs deleted file mode 100644 index 6b9955c..0000000 --- a/src/dynamic/list/iterator/all_versions.rs +++ /dev/null @@ -1,692 +0,0 @@ -use super::super::{Allocator, NodePointer, RefCounter, SkipList, Version, VersionedEntryRef}; -use crate::allocator::Node; -use core::{ - borrow::Borrow, - ops::{Bound, RangeBounds}, -}; -use dbutils::equivalentor::{Comparator, RangeComparator}; - -/// An iterator over the skipmap (this iterator will yields all versions). The current state of the iterator can be cloned by -/// simply value copying the struct. -pub struct IterAll<'a, A, RC, C, Q = [u8], R = core::ops::RangeFull> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized, -{ - pub(super) map: &'a SkipList, - pub(super) version: Version, - pub(super) range: Option, - pub(super) all_versions: bool, - pub(super) head: Option>, - pub(super) tail: Option>, - pub(super) _phantom: core::marker::PhantomData, -} - -impl Clone for IterAll<'_, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized, - R: Clone, -{ - fn clone(&self) -> Self { - Self { - map: self.map, - head: self.head, - tail: self.tail, - version: self.version, - range: self.range.clone(), - all_versions: self.all_versions, - _phantom: core::marker::PhantomData, - } - } -} - -impl Copy for IterAll<'_, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized, - R: Copy, -{ -} - -impl<'a, A, RC, C> IterAll<'a, A, RC, C> -where - A: Allocator, - RC: RefCounter, -{ - #[inline] - pub(crate) const fn new( - version: Version, - map: &'a SkipList, - all_versions: bool, - ) -> Self { - Self { - map, - head: None, - tail: None, - version, - range: None, - all_versions, - _phantom: core::marker::PhantomData, - } - } -} - -impl<'a, A, RC, C, Q, R> IterAll<'a, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized, -{ - #[inline] - pub(crate) fn range( - version: Version, - map: &'a SkipList, - r: R, - all_versions: bool, - ) -> Self { - Self { - map, - head: None, - tail: None, - version, - range: Some(r), - all_versions, - _phantom: core::marker::PhantomData, - } - } -} - -impl<'a, A, RC, C, Q, R> IterAll<'a, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - R: RangeBounds, - Q: ?Sized, -{ - /// Returns the start bound of the iterator. - #[inline] - pub fn start_bound(&self) -> Bound<&Q> { - self - .range - .as_ref() - .map(|r| r.start_bound()) - .unwrap_or(Bound::Unbounded) - } - - /// Returns the end bound of the iterator. - #[inline] - pub fn end_bound(&self) -> Bound<&Q> { - self - .range - .as_ref() - .map(|r| r.end_bound()) - .unwrap_or(Bound::Unbounded) - } - - /// Returns the entry at the current head position of the iterator. - #[inline] - pub const fn head(&self) -> Option<&VersionedEntryRef<'a, A, RC, C>> { - self.head.as_ref() - } - - /// Returns the entry at the current tail position of the iterator. - #[inline] - pub const fn tail(&self) -> Option<&VersionedEntryRef<'a, A, RC, C>> { - self.tail.as_ref() - } -} - -impl<'a, A, RC, C, Q, R> IterAll<'a, A, RC, C, Q, R> -where - A: Allocator, - C: Comparator, - RC: RefCounter, - Q: ?Sized + Borrow<[u8]>, - R: RangeBounds, -{ - /// Advances to the next position. Returns the key and value if the - /// iterator is pointing at a valid entry, and `None` otherwise. - fn next_in(&mut self) -> Option> { - unsafe { - let mut next_head = match self.head.as_ref() { - Some(head) => self.map.get_next(head.ptr, 0), - None => self.map.get_next(self.map.head, 0), - }; - - let next_head = if self.all_versions { - self - .map - .move_to_next(&mut next_head, self.version, |nk| self.check_bounds(nk)) - } else { - self - .map - .move_to_next_maximum_version(&mut next_head, self.version, |nk| { - if let Some(ref head) = self.head { - head.key().ne(nk) && self.check_bounds(nk) - } else { - self.check_bounds(nk) - } - }) - }; - - match (&next_head, &self.tail) { - (Some(next), Some(t)) - if next - .key() - .cmp(t.key()) - .then_with(|| t.version.cmp(&next.version)) - .is_ge() => - { - self.head = next_head; - None - } - (Some(_), _) => { - self.head = next_head; - next_head - } - (None, _) => { - self.head = next_head; - None - } - } - } - } - - /// Advances to the prev position. Returns the key and value if the - /// iterator is pointing at a valid entry, and `None` otherwise. - fn prev(&mut self) -> Option> { - unsafe { - let mut next_tail = match self.tail.as_ref() { - Some(tail) => self.map.get_prev(tail.ptr, 0), - None => self.map.get_prev(self.map.tail, 0), - }; - - let next_tail = if self.all_versions { - self - .map - .move_to_prev(&mut next_tail, self.version, |nk| self.check_bounds(nk)) - } else { - self - .map - .move_to_prev_maximum_version(&mut next_tail, self.version, |nk| { - if let Some(ref tail) = self.tail { - tail.key().ne(nk) && self.check_bounds(nk) - } else { - self.check_bounds(nk) - } - }) - }; - - match (&self.head, &next_tail) { - // The prev key is smaller than the latest head key we observed with this iterator. - (Some(h), Some(next)) - if h - .key() - .cmp(next.key()) - .then_with(|| h.version.cmp(&next.version)) - .is_ge() => - { - self.tail = next_tail; - None - } - (_, Some(_)) => { - self.tail = next_tail; - next_tail - } - (_, None) => { - self.tail = next_tail; - None - } - } - } - } - - fn range_next_in(&mut self) -> Option> { - unsafe { - let mut next_head = match self.head.as_ref() { - Some(head) => self.map.get_next(head.ptr, 0), - None => match self.range.as_ref().unwrap().start_bound() { - Bound::Included(key) => self - .map - .find_near(self.version, key.borrow(), false, true) - .0 - .unwrap_or(::Pointer::NULL), - Bound::Excluded(key) => self - .map - .find_near(Version::MIN, key.borrow(), false, false) - .0 - .unwrap_or(::Pointer::NULL), - Bound::Unbounded => self.map.get_next(self.map.head, 0), - }, - }; - - self.head = if self.all_versions { - self - .map - .move_to_next(&mut next_head, self.version, |nk| self.check_bounds(nk)) - } else { - self - .map - .move_to_next_maximum_version(&mut next_head, self.version, |nk| { - if let Some(ref head) = self.head { - head.key().ne(nk) && self.check_bounds(nk) - } else { - self.check_bounds(nk) - } - }) - }; - - if let Some(ref h) = self.head { - match &self.tail { - Some(t) => { - let bound = Bound::Excluded(t.key()); - if !below_upper_bound(&self.map.cmp, bound, h.key()) { - self.head = None; - self.tail = None; - } - } - None => { - let bound = self.range.as_ref().unwrap().end_bound().map(|b| b.borrow()); - if !below_upper_bound_compare(&self.map.cmp, bound, h.key()) { - self.head = None; - self.tail = None; - } - } - } - } - - self.head - } - } - - fn range_prev(&mut self) -> Option> { - unsafe { - let mut next_tail = match self.tail.as_ref() { - Some(tail) => self.map.get_prev(tail.ptr, 0), - None => match self.range.as_ref().unwrap().end_bound() { - Bound::Included(key) => self - .map - .find_near(Version::MIN, key.borrow(), true, true) - .0 - .unwrap_or(::Pointer::NULL), - Bound::Excluded(key) => self - .map - .find_near(self.version, key.borrow(), true, false) - .0 - .unwrap_or(::Pointer::NULL), - Bound::Unbounded => self.map.get_prev(self.map.tail, 0), - }, - }; - - self.tail = if self.all_versions { - self - .map - .move_to_prev(&mut next_tail, self.version, |nk| self.check_bounds(nk)) - } else { - self - .map - .move_to_prev_maximum_version(&mut next_tail, self.version, |nk| { - if let Some(ref tail) = self.tail { - tail.key().ne(nk) && self.check_bounds(nk) - } else { - self.check_bounds(nk) - } - }) - }; - - if let Some(ref t) = self.tail { - match &self.head { - Some(h) => { - let bound = Bound::Excluded(h.key()); - if !above_lower_bound(&self.map.cmp, bound, t.key()) { - self.head = None; - self.tail = None; - } - } - None => { - let bound = self - .range - .as_ref() - .unwrap() - .start_bound() - .map(|b| b.borrow()); - if !above_lower_bound_compare(&self.map.cmp, bound, t.key()) { - self.head = None; - self.tail = None; - } - } - } - } - - self.tail - } - } -} - -impl<'a, A, RC, C, Q, R> IterAll<'a, A, RC, C, Q, R> -where - A: Allocator, - C: Comparator, - RC: RefCounter, - Q: ?Sized + Borrow<[u8]>, - R: RangeBounds, -{ - /// Moves the iterator to the highest element whose key is below the given bound. - /// If no such element is found then `None` is returned. - /// - /// **Note:** This method will clear the current state of the iterator. - pub fn seek_upper_bound( - &mut self, - upper: Bound<&QR>, - ) -> Option> - where - QR: ?Sized + Borrow<[u8]>, - { - self.head = None; - self.tail = None; - - match upper { - Bound::Included(key) => self.seek_le(key).inspect(|ent| { - self.head = Some(*ent); - }), - Bound::Excluded(key) => self.seek_lt(key).inspect(|ent| { - self.head = Some(*ent); - }), - Bound::Unbounded => self.last(), - } - } - - /// Moves the iterator to the lowest element whose key is above the given bound. - /// If no such element is found then `None` is returned. - /// - /// **Note:** This method will clear the current state of the iterator. - pub fn seek_lower_bound( - &mut self, - lower: Bound<&QR>, - ) -> Option> - where - QR: ?Sized + Borrow<[u8]>, - { - self.head = None; - self.tail = None; - - match lower { - Bound::Included(key) => self.seek_ge(key).inspect(|ent| { - self.head = Some(*ent); - }), - Bound::Excluded(key) => self.seek_gt(key).inspect(|ent| { - self.head = Some(*ent); - }), - Bound::Unbounded => self.first(), - } - } - - /// Moves the iterator to the first entry whose key is greater than or - /// equal to the given key. Returns the key and value if the iterator is - /// pointing at a valid entry, and `None` otherwise. - fn seek_ge(&self, key: &QR) -> Option> - where - QR: ?Sized + Borrow<[u8]>, - { - unsafe { - let (n, _) = self.map.find_near(self.version, key.borrow(), false, true); - - let mut n = n?; - if n.is_null() || n.offset() == self.map.tail.offset() { - return None; - } - - if self.all_versions { - self.map.move_to_next(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - self.map.cmp.compare_contains(range, nk) - } else { - true - } - }) - } else { - self - .map - .move_to_next_maximum_version(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - self.map.cmp.compare_contains(range, nk) - } else { - true - } - }) - } - } - } - - /// Moves the iterator to the first entry whose key is greater than - /// the given key. Returns the key and value if the iterator is - /// pointing at a valid entry, and `None` otherwise. - fn seek_gt(&self, key: &QR) -> Option> - where - QR: ?Sized + Borrow<[u8]>, - { - unsafe { - let (n, _) = self.map.find_near(Version::MIN, key.borrow(), false, false); - - let mut n = n?; - if n.is_null() || n.offset() == self.map.tail.offset() { - return None; - } - - if self.all_versions { - self.map.move_to_next(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - self.map.cmp.compare_contains(range, nk) - } else { - true - } - }) - } else { - self - .map - .move_to_next_maximum_version(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - self.map.cmp.compare_contains(range, nk) - } else { - true - } - }) - } - } - } - - /// Moves the iterator to the first entry whose key is less than or - /// equal to the given key. Returns the key and value if the iterator is - /// pointing at a valid entry, and `None` otherwise. - fn seek_le(&self, key: &QR) -> Option> - where - QR: ?Sized + Borrow<[u8]>, - { - unsafe { - let (n, _) = self.map.find_near(Version::MIN, key.borrow(), true, true); // find less or equal. - - let mut n = n?; - if n.is_null() || n.offset() == self.map.head.offset() { - return None; - } - - if self.all_versions { - self.map.move_to_prev(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - self.map.cmp.compare_contains(range, nk) - } else { - true - } - }) - } else { - self - .map - .move_to_prev_maximum_version(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - self.map.cmp.compare_contains(range, nk) - } else { - true - } - }) - } - } - } - - /// Moves the iterator to the last entry whose key is less than the given - /// key. Returns the key and value if the iterator is pointing at a valid entry, - /// and `None` otherwise. - fn seek_lt(&self, key: &QR) -> Option> - where - QR: ?Sized + Borrow<[u8]>, - { - unsafe { - let (n, _) = self.map.find_near(self.version, key.borrow(), true, false); // find less or equal. - - let mut n = n?; - if n.is_null() || n.offset() == self.map.head.offset() { - return None; - } - - if self.all_versions { - self.map.move_to_prev(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - self.map.cmp.compare_contains(range, nk) - } else { - true - } - }) - } else { - self - .map - .move_to_prev_maximum_version(&mut n, self.version, |nk| self.check_bounds(nk)) - } - } - } - - #[inline] - fn first(&mut self) -> Option> { - self.head = None; - self.tail = None; - self.next() - } - - #[inline] - fn last(&mut self) -> Option> { - self.tail = None; - self.head = None; - self.prev() - } - - #[inline] - fn check_bounds(&self, nk: &'a [u8]) -> bool { - if let Some(ref range) = self.range { - self.map.cmp.compare_contains(range, nk) - } else { - true - } - } -} - -impl<'a, A, RC, C, Q, R> Iterator for IterAll<'a, A, RC, C, Q, R> -where - A: Allocator, - C: Comparator, - RC: RefCounter, - Q: ?Sized + Borrow<[u8]>, - R: RangeBounds, -{ - type Item = VersionedEntryRef<'a, A, RC, C>; - - #[inline] - fn next(&mut self) -> Option { - if self.range.is_some() { - self.range_next_in() - } else { - self.next_in() - } - } - - #[inline] - fn last(mut self) -> Option - where - Self: Sized, - { - IterAll::last(&mut self) - } - - #[inline] - fn max(self) -> Option - where - Self: Sized, - Self::Item: Ord, - { - self.last() - } - - #[inline] - fn min(mut self) -> Option - where - Self: Sized, - Self::Item: Ord, - { - self.first() - } -} - -impl DoubleEndedIterator for IterAll<'_, A, RC, C, Q, R> -where - A: Allocator, - C: Comparator, - RC: RefCounter, - Q: ?Sized + Borrow<[u8]>, - R: RangeBounds, -{ - #[inline] - fn next_back(&mut self) -> Option { - if self.range.is_some() { - self.range_prev() - } else { - self.prev() - } - } -} - -/// Helper function to check if a value is above a lower bound -fn above_lower_bound_compare(cmp: &C, bound: Bound<&[u8]>, other: &[u8]) -> bool { - match bound { - Bound::Unbounded => true, - Bound::Included(key) => cmp.compare(key, other).is_le(), - Bound::Excluded(key) => cmp.compare(key, other).is_lt(), - } -} - -/// Helper function to check if a value is above a lower bound -fn above_lower_bound(cmp: &C, bound: Bound<&[u8]>, other: &[u8]) -> bool { - match bound { - Bound::Unbounded => true, - Bound::Included(key) => cmp.compare(key, other).is_le(), - Bound::Excluded(key) => cmp.compare(key, other).is_lt(), - } -} - -/// Helper function to check if a value is below an upper bound -fn below_upper_bound_compare(cmp: &C, bound: Bound<&[u8]>, other: &[u8]) -> bool { - match bound { - Bound::Unbounded => true, - Bound::Included(key) => cmp.compare(key, other).is_ge(), - Bound::Excluded(key) => cmp.compare(key, other).is_gt(), - } -} - -/// Helper function to check if a value is below an upper bound -fn below_upper_bound(cmp: &C, bound: Bound<&[u8]>, other: &[u8]) -> bool { - match bound { - Bound::Unbounded => true, - Bound::Included(key) => cmp.compare(key, other).is_ge(), - Bound::Excluded(key) => cmp.compare(key, other).is_gt(), - } -} diff --git a/src/dynamic/list/iterator/iter.rs b/src/dynamic/list/iterator/iter.rs deleted file mode 100644 index 8e9e4da..0000000 --- a/src/dynamic/list/iterator/iter.rs +++ /dev/null @@ -1,162 +0,0 @@ -use core::{ - borrow::Borrow, - ops::{Bound, RangeBounds}, -}; - -use dbutils::equivalentor::Comparator; - -use super::{ - super::{Allocator, EntryRef, RefCounter, SkipList, Version}, - IterAll, -}; - -/// An iterator over the skipmap. The current state of the iterator can be cloned by -/// simply value copying the struct. -pub struct Iter<'a, A, RC, C, Q = [u8], R = core::ops::RangeFull>(IterAll<'a, A, RC, C, Q, R>) -where - A: Allocator, - RC: RefCounter, - Q: ?Sized; - -impl Clone for Iter<'_, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized, - R: Clone, -{ - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl<'a, A, RC, C> Iter<'a, A, RC, C> -where - A: Allocator, - RC: RefCounter, -{ - #[inline] - pub(crate) const fn new(version: Version, map: &'a SkipList) -> Self { - Self(IterAll::new(version, map, false)) - } -} - -impl<'a, A, RC, C, Q, R> Iter<'a, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized, -{ - #[inline] - pub(crate) fn range(version: Version, map: &'a SkipList, r: R) -> Self { - Self(IterAll::range(version, map, r, false)) - } -} - -impl Iter<'_, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized, - R: RangeBounds, -{ - /// Returns the start bound of the iterator. - #[inline] - pub fn start_bound(&self) -> Bound<&Q> { - self.0.start_bound() - } - - /// Returns the end bound of the iterator. - #[inline] - pub fn end_bound(&self) -> Bound<&Q> { - self.0.end_bound() - } -} - -impl<'a, A, RC, C, Q, R> Iter<'a, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized, - R: RangeBounds, -{ - /// Returns the entry at the current head position of the iterator. - #[inline] - pub fn head(&self) -> Option> { - self.0.head().map(|e| EntryRef::(*e)) - } - - /// Returns the entry at the current tail position of the iterator. - #[inline] - pub fn tail(&self) -> Option> { - self.0.tail().map(|e| EntryRef::(*e)) - } -} - -impl<'a, A, RC, C, Q, R> Iter<'a, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized + Borrow<[u8]>, - C: Comparator, - R: RangeBounds, -{ - /// Moves the iterator to the highest element whose key is below the given bound. - /// If no such element is found then `None` is returned. - /// - /// **Note**: This method will clear the current state of the iterator. - pub fn seek_upper_bound(&mut self, upper: Bound<&QR>) -> Option> - where - QR: ?Sized + Borrow<[u8]>, - { - self.0.seek_upper_bound(upper).map(EntryRef) - } - - /// Moves the iterator to the lowest element whose key is above the given bound. - /// If no such element is found then `None` is returned. - /// - /// **Note**: This method will clear the current state of the iterator. - pub(crate) fn seek_lower_bound(&mut self, lower: Bound<&QR>) -> Option> - where - QR: ?Sized + Borrow<[u8]>, - { - self.0.seek_lower_bound(lower).map(EntryRef) - } -} - -impl<'a, A, RC, C, Q, R> Iterator for Iter<'a, A, RC, C, Q, R> -where - A: Allocator, - C: Comparator, - RC: RefCounter, - Q: ?Sized + Borrow<[u8]>, - R: RangeBounds, -{ - type Item = EntryRef<'a, A, RC, C>; - - #[inline] - fn next(&mut self) -> Option { - self.0.next().map(EntryRef) - } - - #[inline] - fn last(self) -> Option - where - Self: Sized, - { - self.0.last().map(EntryRef) - } -} - -impl DoubleEndedIterator for Iter<'_, A, RC, C, Q, R> -where - A: Allocator, - RC: RefCounter, - Q: ?Sized + Borrow<[u8]>, - C: Comparator, - R: RangeBounds, -{ - fn next_back(&mut self) -> Option { - self.0.next_back().map(EntryRef) - } -} diff --git a/src/dynamic/multiple_version.rs b/src/dynamic/multiple_version.rs index 27fae9a..0079717 100644 --- a/src/dynamic/multiple_version.rs +++ b/src/dynamic/multiple_version.rs @@ -1,3 +1,5 @@ +#![allow(single_use_lifetimes)] + use core::{ borrow::Borrow, ops::{Bound, RangeBounds}, @@ -15,10 +17,7 @@ use crate::{ Arena, Header, Height, KeyBuilder, ValueBuilder, Version, }; -use super::list::{ - iterator::{Iter, IterAll}, - EntryRef, VersionedEntryRef, -}; +use super::list::{iterator::Iter, EntryRef}; /// Implementations for single-threaded environments. pub mod unsync { @@ -34,23 +33,13 @@ pub mod unsync { type SkipList = super::super::list::SkipList; /// Iterator over the [`SkipMap`]. - pub type Iter<'a, C> = super::super::iter::Iter<'a, Allocator, RefCounter, C>; - - /// Iterator over a subset of the [`SkipMap`]. - pub type Range<'a, C, Q, R> = super::super::iter::Iter<'a, Allocator, RefCounter, C, Q, R>; + pub type Iter<'a, V, C> = super::super::iter::Iter<'a, V, Allocator, RefCounter, C>; /// The entry reference of the [`SkipMap`]. - pub type Entry<'a, C> = super::super::entry::EntryRef<'a, Allocator, RefCounter, C>; - - /// The versioned entry reference of the [`SkipMap`]. - pub type VersionedEntry<'a, C> = - super::super::entry::VersionedEntryRef<'a, Allocator, RefCounter, C>; - - /// Iterator over the [`SkipMap`]. - pub type IterAll<'a, C> = super::super::iter::IterAll<'a, Allocator, RefCounter, C>; + pub type Entry<'a, V, C> = super::super::entry::EntryRef<'a, Allocator, RefCounter, C, V>; /// Iterator over a subset of the [`SkipMap`]. - pub type RangeAll<'a, C, Q, R> = super::super::iter::IterAll<'a, Allocator, RefCounter, C, Q, R>; + pub type Range<'a, V, C, Q, R> = super::super::iter::Iter<'a, V, Allocator, RefCounter, C, Q, R>; /// A fast, ARENA based `SkipMap` that supports multiple versions, forward and backward iteration. /// @@ -142,23 +131,13 @@ pub mod sync { type SkipList = super::super::list::SkipList; /// Iterator over the [`SkipMap`]. - pub type Iter<'a, C> = super::super::iter::Iter<'a, Allocator, RefCounter, C>; + pub type Iter<'a, V, C> = super::super::iter::Iter<'a, V, Allocator, RefCounter, C>; /// Iterator over a subset of the [`SkipMap`]. - pub type Range<'a, C, Q, R> = super::super::iter::Iter<'a, Allocator, RefCounter, C, Q, R>; - - /// Iterator over the [`SkipMap`]. - pub type IterAll<'a, C> = super::super::iter::IterAll<'a, Allocator, RefCounter, C>; - - /// Iterator over a subset of the [`SkipMap`]. - pub type RangeAll<'a, C, Q, R> = super::super::iter::IterAll<'a, Allocator, RefCounter, C, Q, R>; + pub type Range<'a, V, C, Q, R> = super::super::iter::Iter<'a, V, Allocator, RefCounter, C, Q, R>; /// The entry reference of the [`SkipMap`]. - pub type Entry<'a, C> = super::super::entry::EntryRef<'a, Allocator, RefCounter, C>; - - /// The versioned entry reference of the [`SkipMap`]. - pub type VersionedEntry<'a, C> = - super::super::entry::VersionedEntryRef<'a, Allocator, RefCounter, C>; + pub type Entry<'a, C, V> = super::super::entry::EntryRef<'a, Allocator, RefCounter, C, V>; /// A fast, lock-free, thread-safe ARENA based `SkipMap` that supports multiple versions, forward and backward iteration. /// @@ -387,7 +366,7 @@ where fn first( &self, version: Version, - ) -> Option> { + ) -> Option> { if !self.may_contain_version(version) { return None; } @@ -400,7 +379,7 @@ where fn last( &self, version: Version, - ) -> Option> { + ) -> Option> { if !self.may_contain_version(version) { return None; } @@ -416,7 +395,7 @@ where fn first_versioned( &self, version: Version, - ) -> Option> { + ) -> Option, Self::Comparator, Self::Allocator, Self::RefCounter>> { if !self.may_contain_version(version) { return None; } @@ -432,7 +411,7 @@ where fn last_versioned( &self, version: Version, - ) -> Option> { + ) -> Option, Self::Comparator, Self::Allocator, Self::RefCounter>> { if !self.may_contain_version(version) { return None; } @@ -466,7 +445,7 @@ where &self, version: Version, key: &Q, - ) -> Option> + ) -> Option> where Q: ?Sized + Borrow<[u8]>, { @@ -503,7 +482,7 @@ where &self, version: Version, key: &Q, - ) -> Option> + ) -> Option, Self::Comparator, Self::Allocator, Self::RefCounter>> where Q: ?Sized + Borrow<[u8]>, { @@ -521,7 +500,7 @@ where &self, version: Version, upper: Bound<&Q>, - ) -> Option> + ) -> Option> where Q: ?Sized + Borrow<[u8]>, { @@ -539,7 +518,7 @@ where &self, version: Version, lower: Bound<&Q>, - ) -> Option> + ) -> Option> where Q: ?Sized + Borrow<[u8]>, { @@ -550,7 +529,7 @@ where self.as_ref().iter(version).seek_lower_bound(lower) } - /// Returns an `VersionedEntryRef` pointing to the highest element whose key is below the given bound. + /// Returns an `EntryRef` pointing to the highest element whose key is below the given bound. /// If no such element is found then `None` is returned. /// /// The difference between [`upper_bound`](Map::upper_bound) and `upper_bound_versioned` is that `upper_bound_versioned` will return the value even if the entry is removed. @@ -559,7 +538,7 @@ where &self, version: Version, upper: Bound<&Q>, - ) -> Option> + ) -> Option, Self::Comparator, Self::Allocator, Self::RefCounter>> where Q: ?Sized + Borrow<[u8]>, { @@ -573,7 +552,7 @@ where .seek_upper_bound(upper) } - /// Returns an `VersionedEntryRef` pointing to the lowest element whose key is above the given bound. + /// Returns an `EntryRef` pointing to the lowest element whose key is above the given bound. /// If no such element is found then `None` is returned. /// /// The difference between [`lower_bound`](Map::lower_bound) and `lower_bound_versioned` is that `lower_bound_versioned` will return the value even if the entry is removed. @@ -582,7 +561,7 @@ where &self, version: Version, lower: Bound<&Q>, - ) -> Option> + ) -> Option, Self::Comparator, Self::Allocator, Self::RefCounter>> where Q: ?Sized + Borrow<[u8]>, { @@ -601,7 +580,7 @@ where fn iter( &self, version: Version, - ) -> Iter<'_, Self::Allocator, Self::RefCounter, Self::Comparator> { + ) -> Iter<'_, &[u8], Self::Allocator, Self::RefCounter, Self::Comparator> { self.as_ref().iter(version) } @@ -610,7 +589,7 @@ where fn iter_all_versions( &self, version: Version, - ) -> IterAll<'_, Self::Allocator, Self::RefCounter, Self::Comparator> { + ) -> Iter<'_, Option<&[u8]>, Self::Allocator, Self::RefCounter, Self::Comparator> { self.as_ref().iter_all_versions(version) } @@ -620,7 +599,7 @@ where &self, version: Version, range: R, - ) -> Iter<'_, Self::Allocator, Self::RefCounter, Self::Comparator, Q, R> + ) -> Iter<'_, &[u8], Self::Allocator, Self::RefCounter, Self::Comparator, Q, R> where Q: ?Sized + Borrow<[u8]>, R: RangeBounds, @@ -634,7 +613,7 @@ where &self, version: Version, range: R, - ) -> IterAll<'_, Self::Allocator, Self::RefCounter, Self::Comparator, Q, R> + ) -> Iter<'_, Option<&[u8]>, Self::Allocator, Self::RefCounter, Self::Comparator, Q, R> where Q: ?Sized + Borrow<[u8]>, R: RangeBounds, @@ -653,7 +632,10 @@ where version: Version, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.as_ref().insert(version, key, value) } @@ -680,7 +662,10 @@ where height: Height, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.as_ref().insert_at_height(version, height, key, value) } @@ -738,7 +723,7 @@ where key: &'b [u8], value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self.as_ref().insert_at_height_with_value_builder( @@ -805,7 +790,7 @@ where key: &'b [u8], value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self @@ -825,7 +810,10 @@ where version: Version, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self .as_ref() .get_or_insert_at_height(version, self.random_height(), key, value) @@ -844,7 +832,10 @@ where height: Height, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self .as_ref() .get_or_insert_at_height(version, height, key, value) @@ -904,7 +895,7 @@ where key: &'b [u8], value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self.get_or_insert_at_height_with_value_builder( @@ -972,7 +963,7 @@ where key: &'b [u8], value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self @@ -1039,7 +1030,7 @@ where key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Among, > { self.as_ref().insert_at_height_with_builders( @@ -1112,7 +1103,7 @@ where key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Among, > { self @@ -1177,7 +1168,7 @@ where key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Among, > { self.as_ref().get_or_insert_at_height_with_builders( @@ -1247,7 +1238,7 @@ where key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Among, > { self @@ -1270,7 +1261,10 @@ where key: &'b [u8], success: Ordering, failure: Ordering, - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.compare_remove_at_height(version, self.random_height(), key, success, failure) } @@ -1290,7 +1284,10 @@ where key: &'b [u8], success: Ordering, failure: Ordering, - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self .as_ref() .compare_remove_at_height(version, height, key, success, failure) @@ -1307,7 +1304,10 @@ where &'a self, version: Version, key: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.get_or_remove_at_height(version, self.random_height(), key) } @@ -1336,7 +1336,10 @@ where version: Version, height: Height, key: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.as_ref().get_or_remove_at_height(version, height, key) } @@ -1390,7 +1393,7 @@ where version: Version, key_builder: KeyBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self @@ -1450,7 +1453,7 @@ where height: Height, key_builder: KeyBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self diff --git a/src/dynamic/unique.rs b/src/dynamic/unique.rs index 5643d1d..aafb19c 100644 --- a/src/dynamic/unique.rs +++ b/src/dynamic/unique.rs @@ -31,13 +31,14 @@ pub mod unsync { type SkipList = super::super::list::SkipList; /// Iterator over the [`SkipMap`]. - pub type Iter<'a, C> = super::super::iter::Iter<'a, Allocator, RefCounter, C>; + pub type Iter<'a, C> = super::super::iter::Iter<'a, &'a [u8], Allocator, RefCounter, C>; /// Iterator over a subset of the [`SkipMap`]. - pub type Range<'a, C, Q, R> = super::super::iter::Iter<'a, Allocator, RefCounter, C, Q, R>; + pub type Range<'a, C, Q, R> = + super::super::iter::Iter<'a, &'a [u8], Allocator, RefCounter, C, Q, R>; /// The entry reference of the [`SkipMap`]. - pub type Entry<'a, C> = super::super::entry::EntryRef<'a, Allocator, RefCounter, C>; + pub type Entry<'a, C> = super::super::entry::EntryRef<'a, Allocator, RefCounter, C, &'a [u8]>; /// A fast, ARENA based `SkipMap` that supports forward and backward iteration. /// @@ -125,13 +126,14 @@ pub mod sync { type SkipList = super::super::list::SkipList; /// Iterator over the [`SkipMap`]. - pub type Iter<'a, C> = super::super::iter::Iter<'a, Allocator, RefCounter, C>; + pub type Iter<'a, C> = super::super::iter::Iter<'a, &'a [u8], Allocator, RefCounter, C>; /// Iterator over a subset of the [`SkipMap`]. - pub type Range<'a, C, Q, R> = super::super::iter::Iter<'a, Allocator, RefCounter, C, Q, R>; + pub type Range<'a, C, Q, R> = + super::super::iter::Iter<'a, &'a [u8], Allocator, RefCounter, C, Q, R>; /// The entry reference of the [`SkipMap`]. - pub type Entry<'a, C> = super::super::entry::EntryRef<'a, Allocator, RefCounter, C>; + pub type Entry<'a, C> = super::super::entry::EntryRef<'a, Allocator, RefCounter, C, &'a [u8]>; /// A fast, lock-free, thread-safe ARENA based `SkipMap` that supports forward and backward iteration. /// @@ -303,13 +305,17 @@ where /// Returns the first entry in the map. #[inline] - fn first(&self) -> Option> { + fn first( + &self, + ) -> Option> { self.as_ref().first(MIN_VERSION) } /// Returns the last entry in the map. #[inline] - fn last(&self) -> Option> { + fn last( + &self, + ) -> Option> { self.as_ref().last(MIN_VERSION) } @@ -335,7 +341,7 @@ where fn get( &self, key: &Q, - ) -> Option> + ) -> Option> where Q: ?Sized + Borrow<[u8]>, { @@ -348,7 +354,7 @@ where fn upper_bound( &self, upper: Bound<&Q>, - ) -> Option> + ) -> Option> where Q: ?Sized + Borrow<[u8]>, { @@ -361,7 +367,7 @@ where fn lower_bound( &self, lower: Bound<&Q>, - ) -> Option> + ) -> Option> where Q: ?Sized + Borrow<[u8]>, { @@ -370,7 +376,7 @@ where /// Returns a new iterator, this iterator will yield the latest version of all entries in the map less or equal to the given version. #[inline] - fn iter(&self) -> Iter<'_, Self::Allocator, Self::RefCounter, Self::Comparator> { + fn iter(&self) -> Iter<'_, &[u8], Self::Allocator, Self::RefCounter, Self::Comparator> { self.as_ref().iter(MIN_VERSION) } @@ -379,7 +385,7 @@ where fn range( &self, range: R, - ) -> Iter<'_, Self::Allocator, Self::RefCounter, Self::Comparator, Q, R> + ) -> Iter<'_, &[u8], Self::Allocator, Self::RefCounter, Self::Comparator, Q, R> where Q: ?Sized + Borrow<[u8]>, R: RangeBounds, @@ -397,7 +403,10 @@ where &'a self, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.insert_at_height(self.random_height(), key, value) } @@ -423,7 +432,10 @@ where height: Height, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self .as_ref() .insert_at_height(MIN_VERSION, height, key, value) @@ -483,7 +495,7 @@ where key: &'b [u8], value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self.insert_at_height_with_value_builder(self.random_height(), key, value_builder) @@ -545,7 +557,7 @@ where key: &'b [u8], value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self @@ -564,7 +576,10 @@ where &'a self, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.get_or_insert_at_height(self.random_height(), key, value) } @@ -580,7 +595,10 @@ where height: Height, key: &'b [u8], value: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self .as_ref() .get_or_insert_at_height(MIN_VERSION, height, key, value) @@ -640,7 +658,7 @@ where key: &'b [u8], value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self.get_or_insert_at_height_with_value_builder(self.random_height(), key, value_builder) @@ -703,7 +721,7 @@ where key: &'b [u8], value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self.as_ref().get_or_insert_at_height_with_value_builder( @@ -772,7 +790,7 @@ where key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Among, > { self.insert_at_height_with_builders(self.random_height(), key_builder, value_builder) @@ -839,7 +857,7 @@ where key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Among, > { self @@ -903,7 +921,7 @@ where key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Among, > { self.get_or_insert_at_height_with_builders(self.random_height(), key_builder, value_builder) @@ -967,7 +985,7 @@ where key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option>, Among, > { self.as_ref().get_or_insert_at_height_with_builders( @@ -987,10 +1005,14 @@ where /// - Returns `Ok(Some(current))` if the key exists and not in remove status /// or the entry is not successfully removed because of an update on this entry happens in another thread. #[inline] + #[allow(single_use_lifetimes)] fn remove<'a, 'b: 'a>( &'a self, key: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.remove_at_height(self.random_height(), key) } @@ -1008,7 +1030,10 @@ where &'a self, height: Height, key: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.as_ref().compare_remove_at_height( MIN_VERSION, height, @@ -1025,10 +1050,14 @@ where /// - Returns `Ok(None)` if the key does not exist. /// - Returns `Ok(Some(old))` if the key already exists. #[inline] + #[allow(single_use_lifetimes)] fn get_or_remove<'a, 'b: 'a>( &'a self, key: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self.get_or_remove_at_height(self.random_height(), key) } @@ -1057,7 +1086,10 @@ where &'a self, height: Height, key: &'b [u8], - ) -> Result>, Error> { + ) -> Result< + Option>, + Error, + > { self .as_ref() .get_or_remove_at_height(MIN_VERSION, height, key) @@ -1112,7 +1144,7 @@ where &'a self, key_builder: KeyBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self.get_or_remove_at_height_with_builder(self.random_height(), key_builder) @@ -1169,7 +1201,7 @@ where height: Height, key_builder: KeyBuilder) -> Result>, ) -> Result< - Option>, + Option>, Either, > { self diff --git a/src/generic.rs b/src/generic.rs index 91598a0..739fe69 100644 --- a/src/generic.rs +++ b/src/generic.rs @@ -9,14 +9,116 @@ pub mod unique; /// Iterators for the skipmaps. pub mod iter { - pub use super::list::iterator::{Iter, IterAll}; + pub use super::list::iterator::Iter; } /// Entry references for the skipmaps. pub mod entry { - pub use super::list::{EntryRef, VersionedEntryRef}; + pub use super::list::EntryRef; } pub use builder::Builder; pub use dbutils::{equivalent::*, types::*}; + +/// Value that can be converted from a byte slice. +pub trait GenericValue<'a>: sealed::Sealed<'a> {} + +impl<'a, T> GenericValue<'a> for T where T: sealed::Sealed<'a> {} + +mod sealed { + use dbutils::types::{LazyRef, Type}; + + pub trait Sealed<'a> { + type Ref; + type Value: Type + ?Sized; + + fn as_ref(&self) -> Self::Ref; + + fn from_bytes(src: Option<&'a [u8]>) -> Self + where + Self: 'a; + + fn from_lazy_ref(src: Option>) -> Self + where + Self: 'a; + + fn raw(&self) -> Option<&'a [u8]>; + + fn is_removed(&self) -> bool; + } + + impl<'a, T> Sealed<'a> for Option> + where + T: Type + ?Sized, + { + type Ref = Option>; + type Value = T; + + #[inline] + fn as_ref(&self) -> Self::Ref { + self.as_ref().map(|v| *v.get()) + } + + #[inline] + fn from_bytes(src: Option<&'a [u8]>) -> Self { + src.map(|v| unsafe { LazyRef::from_raw(v) }) + } + + #[inline] + fn from_lazy_ref(src: Option>) -> Self { + src + } + + #[inline] + fn raw(&self) -> Option<&'a [u8]> { + self + .as_ref() + .map(|v| v.raw().expect("raw value must be available")) + } + + #[inline] + fn is_removed(&self) -> bool { + self.is_none() + } + } + + impl<'a, T> Sealed<'a> for LazyRef<'a, T> + where + T: Type + ?Sized, + { + type Ref = T::Ref<'a>; + type Value = T; + + #[inline] + fn as_ref(&self) -> Self::Ref { + *self.get() + } + + #[inline] + fn from_bytes(src: Option<&'a [u8]>) -> Self { + match src { + Some(v) => unsafe { LazyRef::from_raw(v) }, + None => panic!("cannot convert None to Value"), + } + } + + #[inline] + fn from_lazy_ref(src: Option>) -> Self { + match src { + Some(v) => v, + None => panic!("cannot convert None to Value"), + } + } + + #[inline] + fn raw(&self) -> Option<&'a [u8]> { + LazyRef::raw(self) + } + + #[inline] + fn is_removed(&self) -> bool { + false + } + } +} diff --git a/src/generic/list.rs b/src/generic/list.rs index caa3890..fdf6728 100644 --- a/src/generic/list.rs +++ b/src/generic/list.rs @@ -4,7 +4,7 @@ use among::Among; use dbutils::{ buffer::VacantBuffer, equivalent::Comparable, - types::{KeyRef, MaybeStructured, Type}, + types::{KeyRef, LazyRef, MaybeStructured, Type}, }; use either::Either; use rarena_allocator::Allocator as _; @@ -24,14 +24,19 @@ use crate::{ }; mod entry; -pub use entry::{EntryRef, VersionedEntryRef}; +pub use entry::EntryRef; + +use super::GenericValue; mod api; pub(super) mod iterator; type UpdateOk<'a, 'b, K, V, A, R> = Either< - Option>, - Result, VersionedEntryRef<'a, K, V, A, R>>, + Option>, A, R>>, + Result< + EntryRef<'a, K, Option>, A, R>, + EntryRef<'a, K, Option>, A, R>, + >, >; /// A fast, cocnurrent map implementation based on skiplist that supports forward @@ -337,14 +342,15 @@ where A: Allocator, R: RefCounter, { - unsafe fn move_to_prev<'a>( + unsafe fn move_to_prev<'a, L>( &'a self, nd: &mut ::Pointer, version: Version, contains_key: impl Fn(&K::Ref<'a>) -> bool, - ) -> Option> + ) -> Option> where K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a, Value = V> + 'a, { loop { unsafe { @@ -361,14 +367,8 @@ where let nk = ty_ref::(raw_key); if contains_key(&nk) { let pointer = nd.get_value_pointer::(); - let ent = VersionedEntryRef::from_node_with_pointer( - version, - *nd, - self, - pointer, - Some(raw_key), - Some(nk), - ); + let ent = + EntryRef::from_node_with_pointer(version, *nd, self, pointer, Some(raw_key), Some(nk)); return Some(ent); } @@ -377,14 +377,15 @@ where } } - unsafe fn move_to_prev_maximum_version<'a>( + unsafe fn move_to_prev_maximum_version<'a, L>( &'a self, nd: &mut ::Pointer, version: Version, contains_key: impl Fn(&K::Ref<'a>) -> bool, - ) -> Option> + ) -> Option> where K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a, Value = V> + 'a, { loop { unsafe { @@ -408,7 +409,7 @@ where if contains_key(&nk) { let pointer = nd.get_value_pointer::(); - let ent = VersionedEntryRef::from_node_with_pointer( + let ent = EntryRef::from_node_with_pointer( version, *nd, self, @@ -432,7 +433,7 @@ where if !nd.is_removed() && contains_key(&nk) { let pointer = nd.get_value_pointer::(); - let ent = VersionedEntryRef::from_node_with_pointer( + let ent = EntryRef::from_node_with_pointer( version, *nd, self, @@ -449,14 +450,15 @@ where } } - unsafe fn move_to_next<'a>( + unsafe fn move_to_next<'a, L>( &'a self, nd: &mut ::Pointer, version: Version, contains_key: impl Fn(&K::Ref<'a>) -> bool, - ) -> Option> + ) -> Option> where K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a, Value = V> + 'a, { loop { unsafe { @@ -473,14 +475,8 @@ where let nk = ty_ref::(raw_key); if contains_key(&nk) { let pointer = nd.get_value_pointer::(); - let ent = VersionedEntryRef::from_node_with_pointer( - version, - *nd, - self, - pointer, - Some(raw_key), - Some(nk), - ); + let ent = + EntryRef::from_node_with_pointer(version, *nd, self, pointer, Some(raw_key), Some(nk)); return Some(ent); } @@ -489,14 +485,15 @@ where } } - unsafe fn move_to_next_maximum_version<'a>( + unsafe fn move_to_next_maximum_version<'a, L>( &'a self, nd: &mut ::Pointer, version: Version, contains_key: impl Fn(&K::Ref<'a>) -> bool, - ) -> Option> + ) -> Option> where K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a, Value = V> + 'a, { loop { unsafe { @@ -536,14 +533,8 @@ where let nk = ty_ref::(raw_key); if contains_key(&nk) { let pointer = nd.get_value_pointer::(); - let ent = VersionedEntryRef::from_node_with_pointer( - version, - *nd, - self, - pointer, - Some(raw_key), - Some(nk), - ); + let ent = + EntryRef::from_node_with_pointer(version, *nd, self, pointer, Some(raw_key), Some(nk)); return Some(ent); } @@ -923,7 +914,7 @@ where if found { let node_ptr = ptr.expect("the NodePtr cannot be `None` when we found"); let k = found_key.expect("the key cannot be `None` when we found"); - let old = VersionedEntryRef::from_node(version, node_ptr, self, None, None); + let old = EntryRef::from_node(version, node_ptr, self, None, None); if upsert { return self @@ -1099,7 +1090,7 @@ where let node_ptr = fr .curr .expect("the current should not be `None` when we found"); - let old = VersionedEntryRef::from_node(version, node_ptr, self, None, None); + let old = EntryRef::from_node(version, node_ptr, self, None, None); if upsert { // let curr = nd.as_ref(&self.arena); @@ -1176,7 +1167,7 @@ where unsafe fn upsert_value<'a, 'b: 'a>( &'a self, version: Version, - old: VersionedEntryRef<'a, K, V, A, R>, + old: EntryRef<'a, K, Option>, A, R>, old_node: ::Pointer, key: &Key<'a, 'b, K, A>, value_offset: u32, @@ -1199,16 +1190,14 @@ where | Key::RemoveVacant { .. } | Key::RemovePointer { .. } => match old_node.clear_value(&self.arena, success, failure) { Ok(_) => Ok(Either::Left(None)), - Err((offset, len)) => Ok(Either::Right(Err( - VersionedEntryRef::from_node_with_pointer( - version, - old_node, - self, - ValuePointerType::new(offset, len), - None, - None, - ), - ))), + Err((offset, len)) => Ok(Either::Right(Err(EntryRef::from_node_with_pointer( + version, + old_node, + self, + ValuePointerType::new(offset, len), + None, + None, + )))), }, } } @@ -1217,7 +1206,7 @@ where unsafe fn upsert<'a, 'b: 'a, E>( &'a self, version: Version, - old: VersionedEntryRef<'a, K, V, A, R>, + old: EntryRef<'a, K, Option>, A, R>, old_node: ::Pointer, key: &Key<'a, 'b, K, A>, value_builder: Option) -> Result>>, @@ -1234,16 +1223,14 @@ where | Key::RemoveVacant { .. } | Key::RemovePointer { .. } => match old_node.clear_value(&self.arena, success, failure) { Ok(_) => Ok(Either::Left(None)), - Err((offset, len)) => Ok(Either::Right(Err( - VersionedEntryRef::from_node_with_pointer( - version, - old_node, - self, - ValuePointerType::new(offset, len), - None, - None, - ), - ))), + Err((offset, len)) => Ok(Either::Right(Err(EntryRef::from_node_with_pointer( + version, + old_node, + self, + ValuePointerType::new(offset, len), + None, + None, + )))), }, } } diff --git a/src/generic/list/api.rs b/src/generic/list/api.rs index 9b0e428..ccc45a3 100644 --- a/src/generic/list/api.rs +++ b/src/generic/list/api.rs @@ -6,7 +6,7 @@ use core::{ use dbutils::{ buffer::VacantBuffer, equivalent::{Comparable, Equivalent}, - types::{KeyRef, Type}, + types::{KeyRef, LazyRef, Type}, }; use rarena_allocator::Allocator as _; @@ -18,7 +18,7 @@ use crate::{ Header, Version, }; -use super::{iterator, EntryRef, RefCounter, SkipList, VersionedEntryRef}; +use super::{iterator, EntryRef, RefCounter, SkipList}; mod update; @@ -186,7 +186,7 @@ where } /// Returns the first entry in the map. - pub fn first<'a>(&'a self, version: Version) -> Option> + pub fn first<'a>(&'a self, version: Version) -> Option, A, RC>> where K::Ref<'a>: KeyRef<'a, K>, { @@ -194,7 +194,7 @@ where } /// Returns the last entry in the map. - pub fn last<'a>(&'a self, version: Version) -> Option> + pub fn last<'a>(&'a self, version: Version) -> Option, A, RC>> where K::Ref<'a>: KeyRef<'a, K>, { @@ -205,7 +205,7 @@ where pub fn first_versioned<'a>( &'a self, version: Version, - ) -> Option> + ) -> Option>, A, RC>> where K::Ref<'a>: KeyRef<'a, K>, { @@ -216,7 +216,7 @@ where pub fn last_versioned<'a>( &'a self, version: Version, - ) -> Option> + ) -> Option>, A, RC>> where K::Ref<'a>: KeyRef<'a, K>, { @@ -227,7 +227,11 @@ where /// /// This method will return `None` if the entry is marked as removed. If you want to get the entry even if it is marked as removed, /// you can use [`get_versioned`](SkipList::get_versioned). - pub fn get<'a, Q>(&'a self, version: Version, key: &Q) -> Option> + pub fn get<'a, Q>( + &'a self, + version: Version, + key: &Q, + ) -> Option, A, RC>> where Q: ?Sized + Comparable>, { @@ -239,14 +243,7 @@ where let (value, pointer) = node.get_value_with_pointer(&self.arena); if eq { return value.map(|_| { - EntryRef(VersionedEntryRef::from_node_with_pointer( - version, - node, - self, - pointer, - Some(raw_node_key), - None, - )) + EntryRef::from_node_with_pointer(version, node, self, pointer, Some(raw_node_key), None) }); } @@ -260,14 +257,14 @@ where } value.map(|_| { - EntryRef(VersionedEntryRef::from_node_with_pointer( + EntryRef::from_node_with_pointer( version, node, self, pointer, Some(raw_node_key), Some(node_key), - )) + ) }) } } @@ -279,7 +276,7 @@ where &'a self, version: Version, key: &Q, - ) -> Option> + ) -> Option>, A, RC>> where Q: ?Sized + Comparable>, { @@ -290,7 +287,7 @@ where let raw_node_key = node.get_key(&self.arena); let (_, pointer) = node.get_value_with_pointer(&self.arena); if eq { - return Some(VersionedEntryRef::from_node_with_pointer( + return Some(EntryRef::from_node_with_pointer( version, node, self, @@ -309,7 +306,7 @@ where return None; } - Some(VersionedEntryRef::from_node_with_pointer( + Some(EntryRef::from_node_with_pointer( version, node, self, @@ -326,7 +323,7 @@ where &'a self, version: Version, upper: Bound<&Q>, - ) -> Option> + ) -> Option, A, RC>> where K::Ref<'a>: KeyRef<'a, K>, Q: ?Sized + Comparable>, @@ -340,7 +337,7 @@ where &'a self, version: Version, lower: Bound<&Q>, - ) -> Option> + ) -> Option, A, RC>> where K::Ref<'a>: KeyRef<'a, K>, Q: ?Sized + Comparable>, @@ -350,20 +347,23 @@ where /// Returns a new iterator, this iterator will yield the latest version of all entries in the map less or equal to the given version. #[inline] - pub fn iter<'a>(&'a self, version: Version) -> iterator::Iter<'a, K, V, A, RC> + pub fn iter<'a>(&'a self, version: Version) -> iterator::Iter<'a, K, LazyRef<'a, V>, A, RC> where K::Ref<'a>: KeyRef<'a, K>, { - iterator::Iter::new(version, self) + iterator::Iter::new(version, self, false) } /// Returns a new iterator, this iterator will yield all versions for all entries in the map less or equal to the given version. #[inline] - pub fn iter_all_versions<'a>(&'a self, version: Version) -> iterator::IterAll<'a, K, V, A, RC> + pub fn iter_all_versions<'a>( + &'a self, + version: Version, + ) -> iterator::Iter<'a, K, Option>, A, RC> where K::Ref<'a>: KeyRef<'a, K>, { - iterator::IterAll::new(version, self, true) + iterator::Iter::new(version, self, true) } /// Returns a iterator that within the range, this iterator will yield the latest version of all entries in the range less or equal to the given version. @@ -372,13 +372,13 @@ where &'a self, version: Version, range: R, - ) -> iterator::Iter<'a, K, V, A, RC, Q, R> + ) -> iterator::Iter<'a, K, LazyRef<'a, V>, A, RC, Q, R> where K::Ref<'a>: KeyRef<'a, K>, Q: ?Sized + Comparable>, R: RangeBounds, { - iterator::Iter::range(version, self, range) + iterator::Iter::range(version, self, range, false) } /// Returns a iterator that within the range, this iterator will yield all versions for all entries in the range less or equal to the given version. @@ -387,12 +387,12 @@ where &'a self, version: Version, range: R, - ) -> iterator::IterAll<'a, K, V, A, RC, Q, R> + ) -> iterator::Iter<'a, K, Option>, A, RC, Q, R> where K::Ref<'a>: KeyRef<'a, K>, Q: ?Sized + Comparable>, R: RangeBounds, { - iterator::IterAll::range(version, self, range, true) + iterator::Iter::range(version, self, range, true) } } diff --git a/src/generic/list/api/update.rs b/src/generic/list/api/update.rs index de57a3f..13e29be 100644 --- a/src/generic/list/api/update.rs +++ b/src/generic/list/api/update.rs @@ -3,7 +3,7 @@ use core::sync::atomic::Ordering; use among::Among; use dbutils::{ buffer::VacantBuffer, - types::{KeyRef, MaybeStructured, Type}, + types::{KeyRef, LazyRef, MaybeStructured, Type}, }; use either::Either; @@ -32,7 +32,7 @@ where version: Version, key: impl Into>, value: impl Into>, - ) -> Result>, Among> + ) -> Result, A, R>>, Among> where K::Ref<'a>: KeyRef<'a, K>, { @@ -50,7 +50,7 @@ where height: Height, key: impl Into>, value: impl Into>, - ) -> Result>, Among> + ) -> Result, A, R>>, Among> where K::Ref<'a>: KeyRef<'a, K>, { @@ -80,7 +80,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -104,7 +104,7 @@ where height: Height, key: impl Into>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result, A, R>>, Among> where K::Ref<'a>: KeyRef<'a, K>, { @@ -129,7 +129,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -147,7 +147,7 @@ where height: Height, key: impl Into>, value: impl Into>, - ) -> Result>, Among> + ) -> Result, A, R>>, Among> where K::Ref<'a>: KeyRef<'a, K>, { @@ -176,7 +176,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -201,7 +201,7 @@ where height: Height, key: impl Into>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result, A, R>>, Among> where K::Ref<'a>: KeyRef<'a, K>, { @@ -226,7 +226,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -249,7 +249,7 @@ where height: Height, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result, A, R>>, Among> where K::Ref<'a>: KeyRef<'a, K>, { @@ -279,7 +279,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -305,7 +305,7 @@ where height: Height, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result, A, R>>, Among> where K::Ref<'a>: KeyRef<'a, K>, { @@ -335,7 +335,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } }) }) @@ -362,7 +362,7 @@ where key: impl Into>, success: Ordering, failure: Ordering, - ) -> Result>, Either> + ) -> Result, A, R>>, Either> where K::Ref<'a>: KeyRef<'a, K>, { @@ -389,14 +389,14 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } } Err(current) => { if current.is_removed() { None } else { - Some(EntryRef(current)) + Some(current.map()) } } }, @@ -415,7 +415,7 @@ where version: Version, height: Height, key: impl Into>, - ) -> Result>, Either> + ) -> Result, A, R>>, Either> where K::Ref<'a>: KeyRef<'a, K>, { @@ -441,7 +441,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } } None => None, @@ -467,7 +467,7 @@ where version: Version, height: Height, key_builder: KeyBuilder) -> Result>, - ) -> Result>, Either> + ) -> Result, A, R>>, Either> where K::Ref<'a>: KeyRef<'a, K>, { @@ -495,7 +495,7 @@ where if old.is_removed() { None } else { - Some(EntryRef(old)) + Some(old.map()) } } None => None, diff --git a/src/generic/list/entry.rs b/src/generic/list/entry.rs index 87b9742..0783c2c 100644 --- a/src/generic/list/entry.rs +++ b/src/generic/list/entry.rs @@ -3,38 +3,38 @@ use dbutils::types::{KeyRef, LazyRef, Type}; use super::{RefCounter, SkipList}; use crate::{ allocator::{Allocator, Node, NodePointer, WithVersion}, + generic::GenericValue, types::internal::ValuePointer, Version, }; -/// A versioned entry reference of the skipmap. -/// -/// Compared to the [`EntryRef`], this one's value can be `None` which means the entry is removed. -pub struct VersionedEntryRef<'a, K, V, A, R> +/// An entry reference of the `SkipMap`. +pub struct EntryRef<'a, K, V, A, R> where K: ?Sized + Type, - V: ?Sized + Type, + V: GenericValue<'a>, A: Allocator, R: RefCounter, { - pub(super) list: &'a SkipList, + pub(super) list: &'a SkipList, pub(super) key: LazyRef<'a, K>, - pub(super) value: Option>, + pub(super) value: V, pub(super) value_part_pointer: ValuePointer, pub(super) version: Version, pub(super) query_version: Version, pub(super) ptr: ::Pointer, } -impl core::fmt::Debug for VersionedEntryRef<'_, K, V, A, R> +impl<'a, K, V, A, R> core::fmt::Debug for EntryRef<'a, K, V, A, R> where K: ?Sized + Type, - V: ?Sized + Type, + V: GenericValue<'a>, + V::Ref: core::fmt::Debug, A: Allocator, R: RefCounter, { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("VersionedEntryRef") + f.debug_struct("EntryRef") .field("key", &self.key()) .field("value", &self.value()) .field("version", &self.version) @@ -42,12 +42,11 @@ where } } -impl<'a, K, V, A, R> Clone for VersionedEntryRef<'a, K, V, A, R> +impl<'a, K, V, A, R> Clone for EntryRef<'a, K, V, A, R> where K: ?Sized + Type, K::Ref<'a>: Clone, - V: ?Sized + Type, - V::Ref<'a>: Clone, + V: GenericValue<'a> + Clone, A: Allocator, R: RefCounter, { @@ -64,12 +63,37 @@ where } } -impl<'a, K, V, A, R> VersionedEntryRef<'a, K, V, A, R> +impl<'a, K, V, A, R> EntryRef<'a, K, Option>, A, R> where K: ?Sized + Type, + K::Ref<'a>: Clone, V: ?Sized + Type, A: Allocator, R: RefCounter, +{ + #[inline] + pub(super) fn map(self) -> EntryRef<'a, K, NV, A, R> + where + NV: GenericValue<'a, Value = V> + 'a, + { + EntryRef { + list: self.list, + key: self.key, + value: NV::from_lazy_ref(self.value), + value_part_pointer: self.value_part_pointer, + version: self.version, + query_version: self.query_version, + ptr: self.ptr, + } + } +} + +impl<'a, K, V, A, R> EntryRef<'a, K, V, A, R> +where + K: ?Sized + Type, + V: GenericValue<'a>, + A: Allocator, + R: RefCounter, { /// Returns the reference to the key #[inline] @@ -85,31 +109,28 @@ where /// Returns the reference to the value, `None` means the entry is removed. #[inline] - pub fn value(&self) -> Option<&V::Ref<'a>> { - self.value.as_deref() + pub fn value(&self) -> V::Ref { + self.value.as_ref() } /// Returns the value in raw bytes #[inline] pub fn raw_value(&self) -> Option<&'a [u8]> { - self - .value - .as_ref() - .map(|value| value.raw().expect("raw value must be available")) + self.value.raw() } /// Returns if the entry is marked as removed #[inline] pub fn is_removed(&self) -> bool { - self.value().is_none() + self.value.is_removed() } } -impl<'a, K, V, A, R> VersionedEntryRef<'a, K, V, A, R> +impl<'a, K, V, A, R> EntryRef<'a, K, V, A, R> where K: ?Sized + Type, K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, + V: GenericValue<'a> + 'a, A: Allocator, R: RefCounter, { @@ -164,10 +185,10 @@ where } } -impl VersionedEntryRef<'_, K, V, A, R> +impl<'a, K, V, A, R> EntryRef<'a, K, V, A, R> where K: ?Sized + Type, - V: ?Sized + Type, + V: GenericValue<'a>, A: Allocator, A::Node: WithVersion, R: RefCounter, @@ -179,10 +200,10 @@ where } } -impl<'a, K, V, A, R> VersionedEntryRef<'a, K, V, A, R> +impl<'a, K, V, A, R> EntryRef<'a, K, V, A, R> where K: ?Sized + Type, - V: ?Sized + Type, + V: GenericValue<'a> + 'a, A: Allocator, R: RefCounter, { @@ -190,7 +211,7 @@ where pub(crate) fn from_node( query_version: Version, node: ::Pointer, - list: &'a SkipList, + list: &'a SkipList, raw_key: Option<&'a [u8]>, key: Option>, ) -> Self { @@ -214,7 +235,7 @@ where Self { list, key, - value: raw_value.map(|raw_value| LazyRef::from_raw(raw_value)), + value: V::from_bytes(raw_value), value_part_pointer: vp, version: node.version(), query_version, @@ -227,7 +248,7 @@ where pub(crate) fn from_node_with_pointer( query_version: Version, node: ::Pointer, - list: &'a SkipList, + list: &'a SkipList, pointer: ValuePointer, raw_key: Option<&'a [u8]>, key: Option>, @@ -253,7 +274,7 @@ where Self { list, key, - value: raw_value.map(|raw_value| LazyRef::from_raw(raw_value)), + value: V::from_bytes(raw_value), value_part_pointer: pointer, version: node.version(), query_version, @@ -262,113 +283,3 @@ where } } } - -/// An entry reference to the skipmap's entry. -/// -/// Compared to the [`VersionedEntryRef`], this one's value cannot be `None`. -pub struct EntryRef<'a, K, V, A, R>(pub(crate) VersionedEntryRef<'a, K, V, A, R>) -where - K: Type + ?Sized, - V: Type + ?Sized, - A: Allocator, - R: RefCounter; - -impl core::fmt::Debug for EntryRef<'_, K, V, A, R> -where - K: ?Sized + Type, - V: ?Sized + Type, - A: Allocator, - R: RefCounter, -{ - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("EntryRef") - .field("key", &self.key()) - .field("value", &self.value()) - .finish() - } -} - -impl<'a, K, V, A, R> Clone for EntryRef<'a, K, V, A, R> -where - K: ?Sized + Type, - K::Ref<'a>: Clone, - V: ?Sized + Type, - V::Ref<'a>: Clone, - A: Allocator, - R: RefCounter, -{ - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl<'a, K, V, A, R> EntryRef<'a, K, V, A, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - R: RefCounter, -{ - /// Returns the next entry in the map. - #[inline] - pub fn next(&self) -> Option { - self.0.next_in(false).map(Self) - } - - /// Returns the previous entry in the map. - #[inline] - pub fn prev(&self) -> Option { - self.0.prev_in(false).map(Self) - } -} - -impl EntryRef<'_, K, V, A, R> -where - K: ?Sized + Type, - V: ?Sized + Type, - A: Allocator, - A::Node: WithVersion, - R: RefCounter, -{ - /// Returns the version of the entry - #[inline] - pub fn version(&self) -> Version { - self.0.version() - } -} - -impl<'a, K, V, A, R> EntryRef<'a, K, V, A, R> -where - K: ?Sized + Type, - V: ?Sized + Type, - A: Allocator, - R: RefCounter, -{ - /// Returns the reference to the key - #[inline] - pub fn key(&self) -> &K::Ref<'a> { - self.0.key() - } - - /// Returns the key in raw bytes - #[inline] - pub fn raw_key(&self) -> &'a [u8] { - self.0.raw_key() - } - - /// Returns the reference to the value, `None` means the entry is removed. - #[inline] - pub fn value(&self) -> &V::Ref<'a> { - self.0.value().expect("EntryRef's value cannot be `None`") - } - - /// Returns the value in raw bytes - #[inline] - pub fn raw_value(&self) -> &'a [u8] { - self - .0 - .raw_value() - .expect("EntryRef's raw value cannot be `None`") - } -} diff --git a/src/generic/list/iterator.rs b/src/generic/list/iterator.rs index da39ae8..ccec244 100644 --- a/src/generic/list/iterator.rs +++ b/src/generic/list/iterator.rs @@ -1,5 +1,699 @@ -mod all_versions; -pub use all_versions::*; +use core::ops::{Bound, RangeBounds}; -mod iter; -pub use iter::*; +use dbutils::{ + equivalent::{Comparable, ComparableRangeBounds}, + types::{KeyRef, Type}, +}; + +use crate::{allocator::Node, generic::GenericValue}; + +use super::{Allocator, EntryRef, NodePointer, RefCounter, SkipList, Version}; + +/// An iterator over the skipmap (this iterator will yields all versions). The current state of the iterator can be cloned by +/// simply value copying the struct. +pub struct Iter<'a, K, L, A, RC, Q = ::Ref<'a>, R = core::ops::RangeFull> +where + A: Allocator, + K: ?Sized + Type, + L: GenericValue<'a>, + Q: ?Sized, + RC: RefCounter, +{ + pub(super) map: &'a SkipList, + pub(super) version: Version, + pub(super) range: Option, + pub(super) all_versions: bool, + pub(super) head: Option>, + pub(super) tail: Option>, + pub(super) _phantom: core::marker::PhantomData, +} + +impl<'a, K, L, A, RC, Q, R: Clone> Clone for Iter<'a, K, L, A, RC, Q, R> +where + K: ?Sized + Type, + K::Ref<'a>: Clone, + L: GenericValue<'a> + Clone, + A: Allocator, + Q: ?Sized, + RC: RefCounter, +{ + fn clone(&self) -> Self { + Self { + map: self.map, + head: self.head.clone(), + tail: self.tail.clone(), + version: self.version, + range: self.range.clone(), + all_versions: self.all_versions, + _phantom: core::marker::PhantomData, + } + } +} + +impl<'a, K, L, A, RC> Iter<'a, K, L, A, RC> +where + K: ?Sized + Type, + K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a>, + A: Allocator, + RC: RefCounter, +{ + #[inline] + pub(crate) const fn new( + version: Version, + map: &'a SkipList, + all_versions: bool, + ) -> Self { + Self { + map, + head: None, + tail: None, + version, + range: None, + all_versions, + _phantom: core::marker::PhantomData, + } + } +} + +impl<'a, K, L, A, RC, Q, R> Iter<'a, K, L, A, RC, Q, R> +where + K: ?Sized + Type, + K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a>, + A: Allocator, + RC: RefCounter, + Q: ?Sized, +{ + #[inline] + pub(crate) fn range( + version: Version, + map: &'a SkipList, + r: R, + all_versions: bool, + ) -> Self { + Self { + map, + head: None, + tail: None, + version, + range: Some(r), + all_versions, + _phantom: core::marker::PhantomData, + } + } +} + +impl<'a, K, L, A, RC, Q, R> Iter<'a, K, L, A, RC, Q, R> +where + K: ?Sized + Type, + K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a>, + A: Allocator, + RC: RefCounter, + R: RangeBounds, + Q: ?Sized, +{ + /// Returns the start bound of the iterator. + #[inline] + pub fn start_bound(&self) -> Bound<&Q> { + self + .range + .as_ref() + .map(|r| r.start_bound()) + .unwrap_or(Bound::Unbounded) + } + + /// Returns the end bound of the iterator. + #[inline] + pub fn end_bound(&self) -> Bound<&Q> { + self + .range + .as_ref() + .map(|r| r.end_bound()) + .unwrap_or(Bound::Unbounded) + } + + /// Returns the entry at the current head position of the iterator. + #[inline] + pub const fn head(&self) -> Option<&EntryRef<'a, K, L, A, RC>> { + self.head.as_ref() + } + + /// Returns the entry at the current tail position of the iterator. + #[inline] + pub const fn tail(&self) -> Option<&EntryRef<'a, K, L, A, RC>> { + self.tail.as_ref() + } +} + +impl<'a, K, L, A, RC, Q, R> Iter<'a, K, L, A, RC, Q, R> +where + K: ?Sized + Type, + K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a> + Clone + 'a, + A: Allocator, + RC: RefCounter, + Q: ?Sized + Comparable>, + R: RangeBounds, +{ + /// Advances to the next position. Returns the key and value if the + /// iterator is pointing at a valid entry, and `None` otherwise. + fn next_in(&mut self) -> Option> { + unsafe { + let mut next_head = match self.head.as_ref() { + Some(head) => self.map.get_next(head.ptr, 0), + None => self.map.get_next(self.map.head, 0), + }; + + let next_head = if self.all_versions { + self + .map + .move_to_next(&mut next_head, self.version, |nk| self.check_bounds(nk)) + } else { + self + .map + .move_to_next_maximum_version(&mut next_head, self.version, |nk| { + if let Some(ref head) = self.head { + head.key().ne(nk) && self.check_bounds(nk) + } else { + self.check_bounds(nk) + } + }) + }; + + match (&next_head, &self.tail) { + (Some(next), Some(t)) + if next + .key() + .cmp(t.key()) + .then_with(|| t.version.cmp(&next.version)) + .is_ge() => + { + self.head = next_head; + None + } + (Some(_), _) => { + self.head = next_head.clone(); + next_head + } + (None, _) => { + self.head = next_head; + None + } + } + } + } + + /// Advances to the prev position. Returns the key and value if the + /// iterator is pointing at a valid entry, and `None` otherwise. + fn prev(&mut self) -> Option> { + unsafe { + let mut next_tail = match self.tail.as_ref() { + Some(tail) => self.map.get_prev(tail.ptr, 0), + None => self.map.get_prev(self.map.tail, 0), + }; + + let next_tail = if self.all_versions { + self + .map + .move_to_prev(&mut next_tail, self.version, |nk| self.check_bounds(nk)) + } else { + self + .map + .move_to_prev_maximum_version(&mut next_tail, self.version, |nk| { + if let Some(ref tail) = self.tail { + tail.key().ne(nk) && self.check_bounds(nk) + } else { + self.check_bounds(nk) + } + }) + }; + + match (&self.head, &next_tail) { + // The prev key is smaller than the latest head key we observed with this iterator. + (Some(h), Some(next)) + if h + .key() + .cmp(next.key()) + .then_with(|| h.version.cmp(&next.version)) + .is_ge() => + { + self.tail = next_tail; + None + } + (_, Some(_)) => { + self.tail = next_tail.clone(); + next_tail + } + (_, None) => { + self.tail = next_tail; + None + } + } + } + } + + fn range_next_in(&mut self) -> Option> { + unsafe { + let mut next_head = match self.head.as_ref() { + Some(head) => self.map.get_next(head.ptr, 0), + None => match self.range.as_ref().unwrap().start_bound() { + Bound::Included(key) => self + .map + .find_near(self.version, key, false, true) + .0 + .unwrap_or(::Pointer::NULL), + Bound::Excluded(key) => self + .map + .find_near(Version::MIN, key, false, false) + .0 + .unwrap_or(::Pointer::NULL), + Bound::Unbounded => self.map.get_next(self.map.head, 0), + }, + }; + + self.head = if self.all_versions { + self + .map + .move_to_next(&mut next_head, self.version, |nk| self.check_bounds(nk)) + } else { + self + .map + .move_to_next_maximum_version(&mut next_head, self.version, |nk| { + if let Some(ref head) = self.head { + head.key().ne(nk) && self.check_bounds(nk) + } else { + self.check_bounds(nk) + } + }) + }; + + if let Some(ref h) = self.head { + match &self.tail { + Some(t) => { + let bound = Bound::Excluded(t.key()); + if !below_upper_bound(&bound, h.key()) { + self.head = None; + self.tail = None; + } + } + None => { + let bound = self.range.as_ref().unwrap().end_bound(); + if !below_upper_bound_compare(&bound, h.key()) { + self.head = None; + self.tail = None; + } + } + } + } + + self.head.clone() + } + } + + fn range_prev(&mut self) -> Option> { + unsafe { + let mut next_tail = match self.tail.as_ref() { + Some(tail) => self.map.get_prev(tail.ptr, 0), + None => match self.range.as_ref().unwrap().end_bound() { + Bound::Included(key) => self + .map + .find_near(Version::MIN, key, true, true) + .0 + .unwrap_or(::Pointer::NULL), + Bound::Excluded(key) => self + .map + .find_near(self.version, key, true, false) + .0 + .unwrap_or(::Pointer::NULL), + Bound::Unbounded => self.map.get_prev(self.map.tail, 0), + }, + }; + + self.tail = if self.all_versions { + self + .map + .move_to_prev(&mut next_tail, self.version, |nk| self.check_bounds(nk)) + } else { + self + .map + .move_to_prev_maximum_version(&mut next_tail, self.version, |nk| { + if let Some(ref tail) = self.tail { + tail.key().ne(nk) && self.check_bounds(nk) + } else { + self.check_bounds(nk) + } + }) + }; + + if let Some(ref t) = self.tail { + match &self.head { + Some(h) => { + let bound = Bound::Excluded(h.key()); + if !above_lower_bound(&bound, t.key()) { + self.head = None; + self.tail = None; + } + } + None => { + let bound = self.range.as_ref().unwrap().start_bound(); + if !above_lower_bound_compare(&bound, t.key()) { + self.head = None; + self.tail = None; + } + } + } + } + + self.tail.clone() + } + } +} + +impl<'a, K, L, A, RC, Q, R> Iter<'a, K, L, A, RC, Q, R> +where + K: ?Sized + Type, + K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a> + Clone + 'a, + A: Allocator, + RC: RefCounter, + Q: ?Sized + Comparable>, + R: RangeBounds, +{ + /// Moves the iterator to the highest element whose key is below the given bound. + /// If no such element is found then `None` is returned. + /// + /// **Note:** This method will clear the current state of the iterator. + pub fn seek_upper_bound(&mut self, upper: Bound<&QR>) -> Option> + where + QR: ?Sized + Comparable>, + { + self.head = None; + self.tail = None; + + match upper { + Bound::Included(key) => self.seek_le(key).inspect(|ent| { + self.head = Some(ent.clone()); + }), + Bound::Excluded(key) => self.seek_lt(key).inspect(|ent| { + self.head = Some(ent.clone()); + }), + Bound::Unbounded => self.last(), + } + } + + /// Moves the iterator to the lowest element whose key is above the given bound. + /// If no such element is found then `None` is returned. + /// + /// **Note:** This method will clear the current state of the iterator. + pub fn seek_lower_bound(&mut self, lower: Bound<&QR>) -> Option> + where + QR: ?Sized + Comparable>, + { + self.head = None; + self.tail = None; + + match lower { + Bound::Included(key) => self.seek_ge(key).inspect(|ent| { + self.head = Some(ent.clone()); + }), + Bound::Excluded(key) => self.seek_gt(key).inspect(|ent| { + self.head = Some(ent.clone()); + }), + Bound::Unbounded => self.first(), + } + } + + /// Moves the iterator to the first entry whose key is greater than or + /// equal to the given key. Returns the key and value if the iterator is + /// pointing at a valid entry, and `None` otherwise. + fn seek_ge(&self, key: &QR) -> Option> + where + QR: ?Sized + Comparable>, + { + unsafe { + let (n, _) = self.map.find_near(self.version, key, false, true); + + let mut n = n?; + if n.is_null() || n.offset() == self.map.tail.offset() { + return None; + } + + if self.all_versions { + self.map.move_to_next(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + range.compare_contains(nk) + } else { + true + } + }) + } else { + self + .map + .move_to_next_maximum_version(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + range.compare_contains(nk) + } else { + true + } + }) + } + } + } + + /// Moves the iterator to the first entry whose key is greater than + /// the given key. Returns the key and value if the iterator is + /// pointing at a valid entry, and `None` otherwise. + fn seek_gt(&self, key: &QR) -> Option> + where + QR: ?Sized + Comparable>, + { + unsafe { + let (n, _) = self.map.find_near(Version::MIN, key, false, false); + + let mut n = n?; + if n.is_null() || n.offset() == self.map.tail.offset() { + return None; + } + + if self.all_versions { + self.map.move_to_next(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + range.compare_contains(nk) + } else { + true + } + }) + } else { + self + .map + .move_to_next_maximum_version(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + range.compare_contains(nk) + } else { + true + } + }) + } + } + } + + /// Moves the iterator to the first entry whose key is less than or + /// equal to the given key. Returns the key and value if the iterator is + /// pointing at a valid entry, and `None` otherwise. + fn seek_le(&self, key: &QR) -> Option> + where + QR: ?Sized + Comparable>, + { + unsafe { + let (n, _) = self.map.find_near(Version::MIN, key, true, true); // find less or equal. + + let mut n = n?; + if n.is_null() || n.offset() == self.map.head.offset() { + return None; + } + + if self.all_versions { + self.map.move_to_prev(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + range.compare_contains(nk) + } else { + true + } + }) + } else { + self + .map + .move_to_prev_maximum_version(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + range.compare_contains(nk) + } else { + true + } + }) + } + } + } + + /// Moves the iterator to the last entry whose key is less than the given + /// key. Returns the key and value if the iterator is pointing at a valid entry, + /// and `None` otherwise. + fn seek_lt(&self, key: &QR) -> Option> + where + QR: ?Sized + Comparable>, + { + unsafe { + let (n, _) = self.map.find_near(self.version, key, true, false); // find less or equal. + + let mut n = n?; + if n.is_null() || n.offset() == self.map.head.offset() { + return None; + } + + if self.all_versions { + self.map.move_to_prev(&mut n, self.version, |nk| { + if let Some(ref range) = self.range { + range.compare_contains(nk) + } else { + true + } + }) + } else { + self + .map + .move_to_prev_maximum_version(&mut n, self.version, |nk| self.check_bounds(nk)) + } + } + } + + #[inline] + fn first(&mut self) -> Option> { + self.head = None; + self.tail = None; + self.next() + } + + #[inline] + fn last(&mut self) -> Option> { + self.tail = None; + self.head = None; + self.prev() + } + + #[inline] + fn check_bounds(&self, nk: &K::Ref<'a>) -> bool { + if let Some(ref range) = self.range { + range.compare_contains(nk) + } else { + true + } + } +} + +impl<'a, K, L, A, RC, Q, R> Iterator for Iter<'a, K, L, A, RC, Q, R> +where + K: ?Sized + Type, + K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a> + Clone + 'a, + A: Allocator, + RC: RefCounter, + Q: ?Sized + Comparable>, + R: RangeBounds, +{ + type Item = EntryRef<'a, K, L, A, RC>; + + #[inline] + fn next(&mut self) -> Option { + if self.range.is_some() { + self.range_next_in() + } else { + self.next_in() + } + } + + #[inline] + fn last(mut self) -> Option + where + Self: Sized, + { + Iter::last(&mut self) + } + + #[inline] + fn max(self) -> Option + where + Self: Sized, + Self::Item: Ord, + { + self.last() + } + + #[inline] + fn min(mut self) -> Option + where + Self: Sized, + Self::Item: Ord, + { + self.first() + } +} + +impl<'a, K, L, A, RC, Q, R> DoubleEndedIterator for Iter<'a, K, L, A, RC, Q, R> +where + K: ?Sized + Type, + K::Ref<'a>: KeyRef<'a, K>, + L: GenericValue<'a> + Clone + 'a, + A: Allocator, + RC: RefCounter, + Q: ?Sized + Comparable>, + R: RangeBounds, +{ + #[inline] + fn next_back(&mut self) -> Option { + if self.range.is_some() { + self.range_prev() + } else { + self.prev() + } + } +} + +/// Helper function to check if a value is above a lower bound +fn above_lower_bound_compare>(bound: &Bound<&T>, other: &V) -> bool { + match *bound { + Bound::Unbounded => true, + Bound::Included(key) => key.compare(other).is_le(), + Bound::Excluded(key) => key.compare(other).is_lt(), + } +} + +/// Helper function to check if a value is above a lower bound +fn above_lower_bound(bound: &Bound<&K>, other: &K) -> bool { + match *bound { + Bound::Unbounded => true, + Bound::Included(key) => key.cmp(other).is_le(), + Bound::Excluded(key) => key.cmp(other).is_lt(), + } +} + +/// Helper function to check if a value is below an upper bound +fn below_upper_bound_compare>( + bound: &Bound<&T>, + other: &V, +) -> bool { + match *bound { + Bound::Unbounded => true, + Bound::Included(key) => key.compare(other).is_ge(), + Bound::Excluded(key) => key.compare(other).is_gt(), + } +} + +/// Helper function to check if a value is below an upper bound +fn below_upper_bound(bound: &Bound<&K>, other: &K) -> bool { + match *bound { + Bound::Unbounded => true, + Bound::Included(key) => key.cmp(other).is_ge(), + Bound::Excluded(key) => key.cmp(other).is_gt(), + } +} diff --git a/src/generic/list/iterator/all_versions.rs b/src/generic/list/iterator/all_versions.rs deleted file mode 100644 index 88f1135..0000000 --- a/src/generic/list/iterator/all_versions.rs +++ /dev/null @@ -1,717 +0,0 @@ -use core::ops::{Bound, RangeBounds}; - -use dbutils::{ - equivalent::{Comparable, ComparableRangeBounds}, - types::{KeyRef, Type}, -}; - -use crate::allocator::Node; - -use super::super::{Allocator, NodePointer, RefCounter, SkipList, Version, VersionedEntryRef}; - -/// An iterator over the skipmap (this iterator will yields all versions). The current state of the iterator can be cloned by -/// simply value copying the struct. -pub struct IterAll<'a, K, V, A, RC, Q = ::Ref<'a>, R = core::ops::RangeFull> -where - A: Allocator, - K: ?Sized + Type, - V: ?Sized + Type, - Q: ?Sized, - RC: RefCounter, -{ - pub(super) map: &'a SkipList, - pub(super) version: Version, - pub(super) range: Option, - pub(super) all_versions: bool, - pub(super) head: Option>, - pub(super) tail: Option>, - pub(super) _phantom: core::marker::PhantomData, -} - -impl<'a, K, V, A, RC, Q, R: Clone> Clone for IterAll<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: Clone, - V: ?Sized + Type, - A: Allocator, - Q: ?Sized, - RC: RefCounter, -{ - fn clone(&self) -> Self { - Self { - map: self.map, - head: self.head.clone(), - tail: self.tail.clone(), - version: self.version, - range: self.range.clone(), - all_versions: self.all_versions, - _phantom: core::marker::PhantomData, - } - } -} - -impl<'a, K, V, A, RC, Q, R: Copy> Copy for IterAll<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: Copy, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - VersionedEntryRef<'a, K, V, A, RC>: Copy, - Q: ?Sized, -{ -} - -impl<'a, K, V, A, RC> IterAll<'a, K, V, A, RC> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, -{ - #[inline] - pub(crate) const fn new( - version: Version, - map: &'a SkipList, - all_versions: bool, - ) -> Self { - Self { - map, - head: None, - tail: None, - version, - range: None, - all_versions, - _phantom: core::marker::PhantomData, - } - } -} - -impl<'a, K, V, A, RC, Q, R> IterAll<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized, -{ - #[inline] - pub(crate) fn range( - version: Version, - map: &'a SkipList, - r: R, - all_versions: bool, - ) -> Self { - Self { - map, - head: None, - tail: None, - version, - range: Some(r), - all_versions, - _phantom: core::marker::PhantomData, - } - } -} - -impl<'a, K, V, A, RC, Q, R> IterAll<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - R: RangeBounds, - Q: ?Sized, -{ - /// Returns the start bound of the iterator. - #[inline] - pub fn start_bound(&self) -> Bound<&Q> { - self - .range - .as_ref() - .map(|r| r.start_bound()) - .unwrap_or(Bound::Unbounded) - } - - /// Returns the end bound of the iterator. - #[inline] - pub fn end_bound(&self) -> Bound<&Q> { - self - .range - .as_ref() - .map(|r| r.end_bound()) - .unwrap_or(Bound::Unbounded) - } - - /// Returns the entry at the current head position of the iterator. - #[inline] - pub const fn head(&self) -> Option<&VersionedEntryRef<'a, K, V, A, RC>> { - self.head.as_ref() - } - - /// Returns the entry at the current tail position of the iterator. - #[inline] - pub const fn tail(&self) -> Option<&VersionedEntryRef<'a, K, V, A, RC>> { - self.tail.as_ref() - } -} - -impl<'a, K, V, A, RC, Q, R> IterAll<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized + Comparable>, - R: RangeBounds, -{ - /// Advances to the next position. Returns the key and value if the - /// iterator is pointing at a valid entry, and `None` otherwise. - fn next_in(&mut self) -> Option> { - unsafe { - let mut next_head = match self.head.as_ref() { - Some(head) => self.map.get_next(head.ptr, 0), - None => self.map.get_next(self.map.head, 0), - }; - - let next_head = if self.all_versions { - self - .map - .move_to_next(&mut next_head, self.version, |nk| self.check_bounds(nk)) - } else { - self - .map - .move_to_next_maximum_version(&mut next_head, self.version, |nk| { - if let Some(ref head) = self.head { - head.key().ne(nk) && self.check_bounds(nk) - } else { - self.check_bounds(nk) - } - }) - }; - - match (&next_head, &self.tail) { - (Some(next), Some(t)) - if next - .key() - .cmp(t.key()) - .then_with(|| t.version.cmp(&next.version)) - .is_ge() => - { - self.head = next_head; - None - } - (Some(_), _) => { - self.head = next_head.clone(); - next_head - } - (None, _) => { - self.head = next_head; - None - } - } - } - } - - /// Advances to the prev position. Returns the key and value if the - /// iterator is pointing at a valid entry, and `None` otherwise. - fn prev(&mut self) -> Option> { - unsafe { - let mut next_tail = match self.tail.as_ref() { - Some(tail) => self.map.get_prev(tail.ptr, 0), - None => self.map.get_prev(self.map.tail, 0), - }; - - let next_tail = if self.all_versions { - self - .map - .move_to_prev(&mut next_tail, self.version, |nk| self.check_bounds(nk)) - } else { - self - .map - .move_to_prev_maximum_version(&mut next_tail, self.version, |nk| { - if let Some(ref tail) = self.tail { - tail.key().ne(nk) && self.check_bounds(nk) - } else { - self.check_bounds(nk) - } - }) - }; - - match (&self.head, &next_tail) { - // The prev key is smaller than the latest head key we observed with this iterator. - (Some(h), Some(next)) - if h - .key() - .cmp(next.key()) - .then_with(|| h.version.cmp(&next.version)) - .is_ge() => - { - self.tail = next_tail; - None - } - (_, Some(_)) => { - self.tail = next_tail.clone(); - next_tail - } - (_, None) => { - self.tail = next_tail; - None - } - } - } - } - - fn range_next_in(&mut self) -> Option> { - unsafe { - let mut next_head = match self.head.as_ref() { - Some(head) => self.map.get_next(head.ptr, 0), - None => match self.range.as_ref().unwrap().start_bound() { - Bound::Included(key) => self - .map - .find_near(self.version, key, false, true) - .0 - .unwrap_or(::Pointer::NULL), - Bound::Excluded(key) => self - .map - .find_near(Version::MIN, key, false, false) - .0 - .unwrap_or(::Pointer::NULL), - Bound::Unbounded => self.map.get_next(self.map.head, 0), - }, - }; - - self.head = if self.all_versions { - self - .map - .move_to_next(&mut next_head, self.version, |nk| self.check_bounds(nk)) - } else { - self - .map - .move_to_next_maximum_version(&mut next_head, self.version, |nk| { - if let Some(ref head) = self.head { - head.key().ne(nk) && self.check_bounds(nk) - } else { - self.check_bounds(nk) - } - }) - }; - - if let Some(ref h) = self.head { - match &self.tail { - Some(t) => { - let bound = Bound::Excluded(t.key()); - if !below_upper_bound(&bound, h.key()) { - self.head = None; - self.tail = None; - } - } - None => { - let bound = self.range.as_ref().unwrap().end_bound(); - if !below_upper_bound_compare(&bound, h.key()) { - self.head = None; - self.tail = None; - } - } - } - } - - self.head.clone() - } - } - - fn range_prev(&mut self) -> Option> { - unsafe { - let mut next_tail = match self.tail.as_ref() { - Some(tail) => self.map.get_prev(tail.ptr, 0), - None => match self.range.as_ref().unwrap().end_bound() { - Bound::Included(key) => self - .map - .find_near(Version::MIN, key, true, true) - .0 - .unwrap_or(::Pointer::NULL), - Bound::Excluded(key) => self - .map - .find_near(self.version, key, true, false) - .0 - .unwrap_or(::Pointer::NULL), - Bound::Unbounded => self.map.get_prev(self.map.tail, 0), - }, - }; - - self.tail = if self.all_versions { - self - .map - .move_to_prev(&mut next_tail, self.version, |nk| self.check_bounds(nk)) - } else { - self - .map - .move_to_prev_maximum_version(&mut next_tail, self.version, |nk| { - if let Some(ref tail) = self.tail { - tail.key().ne(nk) && self.check_bounds(nk) - } else { - self.check_bounds(nk) - } - }) - }; - - if let Some(ref t) = self.tail { - match &self.head { - Some(h) => { - let bound = Bound::Excluded(h.key()); - if !above_lower_bound(&bound, t.key()) { - self.head = None; - self.tail = None; - } - } - None => { - let bound = self.range.as_ref().unwrap().start_bound(); - if !above_lower_bound_compare(&bound, t.key()) { - self.head = None; - self.tail = None; - } - } - } - } - - self.tail.clone() - } - } -} - -impl<'a, K, V, A, RC, Q, R> IterAll<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized + Comparable>, - R: RangeBounds, -{ - /// Moves the iterator to the highest element whose key is below the given bound. - /// If no such element is found then `None` is returned. - /// - /// **Note:** This method will clear the current state of the iterator. - pub fn seek_upper_bound( - &mut self, - upper: Bound<&QR>, - ) -> Option> - where - QR: ?Sized + Comparable>, - { - self.head = None; - self.tail = None; - - match upper { - Bound::Included(key) => self.seek_le(key).inspect(|ent| { - self.head = Some(ent.clone()); - }), - Bound::Excluded(key) => self.seek_lt(key).inspect(|ent| { - self.head = Some(ent.clone()); - }), - Bound::Unbounded => self.last(), - } - } - - /// Moves the iterator to the lowest element whose key is above the given bound. - /// If no such element is found then `None` is returned. - /// - /// **Note:** This method will clear the current state of the iterator. - pub fn seek_lower_bound( - &mut self, - lower: Bound<&QR>, - ) -> Option> - where - QR: ?Sized + Comparable>, - { - self.head = None; - self.tail = None; - - match lower { - Bound::Included(key) => self.seek_ge(key).inspect(|ent| { - self.head = Some(ent.clone()); - }), - Bound::Excluded(key) => self.seek_gt(key).inspect(|ent| { - self.head = Some(ent.clone()); - }), - Bound::Unbounded => self.first(), - } - } - - /// Moves the iterator to the first entry whose key is greater than or - /// equal to the given key. Returns the key and value if the iterator is - /// pointing at a valid entry, and `None` otherwise. - fn seek_ge(&self, key: &QR) -> Option> - where - QR: ?Sized + Comparable>, - { - unsafe { - let (n, _) = self.map.find_near(self.version, key, false, true); - - let mut n = n?; - if n.is_null() || n.offset() == self.map.tail.offset() { - return None; - } - - if self.all_versions { - self.map.move_to_next(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - range.compare_contains(nk) - } else { - true - } - }) - } else { - self - .map - .move_to_next_maximum_version(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - range.compare_contains(nk) - } else { - true - } - }) - } - } - } - - /// Moves the iterator to the first entry whose key is greater than - /// the given key. Returns the key and value if the iterator is - /// pointing at a valid entry, and `None` otherwise. - fn seek_gt(&self, key: &QR) -> Option> - where - QR: ?Sized + Comparable>, - { - unsafe { - let (n, _) = self.map.find_near(Version::MIN, key, false, false); - - let mut n = n?; - if n.is_null() || n.offset() == self.map.tail.offset() { - return None; - } - - if self.all_versions { - self.map.move_to_next(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - range.compare_contains(nk) - } else { - true - } - }) - } else { - self - .map - .move_to_next_maximum_version(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - range.compare_contains(nk) - } else { - true - } - }) - } - } - } - - /// Moves the iterator to the first entry whose key is less than or - /// equal to the given key. Returns the key and value if the iterator is - /// pointing at a valid entry, and `None` otherwise. - fn seek_le(&self, key: &QR) -> Option> - where - QR: ?Sized + Comparable>, - { - unsafe { - let (n, _) = self.map.find_near(Version::MIN, key, true, true); // find less or equal. - - let mut n = n?; - if n.is_null() || n.offset() == self.map.head.offset() { - return None; - } - - if self.all_versions { - self.map.move_to_prev(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - range.compare_contains(nk) - } else { - true - } - }) - } else { - self - .map - .move_to_prev_maximum_version(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - range.compare_contains(nk) - } else { - true - } - }) - } - } - } - - /// Moves the iterator to the last entry whose key is less than the given - /// key. Returns the key and value if the iterator is pointing at a valid entry, - /// and `None` otherwise. - fn seek_lt(&self, key: &QR) -> Option> - where - QR: ?Sized + Comparable>, - { - unsafe { - let (n, _) = self.map.find_near(self.version, key, true, false); // find less or equal. - - let mut n = n?; - if n.is_null() || n.offset() == self.map.head.offset() { - return None; - } - - if self.all_versions { - self.map.move_to_prev(&mut n, self.version, |nk| { - if let Some(ref range) = self.range { - range.compare_contains(nk) - } else { - true - } - }) - } else { - self - .map - .move_to_prev_maximum_version(&mut n, self.version, |nk| self.check_bounds(nk)) - } - } - } - - #[inline] - fn first(&mut self) -> Option> { - self.head = None; - self.tail = None; - self.next() - } - - #[inline] - fn last(&mut self) -> Option> { - self.tail = None; - self.head = None; - self.prev() - } - - #[inline] - fn check_bounds(&self, nk: &K::Ref<'a>) -> bool { - if let Some(ref range) = self.range { - range.compare_contains(nk) - } else { - true - } - } -} - -impl<'a, K, V, A, RC, Q, R> Iterator for IterAll<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized + Comparable>, - R: RangeBounds, -{ - type Item = VersionedEntryRef<'a, K, V, A, RC>; - - #[inline] - fn next(&mut self) -> Option { - if self.range.is_some() { - self.range_next_in() - } else { - self.next_in() - } - } - - #[inline] - fn last(mut self) -> Option - where - Self: Sized, - { - IterAll::last(&mut self) - } - - #[inline] - fn max(self) -> Option - where - Self: Sized, - Self::Item: Ord, - { - self.last() - } - - #[inline] - fn min(mut self) -> Option - where - Self: Sized, - Self::Item: Ord, - { - self.first() - } -} - -impl<'a, K, V, A, RC, Q, R> DoubleEndedIterator for IterAll<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized + Comparable>, - R: RangeBounds, -{ - #[inline] - fn next_back(&mut self) -> Option { - if self.range.is_some() { - self.range_prev() - } else { - self.prev() - } - } -} - -/// Helper function to check if a value is above a lower bound -fn above_lower_bound_compare>(bound: &Bound<&T>, other: &V) -> bool { - match *bound { - Bound::Unbounded => true, - Bound::Included(key) => key.compare(other).is_le(), - Bound::Excluded(key) => key.compare(other).is_lt(), - } -} - -/// Helper function to check if a value is above a lower bound -fn above_lower_bound(bound: &Bound<&K>, other: &K) -> bool { - match *bound { - Bound::Unbounded => true, - Bound::Included(key) => key.cmp(other).is_le(), - Bound::Excluded(key) => key.cmp(other).is_lt(), - } -} - -/// Helper function to check if a value is below an upper bound -fn below_upper_bound_compare>( - bound: &Bound<&T>, - other: &V, -) -> bool { - match *bound { - Bound::Unbounded => true, - Bound::Included(key) => key.compare(other).is_ge(), - Bound::Excluded(key) => key.compare(other).is_gt(), - } -} - -/// Helper function to check if a value is below an upper bound -fn below_upper_bound(bound: &Bound<&K>, other: &K) -> bool { - match *bound { - Bound::Unbounded => true, - Bound::Included(key) => key.cmp(other).is_ge(), - Bound::Excluded(key) => key.cmp(other).is_gt(), - } -} diff --git a/src/generic/list/iterator/iter.rs b/src/generic/list/iterator/iter.rs deleted file mode 100644 index 3575a6f..0000000 --- a/src/generic/list/iterator/iter.rs +++ /dev/null @@ -1,188 +0,0 @@ -use core::ops::{Bound, RangeBounds}; - -use dbutils::{ - equivalent::Comparable, - types::{KeyRef, Type}, -}; - -use super::{ - super::{Allocator, EntryRef, RefCounter, SkipList, Version}, - IterAll, -}; - -/// An iterator over the skipmap. The current state of the iterator can be cloned by -/// simply value copying the struct. -pub struct Iter<'a, K, V, A, RC, Q = ::Ref<'a>, R = core::ops::RangeFull>( - IterAll<'a, K, V, A, RC, Q, R>, -) -where - A: Allocator, - RC: RefCounter, - K: ?Sized + Type, - V: ?Sized + Type, - Q: ?Sized; - -impl Clone for Iter<'_, K, V, A, RC, Q, R> -where - A: Allocator, - RC: RefCounter, - K: ?Sized + Type, - V: ?Sized + Type, - Q: ?Sized, -{ - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl<'a, K, V, A, RC> Iter<'a, K, V, A, RC> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, -{ - #[inline] - pub(crate) const fn new(version: Version, map: &'a SkipList) -> Self { - Self(IterAll::new(version, map, false)) - } -} - -impl<'a, K, V, A, RC, Q, R> Iter<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized, -{ - #[inline] - pub(crate) fn range(version: Version, map: &'a SkipList, r: R) -> Self { - Self(IterAll::range(version, map, r, false)) - } -} - -impl<'a, K, V, A, RC, Q, R> Iter<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized, - R: RangeBounds, -{ - /// Returns the start bound of the iterator. - #[inline] - pub fn start_bound(&self) -> Bound<&Q> { - self.0.start_bound() - } - - /// Returns the end bound of the iterator. - #[inline] - pub fn end_bound(&self) -> Bound<&Q> { - self.0.end_bound() - } -} - -impl<'a, K, V, A, RC, Q, R> Iter<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized, - R: RangeBounds, -{ - /// Returns the entry at the current head position of the iterator. - #[inline] - pub fn head(&self) -> Option> { - self.0.head().map(|e| EntryRef::(e.clone())) - } - - /// Returns the entry at the current tail position of the iterator. - #[inline] - pub fn tail(&self) -> Option> { - self.0.tail().map(|e| EntryRef::(e.clone())) - } -} - -impl<'a, K, V, A, RC, Q, R> Iter<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized + Comparable>, - R: RangeBounds, -{ - /// Moves the iterator to the highest element whose key is below the given bound. - /// If no such element is found then `None` is returned. - /// - /// **Note**: This method will clear the current state of the iterator. - pub fn seek_upper_bound(&mut self, upper: Bound<&QR>) -> Option> - where - QR: ?Sized + Comparable>, - { - self.0.seek_upper_bound(upper).map(EntryRef) - } - - /// Moves the iterator to the lowest element whose key is above the given bound. - /// If no such element is found then `None` is returned. - /// - /// **Note**: This method will clear the current state of the iterator. - pub(crate) fn seek_lower_bound( - &mut self, - lower: Bound<&QR>, - ) -> Option> - where - QR: ?Sized + Comparable>, - { - self.0.seek_lower_bound(lower).map(EntryRef) - } -} - -impl<'a, K, V, A, RC, Q, R> Iterator for Iter<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized + Comparable>, - R: RangeBounds, -{ - type Item = EntryRef<'a, K, V, A, RC>; - - #[inline] - fn next(&mut self) -> Option { - self.0.next().map(EntryRef) - } - - #[inline] - fn last(self) -> Option - where - Self: Sized, - { - self.0.last().map(EntryRef) - } -} - -impl<'a, K, V, A, RC, Q, R> DoubleEndedIterator for Iter<'a, K, V, A, RC, Q, R> -where - K: ?Sized + Type, - K::Ref<'a>: KeyRef<'a, K>, - V: ?Sized + Type, - A: Allocator, - RC: RefCounter, - Q: ?Sized + Comparable>, - R: RangeBounds, -{ - fn next_back(&mut self) -> Option { - self.0.next_back().map(EntryRef) - } -} diff --git a/src/generic/multiple_version.rs b/src/generic/multiple_version.rs index 7972e19..00e7fcc 100644 --- a/src/generic/multiple_version.rs +++ b/src/generic/multiple_version.rs @@ -7,7 +7,7 @@ use among::Among; use dbutils::{ buffer::VacantBuffer, equivalent::Comparable, - types::{KeyRef, MaybeStructured, Type}, + types::{KeyRef, LazyRef, MaybeStructured, Type}, }; use either::Either; @@ -18,10 +18,7 @@ use crate::{ Arena, Header, Height, KeyBuilder, ValueBuilder, Version, }; -use super::list::{ - iterator::{Iter, IterAll}, - EntryRef, VersionedEntryRef, -}; +use super::list::{iterator::Iter, EntryRef}; /// Implementations for single-threaded environments. pub mod unsync { @@ -35,24 +32,17 @@ pub mod unsync { type SkipList = super::super::list::SkipList; /// Iterator over the [`SkipMap`]. - pub type Iter<'a, K, V> = super::super::iter::Iter<'a, K, V, Allocator, RefCounter>; + pub type Iter<'a, K, L> = super::super::iter::Iter<'a, K, L, Allocator, RefCounter>; /// Iterator over a subset of the [`SkipMap`]. - pub type Range<'a, K, V, Q, R> = super::super::iter::Iter<'a, K, V, Allocator, RefCounter, Q, R>; + pub type Range<'a, K, L, Q, R> = super::super::iter::Iter<'a, K, L, Allocator, RefCounter, Q, R>; /// The entry reference of the [`SkipMap`]. pub type Entry<'a, K, V> = super::super::entry::EntryRef<'a, K, V, Allocator, RefCounter>; /// The versioned entry reference of the [`SkipMap`]. pub type VersionedEntry<'a, K, V> = - super::super::entry::VersionedEntryRef<'a, K, V, Allocator, RefCounter>; - - /// Iterator over the [`SkipMap`]. - pub type IterAll<'a, K, V> = super::super::iter::IterAll<'a, K, V, Allocator, RefCounter>; - - /// Iterator over a subset of the [`SkipMap`]. - pub type RangeAll<'a, K, V, Q, R> = - super::super::iter::IterAll<'a, K, V, Allocator, RefCounter, Q, R>; + super::super::entry::EntryRef<'a, K, V, Allocator, RefCounter>; /// A fast, ARENA based `SkipMap` that supports multiple versions, forward and backward iteration. /// @@ -145,24 +135,17 @@ pub mod sync { type SkipList = super::super::list::SkipList; /// Iterator over the [`SkipMap`]. - pub type Iter<'a, K, V> = super::super::iter::Iter<'a, K, V, Allocator, RefCounter>; - - /// Iterator over a subset of the [`SkipMap`]. - pub type Range<'a, K, V, Q, R> = super::super::iter::Iter<'a, K, V, Allocator, RefCounter, Q, R>; - - /// Iterator over the [`SkipMap`]. - pub type IterAll<'a, K, V> = super::super::iter::IterAll<'a, K, V, Allocator, RefCounter>; + pub type Iter<'a, K, L> = super::super::iter::Iter<'a, K, L, Allocator, RefCounter>; /// Iterator over a subset of the [`SkipMap`]. - pub type RangeAll<'a, K, V, Q, R> = - super::super::iter::IterAll<'a, K, V, Allocator, RefCounter, Q, R>; + pub type Range<'a, K, L, Q, R> = super::super::iter::Iter<'a, K, L, Allocator, RefCounter, Q, R>; /// The entry reference of the [`SkipMap`]. pub type Entry<'a, K, V> = super::super::entry::EntryRef<'a, K, V, Allocator, RefCounter>; /// The versioned entry reference of the [`SkipMap`]. pub type VersionedEntry<'a, K, V> = - super::super::entry::VersionedEntryRef<'a, K, V, Allocator, RefCounter>; + super::super::entry::EntryRef<'a, K, V, Allocator, RefCounter>; /// A fast, lock-free, thread-safe ARENA based `SkipMap` that supports multiple versions, forward and backward iteration. /// @@ -400,7 +383,7 @@ where fn first<'a>( &'a self, version: Version, - ) -> Option> + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -418,7 +401,7 @@ where fn last<'a>( &'a self, version: Version, - ) -> Option> + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -439,7 +422,7 @@ where fn first_versioned<'a>( &'a self, version: Version, - ) -> Option> + ) -> Option>, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -460,7 +443,7 @@ where fn last_versioned<'a>( &'a self, version: Version, - ) -> Option> + ) -> Option>, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -499,7 +482,7 @@ where &'a self, version: Version, key: &Q, - ) -> Option> + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -539,7 +522,7 @@ where &'a self, version: Version, key: &Q, - ) -> Option> + ) -> Option>, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -560,7 +543,7 @@ where &'a self, version: Version, upper: Bound<&Q>, - ) -> Option> + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -581,7 +564,7 @@ where &'a self, version: Version, lower: Bound<&Q>, - ) -> Option> + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -595,7 +578,7 @@ where self.as_ref().iter(version).seek_lower_bound(lower) } - /// Returns an `VersionedEntryRef` pointing to the highest element whose key is below the given bound. + /// Returns an `EntryRef` pointing to the highest element whose key is below the given bound. /// If no such element is found then `None` is returned. /// /// The difference between [`upper_bound`](Map::upper_bound) and `upper_bound_versioned` is that `upper_bound_versioned` will return the value even if the entry is removed. @@ -604,7 +587,7 @@ where &'a self, version: Version, upper: Bound<&Q>, - ) -> Option> + ) -> Option>, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -621,7 +604,7 @@ where .seek_upper_bound(upper) } - /// Returns an `VersionedEntryRef` pointing to the lowest element whose key is above the given bound. + /// Returns an `EntryRef` pointing to the lowest element whose key is above the given bound. /// If no such element is found then `None` is returned. /// /// The difference between [`lower_bound`](Map::lower_bound) and `lower_bound_versioned` is that `lower_bound_versioned` will return the value even if the entry is removed. @@ -630,7 +613,7 @@ where &'a self, version: Version, lower: Bound<&Q>, - ) -> Option> + ) -> Option>, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -649,7 +632,10 @@ where /// Returns a new iterator, this iterator will yield the latest version of all entries in the map less or equal to the given version. #[inline] - fn iter<'a>(&'a self, version: Version) -> Iter<'a, K, V, Self::Allocator, Self::RefCounter> + fn iter<'a>( + &'a self, + version: Version, + ) -> Iter<'a, K, LazyRef<'a, V>, Self::Allocator, Self::RefCounter> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -663,7 +649,7 @@ where fn iter_all_versions<'a>( &'a self, version: Version, - ) -> IterAll<'a, K, V, Self::Allocator, Self::RefCounter> + ) -> Iter<'a, K, Option>, Self::Allocator, Self::RefCounter> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -678,7 +664,7 @@ where &'a self, version: Version, range: R, - ) -> Iter<'a, K, V, Self::Allocator, Self::RefCounter, Q, R> + ) -> Iter<'a, K, LazyRef<'a, V>, Self::Allocator, Self::RefCounter, Q, R> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -695,7 +681,7 @@ where &'a self, version: Version, range: R, - ) -> IterAll<'a, K, V, Self::Allocator, Self::RefCounter, Q, R> + ) -> Iter<'a, K, Option>, Self::Allocator, Self::RefCounter, Q, R> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -718,7 +704,7 @@ where key: impl Into>, value: impl Into>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -753,7 +739,7 @@ where key: impl Into>, value: impl Into>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -818,7 +804,7 @@ where key: impl Into>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -890,7 +876,7 @@ where key: impl Into>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -916,7 +902,7 @@ where key: impl Into>, value: impl Into>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -943,7 +929,7 @@ where key: impl Into>, value: impl Into>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -1010,7 +996,7 @@ where key: impl Into>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -1083,7 +1069,7 @@ where key: impl Into>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -1154,7 +1140,10 @@ where version: Version, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Among, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -1229,7 +1218,10 @@ where height: Height, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Among, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -1296,7 +1288,10 @@ where version: Version, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Among, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -1368,7 +1363,10 @@ where height: Height, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Among, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -1394,7 +1392,10 @@ where key: impl Into>, success: Ordering, failure: Ordering, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type + 'b, K::Ref<'a>: KeyRef<'a, K>, @@ -1419,7 +1420,10 @@ where key: impl Into>, success: Ordering, failure: Ordering, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type + 'b, K::Ref<'a>: KeyRef<'a, K>, @@ -1441,7 +1445,10 @@ where &'a self, version: Version, key: impl Into>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type + 'b, K::Ref<'a>: KeyRef<'a, K>, @@ -1475,7 +1482,10 @@ where version: Version, height: Height, key: impl Into>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type + 'b, K::Ref<'a>: KeyRef<'a, K>, @@ -1533,7 +1543,10 @@ where &'a self, version: Version, key_builder: KeyBuilder) -> Result>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -1595,7 +1608,10 @@ where version: Version, height: Height, key_builder: KeyBuilder) -> Result>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, diff --git a/src/generic/unique.rs b/src/generic/unique.rs index aa178b5..65b8478 100644 --- a/src/generic/unique.rs +++ b/src/generic/unique.rs @@ -7,7 +7,7 @@ use among::Among; use dbutils::{ buffer::VacantBuffer, equivalent::Comparable, - types::{KeyRef, MaybeStructured, Type}, + types::{KeyRef, LazyRef, MaybeStructured, Type}, }; use either::Either; @@ -22,6 +22,8 @@ use super::list::{iterator::Iter, EntryRef}; /// Implementations for single-threaded environments. pub mod unsync { + use dbutils::types::LazyRef; + pub use crate::unsync::{map::Allocator, RefCounter}; #[cfg(any(all(test, not(miri)), all_skl_tests, test_generic_unsync_map,))] @@ -32,13 +34,15 @@ pub mod unsync { type SkipList = super::super::list::SkipList; /// Iterator over the [`SkipMap`]. - pub type Iter<'a, K, V> = super::super::iter::Iter<'a, K, V, Allocator, RefCounter>; + pub type Iter<'a, K, V> = super::super::iter::Iter<'a, K, LazyRef<'a, V>, Allocator, RefCounter>; /// Iterator over a subset of the [`SkipMap`]. - pub type Range<'a, K, V, Q, R> = super::super::iter::Iter<'a, K, V, Allocator, RefCounter, Q, R>; + pub type Range<'a, K, V, Q, R> = + super::super::iter::Iter<'a, K, LazyRef<'a, V>, Allocator, RefCounter, Q, R>; /// The entry reference of the [`SkipMap`]. - pub type Entry<'a, K, V> = super::super::entry::EntryRef<'a, K, V, Allocator, RefCounter>; + pub type Entry<'a, K, V> = + super::super::entry::EntryRef<'a, K, LazyRef<'a, V>, Allocator, RefCounter>; /// A fast, ARENA based `SkipMap` that supports forward and backward iteration. /// @@ -94,6 +98,8 @@ pub mod unsync { /// Implementations for concurrent environments. pub mod sync { + use dbutils::types::LazyRef; + pub use crate::sync::{map::Allocator, RefCounter}; #[cfg(any(all(test, not(miri)), all_skl_tests, test_generic_sync_map,))] @@ -127,13 +133,15 @@ pub mod sync { type SkipList = super::super::list::SkipList; /// Iterator over the [`SkipMap`]. - pub type Iter<'a, K, V> = super::super::iter::Iter<'a, K, V, Allocator, RefCounter>; + pub type Iter<'a, K, V> = super::super::iter::Iter<'a, K, LazyRef<'a, V>, Allocator, RefCounter>; /// Iterator over a subset of the [`SkipMap`]. - pub type Range<'a, K, V, Q, R> = super::super::iter::Iter<'a, K, V, Allocator, RefCounter, Q, R>; + pub type Range<'a, K, V, Q, R> = + super::super::iter::Iter<'a, K, LazyRef<'a, V>, Allocator, RefCounter, Q, R>; /// The entry reference of the [`SkipMap`]. - pub type Entry<'a, K, V> = super::super::entry::EntryRef<'a, K, V, Allocator, RefCounter>; + pub type Entry<'a, K, V> = + super::super::entry::EntryRef<'a, K, LazyRef<'a, V>, Allocator, RefCounter>; /// A fast, lock-free, thread-safe ARENA based `SkipMap` that supports forward and backward iteration. /// @@ -304,7 +312,9 @@ where /// Returns the first entry in the map. #[inline] - fn first<'a>(&'a self) -> Option> + fn first<'a>( + &'a self, + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -315,7 +325,9 @@ where /// Returns the last entry in the map. #[inline] - fn last<'a>(&'a self) -> Option> + fn last<'a>( + &'a self, + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -343,7 +355,10 @@ where /// assert!(map.get("hello").is_none()); /// ``` #[inline] - fn get<'a, Q>(&'a self, key: &Q) -> Option> + fn get<'a, Q>( + &'a self, + key: &Q, + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -359,7 +374,7 @@ where fn upper_bound<'a, Q>( &'a self, upper: Bound<&Q>, - ) -> Option> + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -375,7 +390,7 @@ where fn lower_bound<'a, Q>( &'a self, lower: Bound<&Q>, - ) -> Option> + ) -> Option, Self::Allocator, Self::RefCounter>> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -387,7 +402,7 @@ where /// Returns a new iterator, this iterator will yield the latest version of all entries in the map less or equal to the given version. #[inline] - fn iter<'a>(&'a self) -> Iter<'a, K, V, Self::Allocator, Self::RefCounter> + fn iter<'a>(&'a self) -> Iter<'a, K, LazyRef<'a, V>, Self::Allocator, Self::RefCounter> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -398,7 +413,10 @@ where /// Returns a iterator that within the range, this iterator will yield the latest version of all entries in the range less or equal to the given version. #[inline] - fn range<'a, Q, R>(&'a self, range: R) -> Iter<'a, K, V, Self::Allocator, Self::RefCounter, Q, R> + fn range<'a, Q, R>( + &'a self, + range: R, + ) -> Iter<'a, K, LazyRef<'a, V>, Self::Allocator, Self::RefCounter, Q, R> where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -420,7 +438,7 @@ where key: impl Into>, value: impl Into>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -454,7 +472,7 @@ where key: impl Into>, value: impl Into>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -521,7 +539,7 @@ where key: impl Into>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -588,7 +606,7 @@ where key: impl Into>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -613,7 +631,7 @@ where key: impl Into>, value: impl Into>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -637,7 +655,7 @@ where key: impl Into>, value: impl Into>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -704,7 +722,7 @@ where key: impl Into>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -772,7 +790,7 @@ where key: impl Into>, value_builder: ValueBuilder) -> Result>, ) -> Result< - Option>, + Option, Self::Allocator, Self::RefCounter>>, Among, > where @@ -845,7 +863,10 @@ where &'a self, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Among, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -914,7 +935,10 @@ where height: Height, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Among, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -980,7 +1004,10 @@ where &'a self, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Among, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -1046,7 +1073,10 @@ where height: Height, key_builder: KeyBuilder) -> Result>, value_builder: ValueBuilder) -> Result>, - ) -> Result>, Among> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Among, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -1072,7 +1102,10 @@ where fn remove<'a, 'b: 'a>( &'a self, key: impl Into>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type + 'b, K::Ref<'a>: KeyRef<'a, K>, @@ -1095,7 +1128,10 @@ where &'a self, height: Height, key: impl Into>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type + 'b, K::Ref<'a>: KeyRef<'a, K>, @@ -1120,7 +1156,10 @@ where fn get_or_remove<'a, 'b: 'a>( &'a self, key: impl Into>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type + 'b, K::Ref<'a>: KeyRef<'a, K>, @@ -1154,7 +1193,10 @@ where &'a self, height: Height, key: impl Into>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type + 'b, K::Ref<'a>: KeyRef<'a, K>, @@ -1213,7 +1255,10 @@ where fn get_or_remove_with_builder<'a, 'b: 'a, E>( &'a self, key_builder: KeyBuilder) -> Result>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, @@ -1272,7 +1317,10 @@ where &'a self, height: Height, key_builder: KeyBuilder) -> Result>, - ) -> Result>, Either> + ) -> Result< + Option, Self::Allocator, Self::RefCounter>>, + Either, + > where K: Type, K::Ref<'a>: KeyRef<'a, K>, diff --git a/src/tests/generic/multiple_version.rs b/src/tests/generic/multiple_version.rs index abca969..ccdb19f 100644 --- a/src/tests/generic/multiple_version.rs +++ b/src/tests/generic/multiple_version.rs @@ -1591,7 +1591,7 @@ where ent.value(), make_value(i + 1000).as_slice(), "{} != {}", - core::str::from_utf8(ent.value()).unwrap(), + core::str::from_utf8(ent.value().as_ref()).unwrap(), core::str::from_utf8(make_value(i + 1000).as_slice()).unwrap() );