From 83f6df96e5a92c657abdaeab9ffb7f112a807027 Mon Sep 17 00:00:00 2001 From: al8n Date: Wed, 2 Oct 2024 18:13:28 +0800 Subject: [PATCH] implement some traits for `Generic` --- src/entry.rs | 117 ++++++++++++++++++++++++++++++++++--- src/swmr/generic.rs | 4 +- src/swmr/generic/reader.rs | 2 +- 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/src/entry.rs b/src/entry.rs index ab447b78..2ea48547 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -1,7 +1,10 @@ use core::borrow::Borrow; use crossbeam_skiplist::set::Entry as SetEntry; -use dbutils::traits::{Type, TypeRef}; +use dbutils::{ + equivalent::{Comparable, Equivalent}, + traits::{Type, TypeRef}, +}; use rarena_allocator::either::Either; use super::{ @@ -215,6 +218,98 @@ pub struct Generic<'a, T: ?Sized> { data: Either<&'a T, &'a [u8]>, } +impl PartialEq for Generic<'_, T> +where + T: ?Sized + PartialEq + Type + for<'a> Equivalent>, +{ + #[inline] + fn eq(&self, other: &T) -> bool { + match &self.data { + Either::Left(val) => (*val).eq(other), + Either::Right(val) => { + let ref_ = unsafe { as TypeRef<'_>>::from_slice(val) }; + other.equivalent(&ref_) + } + } + } +} + +impl PartialEq for Generic<'_, T> +where + T: ?Sized + PartialEq + Type + for<'a> Equivalent>, +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + match (&self.data, &other.data) { + (Either::Left(val), Either::Left(other_val)) => val.eq(other_val), + (Either::Right(val), Either::Right(other_val)) => val.eq(other_val), + (Either::Left(val), Either::Right(other_val)) => { + let ref_ = unsafe { as TypeRef<'_>>::from_slice(other_val) }; + val.equivalent(&ref_) + } + (Either::Right(val), Either::Left(other_val)) => { + let ref_ = unsafe { as TypeRef<'_>>::from_slice(val) }; + other_val.equivalent(&ref_) + } + } + } +} + +impl Eq for Generic<'_, T> where T: ?Sized + Eq + Type + for<'a> Equivalent> {} + +impl PartialOrd for Generic<'_, T> +where + T: ?Sized + Ord + Type + for<'a> Comparable>, + for<'a> T::Ref<'a>: Comparable + Ord, +{ + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialOrd for Generic<'_, T> +where + T: ?Sized + PartialOrd + Type + for<'a> Comparable>, +{ + #[inline] + fn partial_cmp(&self, other: &T) -> Option { + match &self.data { + Either::Left(val) => (*val).partial_cmp(other), + Either::Right(val) => { + let ref_ = unsafe { as TypeRef<'_>>::from_slice(val) }; + Some(other.compare(&ref_).reverse()) + } + } + } +} + +impl Ord for Generic<'_, T> +where + T: ?Sized + Ord + Type + for<'a> Comparable>, + for<'a> T::Ref<'a>: Comparable + Ord, +{ + #[inline] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match (&self.data, &other.data) { + (Either::Left(val), Either::Left(other_val)) => (*val).cmp(other_val), + (Either::Right(val), Either::Right(other_val)) => { + let this = unsafe { as TypeRef<'_>>::from_slice(val) }; + let other = unsafe { as TypeRef<'_>>::from_slice(other_val) }; + this.cmp(&other) + } + (Either::Left(val), Either::Right(other_val)) => { + let other = unsafe { as TypeRef<'_>>::from_slice(other_val) }; + other.compare(*val).reverse() + } + (Either::Right(val), Either::Left(other_val)) => { + let this = unsafe { as TypeRef<'_>>::from_slice(val) }; + this.compare(*other_val) + } + } + } +} + impl Generic<'_, T> { #[inline] pub(crate) fn encoded_len(&self) -> usize { @@ -429,20 +524,26 @@ where impl<'a, K, V> GenericEntryRef<'a, K, V> where - K: Type + ?Sized, + K: ?Sized, V: Type + ?Sized, { - /// Returns the key of the entry. + /// Returns the value of the entry. #[inline] - pub fn key(&self) -> K::Ref<'a> { + pub fn value(&self) -> V::Ref<'a> { let p = self.ent.value(); - unsafe { TypeRef::from_slice(p.as_key_slice()) } + unsafe { TypeRef::from_slice(p.as_value_slice()) } } +} - /// Returns the value of the entry. +impl<'a, K, V> GenericEntryRef<'a, K, V> +where + K: Type + ?Sized, + V: ?Sized, +{ + /// Returns the key of the entry. #[inline] - pub fn value(&self) -> V::Ref<'a> { + pub fn key(&self) -> K::Ref<'a> { let p = self.ent.value(); - unsafe { TypeRef::from_slice(p.as_value_slice()) } + unsafe { TypeRef::from_slice(p.as_key_slice()) } } } diff --git a/src/swmr/generic.rs b/src/swmr/generic.rs index f410ec30..a717df24 100644 --- a/src/swmr/generic.rs +++ b/src/swmr/generic.rs @@ -408,7 +408,7 @@ impl GenericOrderWalCore where K: Type + Ord + ?Sized, for<'a> ::Ref<'a>: KeyRef<'a, K>, - V: Type + ?Sized, + V: ?Sized, { #[inline] fn contains_key<'a, Q>(&'a self, key: &'a Q) -> bool @@ -642,7 +642,7 @@ impl GenericOrderWal where K: Type + Ord + ?Sized, for<'a> K::Ref<'a>: KeyRef<'a, K>, - V: Type + ?Sized, + V: ?Sized, { /// Returns `true` if the key exists in the WAL. #[inline] diff --git a/src/swmr/generic/reader.rs b/src/swmr/generic/reader.rs index 926bc887..f7c60763 100644 --- a/src/swmr/generic/reader.rs +++ b/src/swmr/generic/reader.rs @@ -118,7 +118,7 @@ impl GenericWalReader where K: Type + Ord + ?Sized, for<'a> K::Ref<'a>: KeyRef<'a, K>, - V: Type + ?Sized, + V: ?Sized, { /// Returns `true` if the key exists in the WAL. #[inline]