From 9e1f7d3bf1b975dd02e04f151b0690248b2c1459 Mon Sep 17 00:00:00 2001 From: al8n Date: Mon, 9 Dec 2024 10:47:33 +0800 Subject: [PATCH] flip `K` and `Q` --- crossbeam-skiplist/Cargo.toml | 1 - crossbeam-skiplist/src/base.rs | 125 +++++++++++++++------------ crossbeam-skiplist/src/equivalent.rs | 49 +++++++++++ crossbeam-skiplist/src/lib.rs | 4 + crossbeam-skiplist/src/map.rs | 42 +++++---- crossbeam-skiplist/src/set.rs | 39 +++++---- crossbeam-skiplist/tests/base.rs | 36 +++----- crossbeam-skiplist/tests/map.rs | 74 ++++++++-------- crossbeam-skiplist/tests/set.rs | 70 +++++++-------- 9 files changed, 254 insertions(+), 186 deletions(-) create mode 100644 crossbeam-skiplist/src/equivalent.rs diff --git a/crossbeam-skiplist/Cargo.toml b/crossbeam-skiplist/Cargo.toml index d85bfa8c8..75a0df46b 100644 --- a/crossbeam-skiplist/Cargo.toml +++ b/crossbeam-skiplist/Cargo.toml @@ -28,7 +28,6 @@ std = ["alloc", "crossbeam-epoch/std", "crossbeam-utils/std"] alloc = ["crossbeam-epoch/alloc"] [dependencies] -equivalent = "1" crossbeam-epoch = { version = "0.9.17", path = "../crossbeam-epoch", default-features = false } crossbeam-utils = { version = "0.8.18", path = "../crossbeam-utils", default-features = false } diff --git a/crossbeam-skiplist/src/base.rs b/crossbeam-skiplist/src/base.rs index 314f227ae..2b85a2bb8 100644 --- a/crossbeam-skiplist/src/base.rs +++ b/crossbeam-skiplist/src/base.rs @@ -1,7 +1,7 @@ //! A lock-free skip list. See [`SkipList`]. +use super::equivalent::Comparable; use alloc::alloc::{alloc, dealloc, handle_alloc_error, Layout}; -use core::borrow::Borrow; use core::cmp; use core::fmt; use core::marker::PhantomData; @@ -9,7 +9,6 @@ use core::mem; use core::ops::{Bound, Deref, Index, RangeBounds}; use core::ptr; use core::sync::atomic::{fence, AtomicUsize, Ordering}; -use equivalent::Comparable; use crossbeam_epoch::{self as epoch, Atomic, Collector, Guard, Shared}; use crossbeam_utils::CachePadded; @@ -410,7 +409,8 @@ where /// Returns `true` if the map contains a value for the specified key. pub fn contains_key(&self, key: &Q, guard: &Guard) -> bool where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { self.get(key, guard).is_some() } @@ -418,13 +418,15 @@ where /// Returns an entry with the specified `key`. pub fn get<'a: 'g, 'g, Q>(&'a self, key: &Q, guard: &'g Guard) -> Option> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { self.check_guard(guard); let n = self.search_bound(Bound::Included(key), false, guard)?; - if key.compare(&n.key).is_ne() { + if !n.key.equivalent(key) { return None; } + Some(Entry { parent: self, node: n, @@ -441,7 +443,8 @@ where guard: &'g Guard, ) -> Option> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { self.check_guard(guard); let n = self.search_bound(bound, false, guard)?; @@ -461,7 +464,8 @@ where guard: &'g Guard, ) -> Option> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { self.check_guard(guard); let n = self.search_bound(bound, true, guard)?; @@ -519,9 +523,9 @@ where guard: &'g Guard, ) -> Range<'a, 'g, Q, R, K, V> where - K: Borrow, + K: Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { self.check_guard(guard); Range { @@ -538,8 +542,9 @@ where #[allow(clippy::needless_lifetimes)] pub fn ref_range<'a, Q, R>(&'a self, range: R) -> RefRange<'a, Q, R, K, V> where + K: Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { RefRange { parent: self, @@ -681,7 +686,8 @@ where guard: &'a Guard, ) -> Option<&'a Node> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { unsafe { 'search: loop { @@ -739,11 +745,11 @@ where // bound, we return the last node before the condition became true. For the // lower bound, we return the first node after the condition became true. if upper_bound { - if !below_upper_bound(&bound, c.key.borrow()) { + if !below_upper_bound(&bound, &c.key) { break; } result = Some(c); - } else if above_lower_bound(&bound, c.key.borrow()) { + } else if above_lower_bound(&bound, &c.key) { result = Some(c); break; } @@ -762,7 +768,8 @@ where /// Searches for a key in the skip list and returns a list of all adjacent nodes. fn search_position<'a, Q>(&'a self, key: &Q, guard: &'a Guard) -> Position<'a, K, V> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { unsafe { 'search: loop { @@ -819,7 +826,7 @@ where // If `curr` contains a key that is greater than or equal to `key`, we're // done with this level. - match key.compare(&c.key).reverse() { + match c.key.compare(key) { cmp::Ordering::Greater => break, cmp::Ordering::Equal => { result.found = Some(c); @@ -1095,7 +1102,8 @@ where /// Removes an entry with the specified `key` from the map and returns it. pub fn remove(&self, key: &Q, guard: &Guard) -> Option> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { self.check_guard(guard); @@ -1788,9 +1796,9 @@ impl<'a, K: 'a, V: 'a> RefIter<'a, K, V> { /// An iterator over a subset of entries of a `SkipList`. pub struct Range<'a: 'g, 'g, Q, R, K, V> where - K: Ord, + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { parent: &'a SkipList, head: Option<&'g Node>, @@ -1802,9 +1810,9 @@ where impl<'a: 'g, 'g, Q, R, K: 'a, V: 'a> Iterator for Range<'a, 'g, Q, R, K, V> where - K: Ord, + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { type Item = Entry<'a, 'g, K, V>; @@ -1845,15 +1853,15 @@ where impl<'a: 'g, 'g, Q, R, K: 'a, V: 'a> DoubleEndedIterator for Range<'a, 'g, Q, R, K, V> where - K: Ord, + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { fn next_back(&mut self) -> Option> { self.tail = match self.tail { Some(n) => self .parent - .search_bound(Bound::Excluded(n.key.borrow()), true, self.guard), + .search_bound::(Bound::Excluded(&n.key), true, self.guard), None => self .parent .search_bound(self.range.end_bound(), true, self.guard), @@ -1861,7 +1869,7 @@ where if let Some(t) = self.tail { match self.head { Some(h) => { - let bound = Bound::Excluded(h.key.borrow()); + let bound = Bound::Excluded(&h.key); if !above_lower_bound(&bound, &t.key) { self.head = None; self.tail = None; @@ -1886,10 +1894,10 @@ where impl fmt::Debug for Range<'_, '_, Q, R, K, V> where - K: Ord + fmt::Debug, + K: Ord + fmt::Debug + Comparable, V: fmt::Debug, R: RangeBounds + fmt::Debug, - Q: ?Sized + Comparable, + Q: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Range") @@ -1903,8 +1911,9 @@ where /// An iterator over reference-counted subset of entries of a `SkipList`. pub struct RefRange<'a, Q, R, K, V> where + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { parent: &'a SkipList, pub(crate) head: Option>, @@ -1915,24 +1924,26 @@ where unsafe impl Send for RefRange<'_, Q, R, K, V> where + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { } unsafe impl Sync for RefRange<'_, Q, R, K, V> where + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { } impl fmt::Debug for RefRange<'_, Q, R, K, V> where - K: fmt::Debug, + K: Ord + fmt::Debug + Comparable, V: fmt::Debug, R: RangeBounds + fmt::Debug, - Q: ?Sized + Comparable, + Q: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RefRange") @@ -1945,26 +1956,9 @@ where impl<'a, Q, R, K: 'a, V: 'a> RefRange<'a, Q, R, K, V> where + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, -{ - /// Decrements a reference count owned by this iterator. - pub fn drop_impl(&mut self, guard: &Guard) { - self.parent.check_guard(guard); - if let Some(e) = self.head.take() { - unsafe { e.node.decrement(guard) }; - } - if let Some(e) = self.tail.take() { - unsafe { e.node.decrement(guard) }; - } - } -} - -impl<'a, Q, R, K: 'a, V: 'a> RefRange<'a, Q, R, K, V> -where - K: Ord, - R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { /// Advances the iterator and returns the next value. pub fn next(&mut self, guard: &Guard) -> Option> { @@ -2045,6 +2039,17 @@ where None } } + + /// Decrements a reference count owned by this iterator. + pub fn drop_impl(&mut self, guard: &Guard) { + self.parent.check_guard(guard); + if let Some(e) = self.head.take() { + unsafe { e.node.decrement(guard) }; + } + if let Some(e) = self.tail.take() { + unsafe { e.node.decrement(guard) }; + } + } } /// An owning iterator over the entries of a `SkipList`. @@ -2129,19 +2134,27 @@ where } /// Helper function to check if a value is above a lower bound -fn above_lower_bound>(bound: &Bound<&T>, other: &V) -> bool { +fn above_lower_bound(bound: &Bound<&T>, other: &V) -> bool +where + T: ?Sized, + V: Comparable, +{ match *bound { Bound::Unbounded => true, - Bound::Included(key) => key.compare(other).is_le(), - Bound::Excluded(key) => key.compare(other).is_lt(), + Bound::Included(key) => other.compare(key).is_ge(), + Bound::Excluded(key) => other.compare(key).is_gt(), } } /// Helper function to check if a value is below an upper bound -fn below_upper_bound>(bound: &Bound<&T>, other: &V) -> bool { +fn below_upper_bound(bound: &Bound<&T>, other: &V) -> bool +where + T: ?Sized, + V: Comparable, +{ match *bound { Bound::Unbounded => true, - Bound::Included(key) => key.compare(other).is_ge(), - Bound::Excluded(key) => key.compare(other).is_gt(), + Bound::Included(key) => other.compare(key).is_le(), + Bound::Excluded(key) => other.compare(key).is_lt(), } } diff --git a/crossbeam-skiplist/src/equivalent.rs b/crossbeam-skiplist/src/equivalent.rs new file mode 100644 index 000000000..80439ac4d --- /dev/null +++ b/crossbeam-skiplist/src/equivalent.rs @@ -0,0 +1,49 @@ +use core::{borrow::Borrow, cmp::Ordering}; + +/// Key equivalence trait. +/// +/// This trait allows hash table lookup to be customized. It has one blanket +/// implementation that uses the regular solution with `Borrow` and `Eq`, just +/// like `HashMap` does, so that you can pass `&str` to lookup into a map with +/// `String` keys and so on. +/// +/// # Contract +/// +/// The implementor **must** hash like `Q`, if it is hashable. +pub trait Equivalent { + /// Compare self to `key` and return `true` if they are equal. + fn equivalent(&self, key: &Q) -> bool; +} + +impl Equivalent for K +where + K: Borrow, + Q: Eq, +{ + #[inline] + fn equivalent(&self, key: &Q) -> bool { + PartialEq::eq(self.borrow(), key) + } +} + +/// Key ordering trait. +/// +/// This trait allows ordered map lookup to be customized. It has one blanket +/// implementation that uses the regular solution with `Borrow` and `Ord`, just +/// like `BTreeMap` does, so that you can pass `&str` to lookup into a map with +/// `String` keys and so on. +pub trait Comparable: Equivalent { + /// Compare self to `key` and return their ordering. + fn compare(&self, key: &Q) -> Ordering; +} + +impl Comparable for K +where + K: Borrow, + Q: Ord, +{ + #[inline] + fn compare(&self, key: &Q) -> Ordering { + Ord::cmp(self.borrow(), key) + } +} diff --git a/crossbeam-skiplist/src/lib.rs b/crossbeam-skiplist/src/lib.rs index e5d137fbe..6dddcc7d2 100644 --- a/crossbeam-skiplist/src/lib.rs +++ b/crossbeam-skiplist/src/lib.rs @@ -245,6 +245,7 @@ extern crate std; #[cfg(all(feature = "alloc", target_has_atomic = "ptr"))] pub mod base; + #[cfg(all(feature = "alloc", target_has_atomic = "ptr"))] #[doc(inline)] pub use crate::base::SkipList; @@ -257,3 +258,6 @@ pub mod set; #[cfg(feature = "std")] #[doc(inline)] pub use crate::{map::SkipMap, set::SkipSet}; + +/// Traits for key comparison in maps. +pub mod equivalent; diff --git a/crossbeam-skiplist/src/map.rs b/crossbeam-skiplist/src/map.rs index 353a1d8ef..9502662d3 100644 --- a/crossbeam-skiplist/src/map.rs +++ b/crossbeam-skiplist/src/map.rs @@ -5,9 +5,11 @@ use std::mem::ManuallyDrop; use std::ops::{Bound, RangeBounds}; use std::ptr; -use crate::base::{self, try_pin_loop}; +use crate::{ + base::{self, try_pin_loop}, + equivalent::Comparable, +}; use crossbeam_epoch as epoch; -use equivalent::Comparable; /// An ordered map based on a lock-free skip list. /// @@ -133,7 +135,8 @@ where /// ``` pub fn contains_key(&self, key: &Q) -> bool where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { let guard = &epoch::pin(); self.inner.contains_key(key, guard) @@ -156,7 +159,8 @@ where /// ``` pub fn get(&self, key: &Q) -> Option> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { let guard = &epoch::pin(); try_pin_loop(|| self.inner.get(key, guard)).map(Entry::new) @@ -190,7 +194,8 @@ where /// ``` pub fn lower_bound<'a, Q>(&'a self, bound: Bound<&Q>) -> Option> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { let guard = &epoch::pin(); try_pin_loop(|| self.inner.lower_bound(bound, guard)).map(Entry::new) @@ -221,7 +226,8 @@ where /// ``` pub fn upper_bound<'a, Q>(&'a self, bound: Bound<&Q>) -> Option> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { let guard = &epoch::pin(); try_pin_loop(|| self.inner.upper_bound(bound, guard)).map(Entry::new) @@ -334,7 +340,8 @@ where pub fn range(&self, range: R) -> Range<'_, Q, R, K, V> where R: RangeBounds, - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { Range { inner: self.inner.ref_range(range), @@ -419,7 +426,8 @@ where /// ``` pub fn remove(&self, key: &Q) -> Option> where - Q: ?Sized + Comparable, + K: Comparable, + Q: ?Sized, { let guard = &epoch::pin(); self.inner.remove(key, guard).map(Entry::new) @@ -715,17 +723,18 @@ impl Drop for Iter<'_, K, V> { /// An iterator over a subset of entries of a `SkipMap`. pub struct Range<'a, Q, R, K, V> where + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { pub(crate) inner: base::RefRange<'a, Q, R, K, V>, } impl<'a, Q, R, K, V> Iterator for Range<'a, Q, R, K, V> where - K: Ord, + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { type Item = Entry<'a, K, V>; @@ -737,9 +746,9 @@ where impl<'a, Q, R, K, V> DoubleEndedIterator for Range<'a, Q, R, K, V> where - K: Ord, + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { fn next_back(&mut self) -> Option> { let guard = &epoch::pin(); @@ -749,10 +758,10 @@ where impl fmt::Debug for Range<'_, Q, R, K, V> where - K: fmt::Debug, + K: Ord + fmt::Debug + Comparable, V: fmt::Debug, R: RangeBounds + fmt::Debug, - Q: ?Sized + Comparable, + Q: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Range") @@ -765,8 +774,9 @@ where impl Drop for Range<'_, Q, R, K, V> where + K: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { fn drop(&mut self) { let guard = &epoch::pin(); diff --git a/crossbeam-skiplist/src/set.rs b/crossbeam-skiplist/src/set.rs index b61b496e0..040e315cf 100644 --- a/crossbeam-skiplist/src/set.rs +++ b/crossbeam-skiplist/src/set.rs @@ -4,9 +4,7 @@ use std::fmt; use std::ops::Deref; use std::ops::{Bound, RangeBounds}; -use equivalent::Comparable; - -use crate::map; +use crate::{equivalent::Comparable, map}; /// A set based on a lock-free skip list. /// @@ -123,7 +121,8 @@ where /// ``` pub fn contains(&self, key: &Q) -> bool where - Q: ?Sized + Comparable, + T: Comparable, + Q: ?Sized, { self.inner.contains_key(key) } @@ -141,7 +140,8 @@ where /// ``` pub fn get(&self, key: &Q) -> Option> where - Q: ?Sized + Comparable, + T: Comparable, + Q: ?Sized, { self.inner.get(key).map(Entry::new) } @@ -172,7 +172,8 @@ where /// ``` pub fn lower_bound<'a, Q>(&'a self, bound: Bound<&Q>) -> Option> where - Q: ?Sized + Comparable, + T: Comparable, + Q: ?Sized, { self.inner.lower_bound(bound).map(Entry::new) } @@ -200,7 +201,8 @@ where /// ``` pub fn upper_bound<'a, Q>(&'a self, bound: Bound<&Q>) -> Option> where - Q: ?Sized + Comparable, + T: Comparable, + Q: ?Sized, { self.inner.upper_bound(bound).map(Entry::new) } @@ -264,7 +266,8 @@ where pub fn range(&self, range: R) -> Range<'_, Q, R, T> where R: RangeBounds, - Q: ?Sized + Comparable, + T: Comparable, + Q: ?Sized, { Range { inner: self.inner.range(range), @@ -311,7 +314,8 @@ where /// ``` pub fn remove(&self, key: &Q) -> Option> where - Q: ?Sized + Comparable, + T: Comparable, + Q: ?Sized, { self.inner.remove(key).map(Entry::new) } @@ -450,7 +454,7 @@ impl<'a, T> Entry<'a, T> { } /// Returns a reference to the value. - pub fn value(&self) -> &'a T { + pub fn value(&self) -> &T { self.inner.key() } @@ -577,17 +581,18 @@ impl fmt::Debug for Iter<'_, T> { /// An iterator over a subset of entries of a `SkipSet`. pub struct Range<'a, Q, R, T> where + T: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { inner: map::Range<'a, Q, R, T, ()>, } impl<'a, Q, R, T> Iterator for Range<'a, Q, R, T> where - T: Ord, + T: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { type Item = Entry<'a, T>; @@ -598,9 +603,9 @@ where impl<'a, Q, R, T> DoubleEndedIterator for Range<'a, Q, R, T> where - T: Ord, + T: Ord + Comparable, R: RangeBounds, - Q: ?Sized + Comparable, + Q: ?Sized, { fn next_back(&mut self) -> Option> { self.inner.next_back().map(Entry::new) @@ -609,9 +614,9 @@ where impl fmt::Debug for Range<'_, Q, R, T> where - T: fmt::Debug, + T: Ord + Comparable + fmt::Debug, R: RangeBounds + fmt::Debug, - Q: ?Sized + Comparable, + Q: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Range") diff --git a/crossbeam-skiplist/tests/base.rs b/crossbeam-skiplist/tests/base.rs index 7af6fa1c5..3f717a6b9 100644 --- a/crossbeam-skiplist/tests/base.rs +++ b/crossbeam-skiplist/tests/base.rs @@ -281,12 +281,7 @@ fn lower_bound() { s.insert(40, 4, guard).release(guard); s.insert(20, 2, guard).release(guard); - assert_eq!( - *s.lower_bound::(Bound::Unbounded, guard) - .unwrap() - .value(), - 1 - ); + assert_eq!(*s.lower_bound(Bound::Unbounded, guard).unwrap().value(), 1); assert_eq!( *s.lower_bound(Bound::Included(&10), guard).unwrap().value(), @@ -366,12 +361,7 @@ fn upper_bound() { s.insert(40, 4, guard).release(guard); s.insert(20, 2, guard).release(guard); - assert_eq!( - *s.upper_bound::(Bound::Unbounded, guard) - .unwrap() - .value(), - 5 - ); + assert_eq!(*s.upper_bound(Bound::Unbounded, guard).unwrap().value(), 5); assert_eq!( *s.upper_bound(Bound::Included(&10), guard).unwrap().value(), @@ -913,7 +903,7 @@ fn drops() { #[test] fn comparable_get() { - use equivalent::{Comparable, Equivalent}; + use crossbeam_skiplist::equivalent::{Comparable, Equivalent}; #[derive(PartialEq, Eq, PartialOrd, Ord)] struct Foo { @@ -945,19 +935,19 @@ fn comparable_get() { } } - impl Equivalent for FooRef<'_> { - fn equivalent(&self, key: &Foo) -> bool { - let a = u64::from_be_bytes(self.data[..8].try_into().unwrap()); - let b = u32::from_be_bytes(self.data[8..].try_into().unwrap()); - a == key.a && b == key.b + impl<'a> Equivalent> for Foo { + fn equivalent(&self, key: &FooRef<'a>) -> bool { + let a = u64::from_be_bytes(key.data[..8].try_into().unwrap()); + let b = u32::from_be_bytes(key.data[8..].try_into().unwrap()); + a == self.a && b == self.b } } - impl Comparable for FooRef<'_> { - fn compare(&self, key: &Foo) -> std::cmp::Ordering { - let a = u64::from_be_bytes(self.data[..8].try_into().unwrap()); - let b = u32::from_be_bytes(self.data[8..].try_into().unwrap()); - Foo { a, b }.cmp(key) + impl<'a> Comparable> for Foo { + fn compare(&self, key: &FooRef<'a>) -> std::cmp::Ordering { + let a = u64::from_be_bytes(key.data[..8].try_into().unwrap()); + let b = u32::from_be_bytes(key.data[8..].try_into().unwrap()); + Foo { a, b }.cmp(self) } } diff --git a/crossbeam-skiplist/tests/map.rs b/crossbeam-skiplist/tests/map.rs index 903ba3cba..3b734f110 100644 --- a/crossbeam-skiplist/tests/map.rs +++ b/crossbeam-skiplist/tests/map.rs @@ -443,7 +443,7 @@ fn lower_bound() { s.insert(40, 4); s.insert(20, 2); - assert_eq!(*s.lower_bound::(Bound::Unbounded).unwrap().value(), 1); + assert_eq!(*s.lower_bound(Bound::Unbounded).unwrap().value(), 1); assert_eq!(*s.lower_bound(Bound::Included(&10)).unwrap().value(), 1); assert_eq!(*s.lower_bound(Bound::Included(&20)).unwrap().value(), 2); @@ -477,7 +477,7 @@ fn upper_bound() { s.insert(40, 4); s.insert(20, 2); - assert_eq!(*s.upper_bound::(Bound::Unbounded).unwrap().value(), 5); + assert_eq!(*s.upper_bound(Bound::Unbounded).unwrap().value(), 5); assert_eq!(*s.upper_bound(Bound::Included(&10)).unwrap().value(), 1); assert_eq!(*s.upper_bound(Bound::Included(&20)).unwrap().value(), 2); @@ -670,212 +670,210 @@ fn iter_range() { vec![90, 80, 70, 60, 50, 40, 30, 20, 10, 0] ); assert_eq!( - s.range::(..) - .map(|x| *x.value()) - .collect::>(), + s.range(..).map(|x| *x.value()).collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Included(&0), Unbounded)) + s.range((Included(&0), Unbounded)) .map(|x| *x.value()) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Included(&0), Included(&60))) + s.range((Included(&0), Included(&60))) .rev() .map(|x| *x.value()) .collect::>(), vec![60, 50, 40, 30, 20, 10, 0] ); assert_eq!( - s.range::((Excluded(&0), Unbounded)) + s.range((Excluded(&0), Unbounded)) .map(|x| *x.value()) .collect::>(), vec![10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Included(&25), Unbounded)) + s.range((Included(&25), Unbounded)) .map(|x| *x.value()) .collect::>(), vec![30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Excluded(&25), Unbounded)) + s.range((Excluded(&25), Unbounded)) .map(|x| *x.value()) .collect::>(), vec![30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Included(&70), Unbounded)) + s.range((Included(&70), Unbounded)) .map(|x| *x.value()) .collect::>(), vec![70, 80, 90] ); assert_eq!( - s.range::((Excluded(&70), Unbounded)) + s.range((Excluded(&70), Unbounded)) .map(|x| *x.value()) .collect::>(), vec![80, 90] ); assert_eq!( - s.range::((Included(&100), Unbounded)) + s.range((Included(&100), Unbounded)) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&100), Unbounded)) + s.range((Excluded(&100), Unbounded)) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Unbounded, Included(&90))) + s.range((Unbounded, Included(&90))) .map(|x| *x.value()) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Unbounded, Excluded(&90))) + s.range((Unbounded, Excluded(&90))) .map(|x| *x.value()) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80] ); assert_eq!( - s.range::((Unbounded, Included(&25))) + s.range((Unbounded, Included(&25))) .map(|x| *x.value()) .collect::>(), vec![0, 10, 20] ); assert_eq!( - s.range::((Unbounded, Excluded(&25))) + s.range((Unbounded, Excluded(&25))) .map(|x| *x.value()) .collect::>(), vec![0, 10, 20] ); assert_eq!( - s.range::((Unbounded, Included(&70))) + s.range((Unbounded, Included(&70))) .map(|x| *x.value()) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70] ); assert_eq!( - s.range::((Unbounded, Excluded(&70))) + s.range((Unbounded, Excluded(&70))) .map(|x| *x.value()) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60] ); assert_eq!( - s.range::((Unbounded, Included(&-1))) + s.range((Unbounded, Included(&-1))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Unbounded, Excluded(&-1))) + s.range((Unbounded, Excluded(&-1))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&25), Included(&80))) + s.range((Included(&25), Included(&80))) .map(|x| *x.value()) .collect::>(), vec![30, 40, 50, 60, 70, 80] ); assert_eq!( - s.range::((Included(&25), Excluded(&80))) + s.range((Included(&25), Excluded(&80))) .map(|x| *x.value()) .collect::>(), vec![30, 40, 50, 60, 70] ); assert_eq!( - s.range::((Excluded(&25), Included(&80))) + s.range((Excluded(&25), Included(&80))) .map(|x| *x.value()) .collect::>(), vec![30, 40, 50, 60, 70, 80] ); assert_eq!( - s.range::((Excluded(&25), Excluded(&80))) + s.range((Excluded(&25), Excluded(&80))) .map(|x| *x.value()) .collect::>(), vec![30, 40, 50, 60, 70] ); assert_eq!( - s.range::((Included(&25), Included(&25))) + s.range((Included(&25), Included(&25))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&25), Excluded(&25))) + s.range((Included(&25), Excluded(&25))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&25), Included(&25))) + s.range((Excluded(&25), Included(&25))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&25), Excluded(&25))) + s.range((Excluded(&25), Excluded(&25))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&50), Included(&50))) + s.range((Included(&50), Included(&50))) .map(|x| *x.value()) .collect::>(), vec![50] ); assert_eq!( - s.range::((Included(&50), Excluded(&50))) + s.range((Included(&50), Excluded(&50))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&50), Included(&50))) + s.range((Excluded(&50), Included(&50))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&50), Excluded(&50))) + s.range((Excluded(&50), Excluded(&50))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&100), Included(&-2))) + s.range((Included(&100), Included(&-2))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&100), Excluded(&-2))) + s.range((Included(&100), Excluded(&-2))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&100), Included(&-2))) + s.range((Excluded(&100), Included(&-2))) .map(|x| *x.value()) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&100), Excluded(&-2))) + s.range((Excluded(&100), Excluded(&-2))) .map(|x| *x.value()) .collect::>(), vec![] diff --git a/crossbeam-skiplist/tests/set.rs b/crossbeam-skiplist/tests/set.rs index 3754a0d48..65003798b 100644 --- a/crossbeam-skiplist/tests/set.rs +++ b/crossbeam-skiplist/tests/set.rs @@ -296,7 +296,7 @@ fn lower_bound() { s.insert(40); s.insert(20); - assert_eq!(*s.lower_bound::(Bound::Unbounded).unwrap(), 10); + assert_eq!(*s.lower_bound(Bound::Unbounded).unwrap(), 10); assert_eq!(*s.lower_bound(Bound::Included(&10)).unwrap(), 10); assert_eq!(*s.lower_bound(Bound::Included(&20)).unwrap(), 20); @@ -330,7 +330,7 @@ fn upper_bound() { s.insert(40); s.insert(20); - assert_eq!(*s.upper_bound::(Bound::Unbounded).unwrap(), 50); + assert_eq!(*s.upper_bound(Bound::Unbounded).unwrap(), 50); assert_eq!(*s.upper_bound(Bound::Included(&10)).unwrap(), 10); assert_eq!(*s.upper_bound(Bound::Included(&20)).unwrap(), 20); @@ -462,203 +462,203 @@ fn iter_range() { vec![90, 80, 70, 60, 50, 40, 30, 20, 10, 0] ); assert_eq!( - s.range::(..).map(|x| *x).collect::>(), + s.range(..).map(|x| *x).collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Included(&0), Unbounded)) + s.range((Included(&0), Unbounded)) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Excluded(&0), Unbounded)) + s.range((Excluded(&0), Unbounded)) .map(|x| *x) .collect::>(), vec![10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Included(&25), Unbounded)) + s.range((Included(&25), Unbounded)) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Excluded(&25), Unbounded)) + s.range((Excluded(&25), Unbounded)) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Included(&70), Unbounded)) + s.range((Included(&70), Unbounded)) .map(|x| *x) .collect::>(), vec![70, 80, 90] ); assert_eq!( - s.range::((Excluded(&70), Unbounded)) + s.range((Excluded(&70), Unbounded)) .map(|x| *x) .collect::>(), vec![80, 90] ); assert_eq!( - s.range::((Included(&100), Unbounded)) + s.range((Included(&100), Unbounded)) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&100), Unbounded)) + s.range((Excluded(&100), Unbounded)) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Unbounded, Included(&90))) + s.range((Unbounded, Included(&90))) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90] ); assert_eq!( - s.range::((Unbounded, Excluded(&90))) + s.range((Unbounded, Excluded(&90))) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70, 80] ); assert_eq!( - s.range::((Unbounded, Included(&25))) + s.range((Unbounded, Included(&25))) .map(|x| *x) .collect::>(), vec![0, 10, 20] ); assert_eq!( - s.range::((Unbounded, Excluded(&25))) + s.range((Unbounded, Excluded(&25))) .map(|x| *x) .collect::>(), vec![0, 10, 20] ); assert_eq!( - s.range::((Unbounded, Included(&70))) + s.range((Unbounded, Included(&70))) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60, 70] ); assert_eq!( - s.range::((Unbounded, Excluded(&70))) + s.range((Unbounded, Excluded(&70))) .map(|x| *x) .collect::>(), vec![0, 10, 20, 30, 40, 50, 60] ); assert_eq!( - s.range::((Unbounded, Included(&-1))) + s.range((Unbounded, Included(&-1))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Unbounded, Excluded(&-1))) + s.range((Unbounded, Excluded(&-1))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&25), Included(&80))) + s.range((Included(&25), Included(&80))) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70, 80] ); assert_eq!( - s.range::((Included(&25), Excluded(&80))) + s.range((Included(&25), Excluded(&80))) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70] ); assert_eq!( - s.range::((Excluded(&25), Included(&80))) + s.range((Excluded(&25), Included(&80))) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70, 80] ); assert_eq!( - s.range::((Excluded(&25), Excluded(&80))) + s.range((Excluded(&25), Excluded(&80))) .map(|x| *x) .collect::>(), vec![30, 40, 50, 60, 70] ); assert_eq!( - s.range::((Included(&25), Included(&25))) + s.range((Included(&25), Included(&25))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&25), Excluded(&25))) + s.range((Included(&25), Excluded(&25))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&25), Included(&25))) + s.range((Excluded(&25), Included(&25))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&25), Excluded(&25))) + s.range((Excluded(&25), Excluded(&25))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&50), Included(&50))) + s.range((Included(&50), Included(&50))) .map(|x| *x) .collect::>(), vec![50] ); assert_eq!( - s.range::((Included(&50), Excluded(&50))) + s.range((Included(&50), Excluded(&50))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&50), Included(&50))) + s.range((Excluded(&50), Included(&50))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&50), Excluded(&50))) + s.range((Excluded(&50), Excluded(&50))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&100), Included(&-2))) + s.range((Included(&100), Included(&-2))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Included(&100), Excluded(&-2))) + s.range((Included(&100), Excluded(&-2))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&100), Included(&-2))) + s.range((Excluded(&100), Included(&-2))) .map(|x| *x) .collect::>(), vec![] ); assert_eq!( - s.range::((Excluded(&100), Excluded(&-2))) + s.range((Excluded(&100), Excluded(&-2))) .map(|x| *x) .collect::>(), vec![]