Skip to content

Commit

Permalink
refactor: Refactor sync structures and improve debugging output
Browse files Browse the repository at this point in the history
- Renamed and relocated `sync_index_set.rs` and `sync_index_map.rs` files into a new `sync` directory for better file structuring.
- Enabled custom `Debug` implementations for sync variants of `FrozenIndexSet` and `FrozenIndexMap`.
- Introduced feature-gated support for `indexmap` within `sync` with `index_map` and `index_set` modules.
  • Loading branch information
huitseeker committed Oct 26, 2023
1 parent aec4451 commit 166078c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 26 deletions.
4 changes: 0 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ pub mod vec;
pub mod index_map;
#[cfg(feature = "indexmap")]
pub mod index_set;
#[cfg(feature = "indexmap")]
pub mod sync_index_map;
#[cfg(feature = "indexmap")]
pub mod sync_index_set;

pub mod sync;

Expand Down
42 changes: 31 additions & 11 deletions src/sync_index_map.rs → src/sync/index_map.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
use std::borrow::Borrow;
use std::collections::hash_map::RandomState;
use std::fmt;
use std::hash::{BuildHasher, Hash};
use std::iter::FromIterator;
use std::ops::Index;

use indexmap::IndexMap;
use stable_deref_trait::StableDeref;
use std::sync::RwLock;
use std::sync::{RwLock, TryLockError};

/// Append-only threadsafe version of `indexmap::IndexMap` where
/// insertion does not require mutable access
#[derive(Debug)]
pub struct FrozenIndexMap<K, V, S = RandomState> {
map: RwLock<IndexMap<K, V, S>>,
}

// safety: UnsafeCell implies !Sync
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for FrozenIndexMap<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.map.try_read() {
Ok(guard) => guard.fmt(f),
Err(TryLockError::Poisoned(err)) => {
f.debug_tuple("FrozenIndexMap").field(&&**err.get_ref()).finish()
}
Err(TryLockError::WouldBlock) => {
struct LockedPlaceholder;
impl fmt::Debug for LockedPlaceholder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("<locked>")
}
}
f.debug_tuple("FrozenIndexMap")
.field(&LockedPlaceholder)
.finish()
}
}
}
}

impl<K: Eq + Hash, V> FrozenIndexMap<K, V> {
pub fn new() -> Self {
Expand All @@ -41,7 +61,7 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
///
/// # Example
/// ```
/// use elsa::sync_index_map::FrozenIndexMap;
/// use elsa::sync::index_map::FrozenIndexMap;
/// let map = FrozenIndexMap::new();
/// assert_eq!(map.insert(1, Box::new("a")), &"a");
/// assert_eq!(map.insert(1, Box::new("b")), &"a");
Expand Down Expand Up @@ -69,7 +89,7 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
///
/// # Example
/// ```
/// use elsa::sync_index_map::FrozenIndexMap;
/// use elsa::sync::index_map::FrozenIndexMap;
/// let map = FrozenIndexMap::new();
/// assert_eq!(map.insert_full(12, Box::new("a")), (0, &"a"));
/// assert_eq!(map.insert_full(12, Box::new("b")), (0, &"a"));
Expand All @@ -94,7 +114,7 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
/// # Examples
///
/// ```
/// use elsa::sync_index_map::FrozenIndexMap;
/// use elsa::sync::index_map::FrozenIndexMap;
///
/// let map = FrozenIndexMap::new();
/// map.insert(1, Box::new("a"));
Expand All @@ -120,7 +140,7 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
/// # Examples
///
/// ```
/// use elsa::sync_index_map::FrozenIndexMap;
/// use elsa::sync::index_map::FrozenIndexMap;
///
/// let map = FrozenIndexMap::new();
/// let (idx, _ref) = map.insert_full(Box::new("foo"), Box::new("a"));
Expand Down Expand Up @@ -150,7 +170,7 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
/// # Examples
///
/// ```
/// use elsa::sync_index_map::FrozenIndexMap;
/// use elsa::sync::index_map::FrozenIndexMap;
///
/// let map = FrozenIndexMap::new();
/// map.insert(1, Box::new("a"));
Expand All @@ -177,7 +197,7 @@ impl<K, V, S> FrozenIndexMap<K, V, S> {
/// # Examples
///
/// ```
/// use elsa::sync_index_map::FrozenIndexMap;
/// use elsa::sync::index_map::FrozenIndexMap;
///
/// let map = FrozenIndexMap::new();
/// map.insert(1, Box::new("a"));
Expand Down Expand Up @@ -209,7 +229,7 @@ impl<K, V, S> FrozenIndexMap<K, V, S> {
/// # Examples
///
/// ```
/// use elsa::sync_index_map::FrozenIndexMap;
/// use elsa::sync::index_map::FrozenIndexMap;
///
/// let map = FrozenIndexMap::new();
/// assert_eq!(map.is_empty(), true);
Expand Down Expand Up @@ -242,7 +262,7 @@ where
/// # Examples
///
/// ```
/// use elsa::sync_index_map::FrozenIndexMap;
/// use elsa::sync::index_map::FrozenIndexMap;
///
/// let map = FrozenIndexMap::new();
/// map.insert(1, Box::new("a"));
Expand Down
40 changes: 29 additions & 11 deletions src/sync_index_set.rs → src/sync/index_set.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
use std::borrow::Borrow;
use std::collections::hash_map::RandomState;
use std::fmt;
use std::hash::{BuildHasher, Hash};
use std::iter::FromIterator;
use std::ops::Index;
use std::sync::RwLock;
use std::sync::{RwLock, TryLockError};

use indexmap::IndexSet;
use stable_deref_trait::StableDeref;

/// Append-only threadsafeversion of `indexmap::IndexSet` where
/// insertion does not require mutable access
#[derive(Debug)]
pub struct FrozenIndexSet<T, S = RandomState> {
set: RwLock<IndexSet<T, S>>,
}

// safety: UnsafeCell implies !Sync
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for FrozenIndexSet<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.set.try_read() {
Ok(guard) => guard.fmt(f),
Err(TryLockError::Poisoned(err)) => {
f.debug_tuple("FrozenIndexSet").field(&&**err.get_ref()).finish()
}
Err(TryLockError::WouldBlock) => {
struct LockedPlaceholder;
impl fmt::Debug for LockedPlaceholder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("<locked>")
}
}
f.debug_tuple("FrozenIndexSet")
.field(&LockedPlaceholder)
.finish()
}
}
}
}

impl<T: Eq + Hash> FrozenIndexSet<T> {
pub fn new() -> Self {
Expand All @@ -34,7 +54,7 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
///
/// # Example
/// ```
/// use elsa::sync_index_set::FrozenIndexSet;
/// use elsa::sync::index_set::FrozenIndexSet;
/// let set = FrozenIndexSet::new();
/// let a_ref = set.insert(Box::new("a"));
/// let aa = "a";
Expand Down Expand Up @@ -63,7 +83,7 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
///
/// # Example
/// ```
/// use elsa::sync_index_set::FrozenIndexSet;
/// use elsa::sync::index_set::FrozenIndexSet;
/// let map = FrozenIndexSet::new();
/// assert_eq!(map.insert_full(Box::new("a")), (0, &"a"));
/// assert_eq!(map.insert_full(Box::new("b")), (1, &"b"));
Expand All @@ -86,7 +106,7 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
///
/// # Example
/// ```
/// use elsa::sync_index_set::FrozenIndexSet;
/// use elsa::sync::index_set::FrozenIndexSet;
/// let map = FrozenIndexSet::new();
/// assert_eq!(map.insert_probe(Box::new("a")), (0, true));
/// assert_eq!(map.insert_probe(Box::new("b")), (1, true));
Expand All @@ -102,7 +122,7 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
/// # Examples
///
/// ```
/// use elsa::sync_index_set::FrozenIndexSet;
/// use elsa::sync::index_set::FrozenIndexSet;
///
/// let set = FrozenIndexSet::new();
/// set.insert(Box::new("a"));
Expand All @@ -125,7 +145,7 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
/// # Examples
///
/// ```
/// use elsa::sync_index_set::FrozenIndexSet;
/// use elsa::sync::index_set::FrozenIndexSet;
///
/// let set = FrozenIndexSet::new();
/// set.insert(Box::new("a"));
Expand Down Expand Up @@ -153,7 +173,7 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
/// # Examples
///
/// ```
/// use elsa::sync_index_set::FrozenIndexSet;
/// use elsa::sync::index_set::FrozenIndexSet;
///
/// let set = FrozenIndexSet::new();
/// set.insert(Box::new("a"));
Expand Down Expand Up @@ -184,8 +204,6 @@ impl<T, S> FrozenIndexSet<T, S> {
pub fn as_mut(&mut self) -> &mut IndexSet<T, S> {
self.set.get_mut().unwrap()
}

// TODO add more
}

impl<T, S> From<IndexSet<T, S>> for FrozenIndexSet<T, S> {
Expand Down
5 changes: 5 additions & 0 deletions src/sync.rs → src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ use std::sync::atomic::Ordering;
use std::sync::RwLock;
use std::sync::TryLockError;

#[cfg(feature = "indexmap")]
pub mod index_map;
#[cfg(feature = "indexmap")]
pub mod index_set;

/// Append-only threadsafe version of `std::collections::HashMap` where
/// insertion does not require mutable access
pub struct FrozenMap<K, V> {
Expand Down

0 comments on commit 166078c

Please sign in to comment.