Skip to content

Commit

Permalink
chore(*): finalize SCC 2.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wvwwvwwv committed Sep 30, 2024
1 parent e2c9289 commit ce71bd2
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 30 deletions.
34 changes: 28 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,15 @@ pub use stack::Stack;
pub mod tree_index;
pub use tree_index::TreeIndex;

/// Re-exports the [`sdd`](https://crates.io/crates/sdd) crate for backward compatibility.
pub use sdd as ebr;

mod exit_guard;
mod hash_table;
mod wait_queue;

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

pub use equivalent::{Comparable, Equivalent};
#[cfg(feature = "serde")]
mod serde;

#[cfg(feature = "loom")]
mod maybe_std {
Expand All @@ -53,8 +51,32 @@ mod maybe_std {
pub(crate) use std::thread::yield_now;
}

#[cfg(feature = "serde")]
mod serde;
mod range_helper {
use crate::Comparable;
use std::ops::Bound::{Excluded, Included, Unbounded};
use std::ops::RangeBounds;

/// Emulates `RangeBounds::contains`.
pub(crate) fn contains<K, Q, R: RangeBounds<Q>>(range: &R, key: &K) -> bool
where
Q: Comparable<K> + ?Sized,
{
(match range.start_bound() {
Included(start) => start.compare(key).is_le(),
Excluded(start) => start.compare(key).is_lt(),
Unbounded => true,
}) && (match range.end_bound() {
Included(end) => end.compare(key).is_ge(),
Excluded(end) => end.compare(key).is_gt(),
Unbounded => true,
})
}
}

/// Re-exports the [`sdd`](https://crates.io/crates/sdd) crate for backward compatibility.
pub use sdd as ebr;

pub use equivalent::{Comparable, Equivalent};

#[cfg(test)]
mod tests;
3 changes: 1 addition & 2 deletions src/tests/correctness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2158,11 +2158,10 @@ mod treeindex_test {
}
}

#[cfg_attr(miri, ignore)]
#[test]
fn mixed() {
let range = if cfg!(miri) { 64 } else { 4096 };
let num_threads = if cfg!(miri) { 4 } else { 16 };
let num_threads = if cfg!(miri) { 2 } else { 16 };
let tree: Arc<TreeIndex<usize, usize>> = Arc::new(TreeIndex::new());
let barrier = Arc::new(Barrier::new(num_threads));
let mut thread_handles = Vec::with_capacity(num_threads);
Expand Down
10 changes: 8 additions & 2 deletions src/tree_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,10 @@ where
/// assert!(!treeindex.contains(&3));
/// ```
#[inline]
pub fn remove_range<R: RangeBounds<K>>(&self, range: R) {
pub fn remove_range<Q, R: RangeBounds<Q>>(&self, range: R)
where
Q: Comparable<K> + ?Sized,
{
let start_unbounded = matches!(range.start_bound(), Unbounded);
let guard = Guard::new();

Expand Down Expand Up @@ -553,7 +556,10 @@ where
/// let future_remove_range = treeindex.remove_range_async(3..8);
/// ```
#[inline]
pub async fn remove_range_async<R: RangeBounds<K>>(&self, range: R) {
pub async fn remove_range_async<Q, R: RangeBounds<Q>>(&self, range: R)
where
Q: Comparable<K> + ?Sized,
{
let start_unbounded = matches!(range.start_bound(), Unbounded);

loop {
Expand Down
7 changes: 5 additions & 2 deletions src/tree_index/internal_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,15 +471,18 @@ where
/// Returns the number of remaining children.
#[allow(clippy::too_many_lines)]
#[inline]
pub(super) fn remove_range<'g, R: RangeBounds<K>, D: DeriveAsyncWait>(
pub(super) fn remove_range<'g, Q, R: RangeBounds<Q>, D: DeriveAsyncWait>(
&self,
range: &R,
start_unbounded: bool,
valid_lower_max_leaf: Option<&'g Leaf<K, V>>,
valid_upper_min_node: Option<&'g Node<K, V>>,
async_wait: &mut D,
guard: &'g Guard,
) -> Result<usize, ()> {
) -> Result<usize, ()>
where
Q: Comparable<K> + ?Sized,
{
debug_assert!(valid_lower_max_leaf.is_none() || start_unbounded);
debug_assert!(valid_lower_max_leaf.is_none() || valid_upper_min_node.is_none());

Expand Down
9 changes: 6 additions & 3 deletions src/tree_index/leaf.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::ebr::{AtomicShared, Guard, Shared};
use crate::maybe_std::AtomicUsize;
use crate::Comparable;
use crate::LinkedList;
use crate::{range_helper, Comparable};
use std::cell::UnsafeCell;
use std::cmp::Ordering;
use std::fmt::{self, Debug};
Expand Down Expand Up @@ -462,7 +462,10 @@ where
///
/// Returns the number of remaining children.
#[inline]
pub(super) fn remove_range<R: RangeBounds<K>>(&self, range: &R) {
pub(super) fn remove_range<Q, R: RangeBounds<Q>>(&self, range: &R)
where
Q: Comparable<K> + ?Sized,
{
let mut mutable_metadata = self.metadata.load(Acquire);
for i in 0..DIMENSION.num_entries {
if mutable_metadata == 0 {
Expand All @@ -471,7 +474,7 @@ where
let rank = mutable_metadata % (1_usize << DIMENSION.num_bits_per_entry);
if rank != Dimension::uninit_rank() && rank != DIMENSION.removed_rank() {
let k = self.key_at(i);
if range.contains(k) {
if range_helper::contains(range, k) {
self.remove_if(k, &mut |_| true);
}
}
Expand Down
31 changes: 18 additions & 13 deletions src/tree_index/leaf_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ 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 crate::{range_helper, Comparable};
use std::borrow::Borrow;
use std::cmp::Ordering::{Equal, Greater, Less};
use std::ops::{Bound, RangeBounds};
Expand Down Expand Up @@ -479,15 +479,18 @@ where
///
/// Returns the number of remaining children.
#[inline]
pub(super) fn remove_range<'g, R: RangeBounds<K>, D: DeriveAsyncWait>(
pub(super) fn remove_range<'g, Q, R: RangeBounds<Q>, D: DeriveAsyncWait>(
&self,
range: &R,
start_unbounded: bool,
valid_lower_max_leaf: Option<&'g Leaf<K, V>>,
valid_upper_min_node: Option<&'g Node<K, V>>,
async_wait: &mut D,
guard: &'g Guard,
) -> Result<usize, ()> {
) -> Result<usize, ()>
where
Q: Comparable<K> + ?Sized,
{
debug_assert!(valid_lower_max_leaf.is_none() || start_unbounded);
debug_assert!(valid_lower_max_leaf.is_none() || valid_upper_min_node.is_none());

Expand Down Expand Up @@ -1098,13 +1101,16 @@ impl<'n, K, V> Drop for Locker<'n, K, V> {

impl RemoveRangeState {
/// Returns the next state.
pub(super) fn next<K: Ord, R: RangeBounds<K>>(
pub(super) fn next<K, Q, R: RangeBounds<Q>>(
self,
key: &K,
range: &R,
start_unbounded: bool,
) -> Self {
if range.contains(key) {
) -> Self
where
Q: Comparable<K> + ?Sized,
{
if range_helper::contains(range, key) {
match self {
RemoveRangeState::Below => {
if start_unbounded {
Expand All @@ -1121,14 +1127,13 @@ impl RemoveRangeState {
} else {
match self {
RemoveRangeState::Below => match range.start_bound() {
Bound::Included(k) => match key.cmp(k) {
Less => RemoveRangeState::Below,
Equal => unreachable!(),
Greater => RemoveRangeState::MaybeAbove,
Bound::Included(k) => match k.compare(key) {
Less | Equal => RemoveRangeState::MaybeAbove,
Greater => RemoveRangeState::Below,
},
Bound::Excluded(k) => match key.cmp(k) {
Less | Equal => RemoveRangeState::Below,
Greater => RemoveRangeState::MaybeAbove,
Bound::Excluded(k) => match k.compare(key) {
Less => RemoveRangeState::MaybeAbove,
Greater | Equal => RemoveRangeState::Below,
},
Bound::Unbounded => RemoveRangeState::MaybeAbove,
},
Expand Down
7 changes: 5 additions & 2 deletions src/tree_index/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,18 @@ where
///
/// Returns the number of remaining children.
#[inline]
pub(super) fn remove_range<'g, R: RangeBounds<K>, D: DeriveAsyncWait>(
pub(super) fn remove_range<'g, Q, R: RangeBounds<Q>, D: DeriveAsyncWait>(
&self,
range: &R,
start_unbounded: bool,
valid_lower_max_leaf: Option<&'g Leaf<K, V>>,
valid_upper_min_node: Option<&'g Node<K, V>>,
async_wait: &mut D,
guard: &'g Guard,
) -> Result<usize, ()> {
) -> Result<usize, ()>
where
Q: Comparable<K> + ?Sized,
{
match &self {
Self::Internal(internal_node) => internal_node.remove_range(
range,
Expand Down

0 comments on commit ce71bd2

Please sign in to comment.