Skip to content

Commit

Permalink
feat(tree_index, #162): vendor traits from "equivalent" crate
Browse files Browse the repository at this point in the history
Make "equivalent" crate optional dependency
  • Loading branch information
qthree committed Sep 21, 2024
1 parent eec6c1d commit bd0f222
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ members = [".", "examples"]
loom = { version = "0.7", optional = true }
sdd = "3.0"
serde = { version = "1.0", optional = true }
equivalent = "1.0.1"
equivalent = { version = "1.0.1", optional = true }

[features]
loom = ["dep:loom", "sdd/loom"]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ A collection of high performance containers and utilities for concurrent and asy
- Near-linear scalability.
- No spin-locks and no busy loops.
- SIMD lookup to scan multiple entries in parallel [^note].
- [`equivalent`](`https://github.com/indexmap-rs/equivalent`) traits support: `features = ["equivalent"]`

[^note]: Advanced SIMD instructions are used only when respective target features are enabled, e.g., `-C target_feature=+avx2`.

Expand Down
63 changes: 63 additions & 0 deletions src/equivalent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::{borrow::Borrow, cmp::Ordering};

/// Key equivalence trait.
///
/// This trait defines the function used to compare the input value with the
/// map keys (or set values) during a lookup operation such as [`HashMap::get`](crate::HashMap::get)
/// or [`HashSet::contains`](crate::HashSet::contains).
/// It is provided with a blanket implementation based on the
/// [`Borrow`](core::borrow::Borrow) trait.
///
/// # Correctness
///
/// The implementor **must** hash like `K`, if it is hashable.
///
/// # Credits
///
/// Inspired by `equivalent` and `hashbrown` crates
pub trait Equivalent<K: ?Sized> {
/// Compare self to `key` and return `true` if they are equal.
///
/// # Correctness
///
/// When this function returns `true`, both `self` and `key` must hash to
/// the same value.
fn equivalent(&self, key: &K) -> bool;
}

impl<Q: ?Sized, K: ?Sized> Equivalent<K> for Q
where
Q: Eq,
K: Borrow<Q>,
{
#[inline]
fn equivalent(&self, key: &K) -> bool {
PartialEq::eq(self, key.borrow())
}
}

/// Key ordering trait.
///
/// This trait defines the function used to compare the input value with the [`TreeIndex`](crate::TreeIndex) keys
/// during a lookup operations such as [`TreeIndex::peek`](crate::TreeIndex::peek) and [`TreeIndex::range`](crate::TreeIndex::range)
/// It is provided with a blanket implementation based on the
/// [`Borrow`](core::borrow::Borrow) trait.
///
/// /// # Credits
///
/// Inspired by `equivalent` crate
pub trait Comparable<K: ?Sized>: Equivalent<K> {
/// Compare self to `key` and return their ordering.
fn compare(&self, key: &K) -> Ordering;
}

impl<Q: ?Sized, K: ?Sized> Comparable<K> for Q
where
Q: Ord,
K: Borrow<Q>,
{
#[inline]
fn compare(&self, key: &K) -> Ordering {
Ord::cmp(self, key.borrow())
}
}
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ mod exit_guard;
mod hash_table;
mod wait_queue;

#[cfg(not(feature = "equivalent"))]
mod equivalent;

pub use equivalent::{Comparable, Equivalent};

#[cfg(feature = "loom")]
mod maybe_std {
pub(crate) use loom::sync::atomic::{AtomicU8, AtomicUsize};
Expand Down
2 changes: 1 addition & 1 deletion src/tree_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod node;

use crate::ebr::{AtomicShared, Guard, Ptr, Shared, Tag};
use crate::wait_queue::AsyncWait;
use equivalent::Comparable;
use crate::Comparable;
use leaf::{InsertResult, Leaf, RemoveResult, Scanner};
use node::Node;
use std::fmt::{self, Debug};
Expand Down
3 changes: 1 addition & 2 deletions src/tree_index/internal_node.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use equivalent::Comparable;

use super::leaf::{InsertResult, Leaf, RemoveResult, Scanner, DIMENSION};
use super::leaf_node::RemoveRangeState;
use super::leaf_node::{LOCKED, RETIRED};
Expand All @@ -8,6 +6,7 @@ use crate::ebr::{AtomicShared, Guard, Ptr, Shared, Tag};
use crate::exit_guard::ExitGuard;
use crate::maybe_std::AtomicU8;
use crate::wait_queue::{DeriveAsyncWait, WaitQueue};
use crate::Comparable;
use std::borrow::Borrow;
use std::cmp::Ordering::{Equal, Greater, Less};
use std::mem::forget;
Expand Down
3 changes: 1 addition & 2 deletions src/tree_index/leaf.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use equivalent::Comparable;

use crate::ebr::{AtomicShared, Guard, Shared};
use crate::maybe_std::AtomicUsize;
use crate::Comparable;
use crate::LinkedList;
use std::cell::UnsafeCell;
use std::cmp::Ordering;
Expand Down
3 changes: 1 addition & 2 deletions src/tree_index/leaf_node.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use equivalent::Comparable;

use super::leaf::{InsertResult, RemoveResult, Scanner, DIMENSION};
use super::node::Node;
use super::Leaf;
use crate::ebr::{AtomicShared, Guard, Ptr, Shared, Tag};
use crate::exit_guard::ExitGuard;
use crate::maybe_std::AtomicU8;
use crate::wait_queue::{DeriveAsyncWait, WaitQueue};
use crate::Comparable;
use crate::LinkedList;
use std::borrow::Borrow;
use std::cmp::Ordering::{Equal, Greater, Less};
Expand Down
3 changes: 1 addition & 2 deletions src/tree_index/node.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use equivalent::Comparable;

use super::internal_node::{self, InternalNode};
use super::leaf::{InsertResult, Leaf, RemoveResult, Scanner};
use super::leaf_node::{self, LeafNode};
use crate::ebr::{AtomicShared, Guard, Ptr, Shared, Tag};
use crate::wait_queue::DeriveAsyncWait;
use crate::Comparable;
use std::fmt::{self, Debug};
use std::ops::RangeBounds;
use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
Expand Down

0 comments on commit bd0f222

Please sign in to comment.