Make cmp more obvious

next
Sayan Nandan 2 years ago
parent 1f608c1f6c
commit 70810445cb
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -24,7 +24,40 @@
*
*/
use std::hash::BuildHasher;
use core::{
borrow::Borrow,
hash::{BuildHasher, Hash},
};
pub trait AsHasher: BuildHasher + Default {}
impl<T> AsHasher for T where T: BuildHasher + Default {}
/// The [`Comparable`] trait is like [`PartialEq`], but is different due to its expectations, and escapes its scandalous relations with [`Eq`] and the consequential
/// implications across the [`std`].
///
/// ☢️ WARNING ☢️: In some cases implementations of the [`Comparable`] set of traits COMPLETELY VIOLATES [`Eq`]'s invariants. BE VERY CAREFUL WHEN USING IN EXPRESSIONS
/*
FIXME(@ohsayan): The gradual idea is to completely move to Comparable, but that means we'll have to go ahead as much as replacing the impls for some items in the
standard library. We don't have the time to do that right now, but I hope we can do it soon
*/
pub trait Comparable<K: ?Sized>: Hash {
fn cmp_eq(&self, key: &K) -> bool;
}
pub trait ComparableUpgradeable<K>: Comparable<K> {
fn upgrade(&self) -> K;
}
impl<K: Borrow<T>, T: Eq + Hash + ?Sized> Comparable<K> for T {
fn cmp_eq(&self, key: &K) -> bool {
self == key.borrow()
}
}
impl<K: Hash, T: ToOwned<Owned = K> + Hash + Comparable<K> + ?Sized> ComparableUpgradeable<K>
for T
{
fn upgrade(&self) -> K {
self.to_owned()
}
}

@ -38,10 +38,12 @@ use {
self::{
iter::{IterKV, IterKey, IterVal},
meta::{CompressState, Config, DefConfig, LNode, NodeFlag, TreeElement},
patch::{TreeKeyComparable, TreeKeyComparableUpgradeable},
},
crate::engine::{
idx::AsKey,
idx::{
meta::{Comparable, ComparableUpgradeable},
AsKey,
},
mem::UArray,
sync::atm::{self, cpin, upin, Atomic, Guard, Owned, Shared, ORD_ACR, ORD_RLX},
},
@ -242,7 +244,7 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
let _ = self.remove(k, g);
});
}
fn patch_insert<Q: TreeKeyComparableUpgradeable<T>>(
fn patch_insert<Q: ComparableUpgradeable<T::Key>>(
&self,
key: Q,
v: T::Value,
@ -250,10 +252,10 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
) -> bool {
self.patch(patch::Insert::new(key, v), g)
}
fn patch_upsert<Q: TreeKeyComparableUpgradeable<T>>(&self, key: Q, v: T::Value, g: &Guard) {
fn patch_upsert<Q: ComparableUpgradeable<T::Key>>(&self, key: Q, v: T::Value, g: &Guard) {
self.patch(patch::Upsert::new(key, v), g)
}
fn patch_upsert_return<'g, Q: TreeKeyComparableUpgradeable<T>>(
fn patch_upsert_return<'g, Q: ComparableUpgradeable<T::Key>>(
&'g self,
key: Q,
v: T::Value,
@ -261,10 +263,10 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
) -> Option<&'g T::Value> {
self.patch(patch::UpsertReturn::new(key, v), g)
}
fn patch_update<Q: TreeKeyComparable<T>>(&self, key: Q, v: T::Value, g: &Guard) -> bool {
fn patch_update<Q: Comparable<T::Key>>(&self, key: Q, v: T::Value, g: &Guard) -> bool {
self.patch(patch::UpdateReplace::new(key, v), g)
}
fn patch_update_return<'g, Q: TreeKeyComparable<T>>(
fn patch_update_return<'g, Q: Comparable<T::Key>>(
&'g self,
key: Q,
v: T::Value,
@ -273,7 +275,7 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
self.patch(patch::UpdateReplaceRet::new(key, v), g)
}
fn patch<'g, P: patch::Patch<T>>(&'g self, mut patch: P, g: &'g Guard) -> P::Ret<'g> {
let hash = self.hash(&patch.target());
let hash = self.hash(patch.target());
let mut level = C::LEVEL_ZERO;
let mut current = &self.root;
let mut parent = None;
@ -329,7 +331,7 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
Self::read_data(node)
};
debug_assert!(!data.is_empty(), "logic,empty node not compressed");
if !patch.target().cmp_eq(&data[0]) && level < C::MAX_TREE_HEIGHT_UB {
if !patch.target().cmp_eq(data[0].key()) && level < C::MAX_TREE_HEIGHT_UB {
/*
so this is a collision and since we haven't reached the max height, we should always
create a new branch so let's do that
@ -351,7 +353,9 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
in this case we either have the same key or we found an lnode. resolve any conflicts and attempt
to update
*/
let p = data.iter().position(|e| patch.target().cmp_eq(e));
let p = data
.iter()
.position(|e| patch.target().cmp_eq(e.key()));
match p {
Some(v) if P::WMODE == patch::WRITEMODE_FRESH => {
return P::ex_ret(&data[v])

@ -24,10 +24,9 @@
*
*/
use std::borrow::Borrow;
use {
super::meta::TreeElement,
crate::engine::idx::meta::{Comparable, ComparableUpgradeable},
core::{hash::Hash, marker::PhantomData},
};
@ -41,38 +40,12 @@ pub const WRITEMODE_REFRESH: WriteFlag = 0b10;
/// any
pub const WRITEMODE_ANY: WriteFlag = 0b11;
pub trait TreeKeyComparable<T: TreeElement>: Hash {
fn cmp_eq(&self, them: &T) -> bool;
}
impl<E: TreeElement, T> TreeKeyComparable<E> for T
where
E::Key: core::borrow::Borrow<T>,
T: Hash + PartialEq,
{
fn cmp_eq(&self, them: &E) -> bool {
self == them.key().borrow()
}
}
pub trait TreeKeyComparableUpgradeable<T: TreeElement>: TreeKeyComparable<T> {
fn upgrade_key(&self) -> T::Key;
}
impl<E: TreeElement> TreeKeyComparableUpgradeable<E> for E::Key {
fn upgrade_key(&self) -> E::Key {
self.clone()
}
}
/// A [`Patch`] is intended to atomically update the state of the tree, which means that all your deltas should be atomic
pub trait Patch<E: TreeElement> {
const WMODE: WriteFlag;
type Ret<'a>;
type Target<'a>: TreeKeyComparable<E>
where
Self: 'a;
fn target<'a>(&'a self) -> &Self::Target<'a>;
type Target: Hash + Comparable<E::Key>;
fn target<'a>(&'a self) -> &Self::Target;
fn nx_new(&mut self) -> E;
fn nx_ret<'a>() -> Self::Ret<'a>;
fn ex_apply(&mut self, current: &E) -> E;
@ -80,13 +53,13 @@ pub trait Patch<E: TreeElement> {
}
/// insert
pub struct Insert<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> {
pub struct Insert<E: TreeElement, U: ComparableUpgradeable<E::Key>> {
target: U,
new_data: E::Value,
_m: PhantomData<E>,
}
impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Insert<E, U> {
impl<E: TreeElement, U: ComparableUpgradeable<E::Key>> Insert<E, U> {
pub fn new(target: U, new_data: E::Value) -> Self {
Self {
target,
@ -96,18 +69,16 @@ impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Insert<E, U> {
}
}
impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Patch<E> for Insert<E, U> {
impl<E: TreeElement, U: ComparableUpgradeable<E::Key>> Patch<E> for Insert<E, U> {
const WMODE: WriteFlag = WRITEMODE_FRESH;
type Ret<'a> = bool;
type Target<'a> = U
where
Self: 'a;
type Target = U;
fn target<'a>(&'a self) -> &Self::Target<'a> {
fn target<'a>(&'a self) -> &Self::Target {
&self.target
}
fn nx_new(&mut self) -> E {
E::new(self.target.upgrade_key(), self.new_data.clone())
E::new(self.target.upgrade(), self.new_data.clone())
}
fn nx_ret<'a>() -> Self::Ret<'a> {
true
@ -121,13 +92,13 @@ impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Patch<E> for Insert<E,
}
/// upsert
pub struct Upsert<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> {
pub struct Upsert<E: TreeElement, U: ComparableUpgradeable<E::Key>> {
target: U,
new_data: E::Value,
_m: PhantomData<E>,
}
impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Upsert<E, U> {
impl<E: TreeElement, U: ComparableUpgradeable<E::Key>> Upsert<E, U> {
pub fn new(target: U, new_data: E::Value) -> Self {
Self {
target,
@ -137,18 +108,16 @@ impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Upsert<E, U> {
}
}
impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Patch<E> for Upsert<E, U> {
impl<E: TreeElement, U: ComparableUpgradeable<E::Key>> Patch<E> for Upsert<E, U> {
const WMODE: WriteFlag = WRITEMODE_ANY;
type Ret<'a> = ();
type Target<'a> = U
where
Self: 'a;
type Target = U;
fn target<'a>(&'a self) -> &Self::Target<'a> {
fn target<'a>(&'a self) -> &Self::Target {
&self.target
}
fn nx_new(&mut self) -> E {
E::new(self.target.upgrade_key(), self.new_data.clone())
E::new(self.target.upgrade(), self.new_data.clone())
}
fn nx_ret<'a>() -> Self::Ret<'a> {
()
@ -162,13 +131,13 @@ impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Patch<E> for Upsert<E,
}
/// upsert return
pub struct UpsertReturn<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> {
pub struct UpsertReturn<E: TreeElement, U: ComparableUpgradeable<E::Key>> {
target: U,
new_data: E::Value,
_m: PhantomData<E>,
}
impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> UpsertReturn<E, U> {
impl<E: TreeElement, U: ComparableUpgradeable<E::Key>> UpsertReturn<E, U> {
pub fn new(target: U, new_data: E::Value) -> Self {
Self {
target,
@ -178,18 +147,16 @@ impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> UpsertReturn<E, U> {
}
}
impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Patch<E> for UpsertReturn<E, U> {
impl<E: TreeElement, U: ComparableUpgradeable<E::Key>> Patch<E> for UpsertReturn<E, U> {
const WMODE: WriteFlag = WRITEMODE_ANY;
type Ret<'a> = Option<&'a E::Value>;
type Target<'a> = U
where
Self: 'a;
type Target = U;
fn target<'a>(&'a self) -> &Self::Target<'a> {
fn target<'a>(&'a self) -> &Self::Target {
&self.target
}
fn nx_new(&mut self) -> E {
E::new(self.target.upgrade_key(), self.new_data.clone())
E::new(self.target.upgrade(), self.new_data.clone())
}
fn nx_ret<'a>() -> Self::Ret<'a> {
None
@ -203,13 +170,13 @@ impl<E: TreeElement, U: TreeKeyComparableUpgradeable<E>> Patch<E> for UpsertRetu
}
/// update
pub struct UpdateReplace<E: TreeElement, U: TreeKeyComparable<E>> {
pub struct UpdateReplace<E: TreeElement, U: Comparable<E::Key>> {
target: U,
new_data: E::Value,
_m: PhantomData<E>,
}
impl<E: TreeElement, U: TreeKeyComparable<E>> UpdateReplace<E, U> {
impl<E: TreeElement, U: Comparable<E::Key>> UpdateReplace<E, U> {
pub fn new(target: U, new_data: E::Value) -> Self {
Self {
target,
@ -219,16 +186,14 @@ impl<E: TreeElement, U: TreeKeyComparable<E>> UpdateReplace<E, U> {
}
}
impl<E: TreeElement, U: TreeKeyComparable<E>> Patch<E> for UpdateReplace<E, U> {
impl<E: TreeElement, U: Comparable<E::Key>> Patch<E> for UpdateReplace<E, U> {
const WMODE: WriteFlag = WRITEMODE_REFRESH;
type Ret<'a> = bool;
type Target<'a> = U
where
Self: 'a;
type Target = U;
fn target<'a>(&'a self) -> &Self::Target<'a> {
fn target<'a>(&'a self) -> &Self::Target {
&self.target
}
@ -250,13 +215,13 @@ impl<E: TreeElement, U: TreeKeyComparable<E>> Patch<E> for UpdateReplace<E, U> {
}
/// update_return
pub struct UpdateReplaceRet<E: TreeElement, U: TreeKeyComparable<E>> {
pub struct UpdateReplaceRet<E: TreeElement, U: Comparable<E::Key>> {
target: U,
new_data: E::Value,
_m: PhantomData<E>,
}
impl<E: TreeElement, U: TreeKeyComparable<E>> UpdateReplaceRet<E, U> {
impl<E: TreeElement, U: Comparable<E::Key>> UpdateReplaceRet<E, U> {
pub fn new(target: U, new_data: E::Value) -> Self {
Self {
target,
@ -266,16 +231,14 @@ impl<E: TreeElement, U: TreeKeyComparable<E>> UpdateReplaceRet<E, U> {
}
}
impl<E: TreeElement, U: TreeKeyComparable<E>> Patch<E> for UpdateReplaceRet<E, U> {
impl<E: TreeElement, U: Comparable<E::Key>> Patch<E> for UpdateReplaceRet<E, U> {
const WMODE: WriteFlag = WRITEMODE_REFRESH;
type Ret<'a> = Option<&'a E::Value>;
type Target<'a> = U
where
Self: 'a;
type Target = U;
fn target<'a>(&'a self) -> &Self::Target<'a> {
fn target<'a>(&'a self) -> &Self::Target {
&self.target
}
@ -311,8 +274,8 @@ impl<T: TreeElement> InsertDirect<T> {
impl<T: TreeElement> Patch<T> for InsertDirect<T> {
const WMODE: WriteFlag = WRITEMODE_FRESH;
type Ret<'a> = bool;
type Target<'a> = T::Key;
fn target<'a>(&'a self) -> &Self::Target<'a> {
type Target = T::Key;
fn target<'a>(&'a self) -> &Self::Target {
self.data.key()
}
fn nx_ret<'a>() -> Self::Ret<'a> {

Loading…
Cancel
Save