Skip to content

Commit

Permalink
feat(tree_index): relax trait bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
wvwwvwwv committed Apr 12, 2024
1 parent e74255a commit a6a0a8c
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 517 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk

# IntelliJ
.idea

# macOS
**/.DS_Store

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Version 2

2.0.20

* Relax trait bounds of `TreeIndex`.

2.0.19

* Remove unnecessary trait bounds from type definitions of `HashCache`, `HashIndex`, `HashMap`, and `HashSet`.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "scc"
description = "High performance containers and utilities for concurrent and asynchronous programming"
documentation = "https://docs.rs/scc"
version = "2.0.19"
version = "2.0.20"
authors = ["wvwwvwwv <[email protected]>"]
edition = "2021"
rust-version = "1.65.0"
Expand Down
34 changes: 17 additions & 17 deletions src/hash_table/bucket_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ impl<K, V, L: LruList, const TYPE: char> BucketArray<K, V, L, TYPE> {
self.array_len
}

/// Returns a reference to a [`Bucket`] at the given position.
#[inline]
pub(crate) fn bucket(&self, index: usize) -> &Bucket<K, V, L, TYPE> {
debug_assert!(index < self.num_buckets());
unsafe { &(*(self.bucket_ptr.add(index))) }
}

/// Returns a mutable reference to a [`Bucket`] at the given position.
#[allow(clippy::mut_from_ref)]
#[inline]
Expand Down Expand Up @@ -53,19 +60,6 @@ impl<K, V, L: LruList, const TYPE: char> BucketArray<K, V, L, TYPE> {
}

impl<K, V, L: LruList, const TYPE: char> BucketArray<K, V, L, TYPE> {
/// Returns the minimum capacity.
#[inline]
pub const fn minimum_capacity() -> usize {
BUCKET_LEN << 1
}

/// Returns the partial hash value of the given hash.
#[allow(clippy::cast_possible_truncation)]
#[inline]
pub(crate) const fn partial_hash(hash: u64) -> u8 {
(hash % (1 << 8)) as u8
}

/// Creates a new [`BucketArray`] of the given capacity.
///
/// `capacity` is the desired number entries, not the number of [`Bucket`] instances.
Expand Down Expand Up @@ -132,11 +126,17 @@ impl<K, V, L: LruList, const TYPE: char> BucketArray<K, V, L, TYPE> {
}
}

/// Returns a reference to a [`Bucket`] at the given position.
/// Returns the minimum capacity.
#[inline]
pub(crate) fn bucket(&self, index: usize) -> &Bucket<K, V, L, TYPE> {
debug_assert!(index < self.num_buckets());
unsafe { &(*(self.bucket_ptr.add(index))) }
pub const fn minimum_capacity() -> usize {
BUCKET_LEN << 1
}

/// Returns the partial hash value of the given hash.
#[allow(clippy::cast_possible_truncation)]
#[inline]
pub(crate) const fn partial_hash(hash: u64) -> u8 {
(hash % (1 << 8)) as u8
}

/// Returns a reference to its rehashing metadata.
Expand Down
157 changes: 60 additions & 97 deletions src/tree_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,35 +55,22 @@ use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed};
///
/// [`TreeIndex`] is impervious to out-of-memory errors and panics in user specified code on one
/// condition; `K::drop` and `V::drop` must not panic.
pub struct TreeIndex<K, V>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
{
pub struct TreeIndex<K, V> {
root: AtomicShared<Node<K, V>>,
}

/// An iterator over the entries of a [`TreeIndex`].
///
/// An [`Iter`] iterates over all the entries that survive the [`Iter`] in monotonically increasing
/// order.
pub struct Iter<'t, 'g, K, V>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
{
pub struct Iter<'t, 'g, K, V> {
root: &'t AtomicShared<Node<K, V>>,
leaf_scanner: Option<Scanner<'g, K, V>>,
guard: &'g Guard,
}

/// An iterator over a sub-range of entries in a [`TreeIndex`].
pub struct Range<'t, 'g, K, V, R>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
R: RangeBounds<K>,
{
pub struct Range<'t, 'g, K, V, R: RangeBounds<K>> {
root: &'t AtomicShared<Node<K, V>>,
leaf_scanner: Option<Scanner<'g, K, V>>,
range: R,
Expand All @@ -92,11 +79,7 @@ where
guard: &'g Guard,
}

impl<K, V> TreeIndex<K, V>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
{
impl<K, V> TreeIndex<K, V> {
/// Creates an empty [`TreeIndex`].
///
/// # Examples
Expand All @@ -114,6 +97,48 @@ where
}
}

/// Clears the [`TreeIndex`].
///
/// # Examples
///
/// ```
/// use scc::TreeIndex;
///
/// let treeindex: TreeIndex<u64, u32> = TreeIndex::new();
///
/// treeindex.clear();
/// assert_eq!(treeindex.len(), 0);
/// ```
#[inline]
pub fn clear(&self) {
self.root.swap((None, Tag::None), Relaxed);
}

/// Returns the depth of the [`TreeIndex`].
///
/// # Examples
///
/// ```
/// use scc::TreeIndex;
///
/// let treeindex: TreeIndex<u64, u32> = TreeIndex::new();
/// assert_eq!(treeindex.depth(), 0);
/// ```
#[inline]
pub fn depth(&self) -> usize {
let guard = Guard::new();
self.root
.load(Acquire, &guard)
.as_ref()
.map_or(0, |root_ref| root_ref.depth(1, &guard))
}
}

impl<K, V> TreeIndex<K, V>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
{
/// Inserts a key-value pair.
///
/// # Errors
Expand Down Expand Up @@ -572,23 +597,6 @@ where
self.peek(key, &Guard::new()).is_some()
}

/// Clears the [`TreeIndex`].
///
/// # Examples
///
/// ```
/// use scc::TreeIndex;
///
/// let treeindex: TreeIndex<u64, u32> = TreeIndex::new();
///
/// treeindex.clear();
/// assert_eq!(treeindex.len(), 0);
/// ```
#[inline]
pub fn clear(&self) {
self.root.swap((None, Tag::None), Relaxed);
}

/// Returns the size of the [`TreeIndex`].
///
/// It internally scans all the leaf nodes, and therefore the time complexity is O(N).
Expand Down Expand Up @@ -624,25 +632,6 @@ where
!self.iter(&guard).any(|_| true)
}

/// Returns the depth of the [`TreeIndex`].
///
/// # Examples
///
/// ```
/// use scc::TreeIndex;
///
/// let treeindex: TreeIndex<u64, u32> = TreeIndex::new();
/// assert_eq!(treeindex.depth(), 0);
/// ```
#[inline]
pub fn depth(&self) -> usize {
let guard = Guard::new();
self.root
.load(Acquire, &guard)
.as_ref()
.map_or(0, |root_ref| root_ref.depth(1, &guard))
}

/// Returns an [`Iter`].
///
/// The returned [`Iter`] starts scanning from the minimum key-value pair. Key-value pairs
Expand Down Expand Up @@ -721,11 +710,7 @@ where
}
}

impl<K, V> Default for TreeIndex<K, V>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
{
impl<K, V> Default for TreeIndex<K, V> {
/// Creates a [`TreeIndex`] with the default parameters.
///
/// # Examples
Expand Down Expand Up @@ -754,11 +739,7 @@ where
}
}

impl<'t, 'g, K, V> Iter<'t, 'g, K, V>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
{
impl<'t, 'g, K, V> Iter<'t, 'g, K, V> {
#[inline]
fn new(root: &'t AtomicShared<Node<K, V>>, guard: &'g Guard) -> Iter<'t, 'g, K, V> {
Iter::<'t, 'g, K, V> {
Expand All @@ -769,11 +750,7 @@ where
}
}

impl<'t, 'g, K, V> Debug for Iter<'t, 'g, K, V>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
{
impl<'t, 'g, K, V> Debug for Iter<'t, 'g, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Iter")
.field("root", &self.root)
Expand Down Expand Up @@ -829,19 +806,9 @@ where
{
}

impl<'t, 'g, K, V> UnwindSafe for Iter<'t, 'g, K, V>
where
K: 'static + Clone + Ord + UnwindSafe,
V: 'static + Clone + UnwindSafe,
{
}
impl<'t, 'g, K, V> UnwindSafe for Iter<'t, 'g, K, V> {}

impl<'t, 'g, K, V, R> Range<'t, 'g, K, V, R>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
R: RangeBounds<K>,
{
impl<'t, 'g, K, V, R: RangeBounds<K>> Range<'t, 'g, K, V, R> {
#[inline]
fn new(
root: &'t AtomicShared<Node<K, V>>,
Expand All @@ -857,7 +824,14 @@ where
guard,
}
}
}

impl<'t, 'g, K, V, R> Range<'t, 'g, K, V, R>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
R: RangeBounds<K>,
{
#[inline]
fn next_unbounded(&mut self) -> Option<(&'g K, &'g V)> {
if self.leaf_scanner.is_none() {
Expand Down Expand Up @@ -929,12 +903,7 @@ where
}
}

impl<'t, 'g, K, V, R> Debug for Range<'t, 'g, K, V, R>
where
K: 'static + Clone + Ord,
V: 'static + Clone,
R: RangeBounds<K>,
{
impl<'t, 'g, K, V, R: RangeBounds<K>> Debug for Range<'t, 'g, K, V, R> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Range")
Expand Down Expand Up @@ -1005,10 +974,4 @@ where
{
}

impl<'t, 'g, K, V, R> UnwindSafe for Range<'t, 'g, K, V, R>
where
K: 'static + Clone + Ord + UnwindSafe,
V: 'static + Clone + UnwindSafe,
R: RangeBounds<K> + UnwindSafe,
{
}
impl<'t, 'g, K, V, R> UnwindSafe for Range<'t, 'g, K, V, R> where R: RangeBounds<K> + UnwindSafe {}
Loading

0 comments on commit a6a0a8c

Please sign in to comment.