From b2692f659feb5f5b4455f3b209ae40e13e9fbb28 Mon Sep 17 00:00:00 2001 From: squidfunk Date: Sat, 17 Jan 2026 21:58:44 +0100 Subject: [PATCH 1/8] style: improve variable naming Signed-off-by: squidfunk --- crates/zrx-store/src/store/decorator/ordered/iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/zrx-store/src/store/decorator/ordered/iter.rs b/crates/zrx-store/src/store/decorator/ordered/iter.rs index b7e90ac..ff64ae5 100644 --- a/crates/zrx-store/src/store/decorator/ordered/iter.rs +++ b/crates/zrx-store/src/store/decorator/ordered/iter.rs @@ -103,7 +103,7 @@ where loop { // Check if we have keys left with the current value if let Some(key) = self.keys.next() { - return self.value.clone().map(|v| (key, v)); + return self.value.clone().map(|value| (key, value)); } // Fetch the next value and associated keys From 49f00473c0a525ea07da50cffd849498f56d2878 Mon Sep 17 00:00:00 2001 From: squidfunk Date: Sun, 18 Jan 2026 10:26:17 +0100 Subject: [PATCH 2/8] docs: harmonize comments for `PhantomData` Signed-off-by: squidfunk --- crates/zrx-scheduler/src/scheduler/session.rs | 2 +- crates/zrx-scheduler/src/scheduler/tick.rs | 2 +- crates/zrx-store/src/store/decorator/changed.rs | 2 +- crates/zrx-store/src/store/decorator/indexed.rs | 2 +- crates/zrx-store/src/store/decorator/indexed/iter.rs | 2 +- crates/zrx-stream/src/stream.rs | 2 +- crates/zrx-stream/src/stream/operator/audit.rs | 2 +- crates/zrx-stream/src/stream/operator/coalesce.rs | 2 +- crates/zrx-stream/src/stream/operator/debounce.rs | 2 +- crates/zrx-stream/src/stream/operator/delta_filter_map.rs | 2 +- crates/zrx-stream/src/stream/operator/delta_map.rs | 2 +- crates/zrx-stream/src/stream/operator/delta_reduce.rs | 2 +- crates/zrx-stream/src/stream/operator/difference.rs | 2 +- crates/zrx-stream/src/stream/operator/filter_map.rs | 2 +- crates/zrx-stream/src/stream/operator/intersection.rs | 2 +- crates/zrx-stream/src/stream/operator/join.rs | 2 +- crates/zrx-stream/src/stream/operator/join_filter.rs | 2 +- crates/zrx-stream/src/stream/operator/join_filter_map.rs | 2 +- crates/zrx-stream/src/stream/operator/join_map.rs | 2 +- crates/zrx-stream/src/stream/operator/map.rs | 2 +- crates/zrx-stream/src/stream/operator/reduce.rs | 2 +- crates/zrx-stream/src/stream/operator/sample.rs | 2 +- crates/zrx-stream/src/stream/operator/throttle.rs | 2 +- crates/zrx-stream/src/stream/operator/transpose.rs | 2 +- crates/zrx-stream/src/stream/operator/union.rs | 2 +- crates/zrx-stream/src/stream/workspace/workflow/schedulable.rs | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/crates/zrx-scheduler/src/scheduler/session.rs b/crates/zrx-scheduler/src/scheduler/session.rs index 5fac4bf..62078bd 100644 --- a/crates/zrx-scheduler/src/scheduler/session.rs +++ b/crates/zrx-scheduler/src/scheduler/session.rs @@ -63,7 +63,7 @@ pub struct Session { id: usize, /// Item submission sender. sender: Sender>, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-scheduler/src/scheduler/tick.rs b/crates/zrx-scheduler/src/scheduler/tick.rs index b354ded..b3fa25f 100644 --- a/crates/zrx-scheduler/src/scheduler/tick.rs +++ b/crates/zrx-scheduler/src/scheduler/tick.rs @@ -49,7 +49,7 @@ pub struct Tick { report: Report, /// Waiting deadline. deadline: Option, - /// Type marker. + /// Capture types. marker: PhantomData<(I, S)>, } diff --git a/crates/zrx-store/src/store/decorator/changed.rs b/crates/zrx-store/src/store/decorator/changed.rs index 057c861..7d1c34e 100644 --- a/crates/zrx-store/src/store/decorator/changed.rs +++ b/crates/zrx-store/src/store/decorator/changed.rs @@ -81,7 +81,7 @@ where store: S, /// Keys of changed items. changes: HashSet, - /// Marker for types. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-store/src/store/decorator/indexed.rs b/crates/zrx-store/src/store/decorator/indexed.rs index b4b4fa9..09f3881 100644 --- a/crates/zrx-store/src/store/decorator/indexed.rs +++ b/crates/zrx-store/src/store/decorator/indexed.rs @@ -108,7 +108,7 @@ where ordering: Vec, /// Comparator. comparator: C, - /// Marker for types. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-store/src/store/decorator/indexed/iter.rs b/crates/zrx-store/src/store/decorator/indexed/iter.rs index 7c546c1..87859ed 100644 --- a/crates/zrx-store/src/store/decorator/indexed/iter.rs +++ b/crates/zrx-store/src/store/decorator/indexed/iter.rs @@ -43,7 +43,7 @@ pub struct IntoIter { store: S, /// Ordering of values. ordering: vec::IntoIter, - /// Marker for types. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream.rs b/crates/zrx-stream/src/stream.rs index b3fd102..b88a5f1 100644 --- a/crates/zrx-stream/src/stream.rs +++ b/crates/zrx-stream/src/stream.rs @@ -50,7 +50,7 @@ pub struct Stream { id: usize, /// Associated workflow. workflow: Workflow, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/audit.rs b/crates/zrx-stream/src/stream/operator/audit.rs index 4c79771..02efaa7 100644 --- a/crates/zrx-stream/src/stream/operator/audit.rs +++ b/crates/zrx-stream/src/stream/operator/audit.rs @@ -47,7 +47,7 @@ use super::{Operator, OperatorExt}; struct Audit { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/coalesce.rs b/crates/zrx-stream/src/stream/operator/coalesce.rs index 89f0b9a..45d9e02 100644 --- a/crates/zrx-stream/src/stream/operator/coalesce.rs +++ b/crates/zrx-stream/src/stream/operator/coalesce.rs @@ -44,7 +44,7 @@ use super::Operator; /// Coalesce operator. struct Coalesce { - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/debounce.rs b/crates/zrx-stream/src/stream/operator/debounce.rs index a2c0c81..5229ac6 100644 --- a/crates/zrx-stream/src/stream/operator/debounce.rs +++ b/crates/zrx-stream/src/stream/operator/debounce.rs @@ -47,7 +47,7 @@ use super::{Operator, OperatorExt}; struct Debounce { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/delta_filter_map.rs b/crates/zrx-stream/src/stream/operator/delta_filter_map.rs index 061efb3..e963b1f 100644 --- a/crates/zrx-stream/src/stream/operator/delta_filter_map.rs +++ b/crates/zrx-stream/src/stream/operator/delta_filter_map.rs @@ -47,7 +47,7 @@ use super::Operator; struct DeltaFilterMap { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/delta_map.rs b/crates/zrx-stream/src/stream/operator/delta_map.rs index ff3ef7d..64abe2e 100644 --- a/crates/zrx-stream/src/stream/operator/delta_map.rs +++ b/crates/zrx-stream/src/stream/operator/delta_map.rs @@ -47,7 +47,7 @@ use super::Operator; struct DeltaMap { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/delta_reduce.rs b/crates/zrx-stream/src/stream/operator/delta_reduce.rs index 67c1cdb..051531e 100644 --- a/crates/zrx-stream/src/stream/operator/delta_reduce.rs +++ b/crates/zrx-stream/src/stream/operator/delta_reduce.rs @@ -51,7 +51,7 @@ struct DeltaReduce { function: F, /// Store of items. store: HashMap>, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/difference.rs b/crates/zrx-stream/src/stream/operator/difference.rs index 240bba9..1fd94b3 100644 --- a/crates/zrx-stream/src/stream/operator/difference.rs +++ b/crates/zrx-stream/src/stream/operator/difference.rs @@ -44,7 +44,7 @@ use super::Operator; /// Difference operator. struct Difference { - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/filter_map.rs b/crates/zrx-stream/src/stream/operator/filter_map.rs index 2f5dc60..0c11f12 100644 --- a/crates/zrx-stream/src/stream/operator/filter_map.rs +++ b/crates/zrx-stream/src/stream/operator/filter_map.rs @@ -46,7 +46,7 @@ use super::{Operator, OperatorExt}; struct FilterMap { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/intersection.rs b/crates/zrx-stream/src/stream/operator/intersection.rs index 5fab953..cd6b5aa 100644 --- a/crates/zrx-stream/src/stream/operator/intersection.rs +++ b/crates/zrx-stream/src/stream/operator/intersection.rs @@ -44,7 +44,7 @@ use super::Operator; /// Intersection operator. struct Intersection { - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/join.rs b/crates/zrx-stream/src/stream/operator/join.rs index 3f1b49d..173f915 100644 --- a/crates/zrx-stream/src/stream/operator/join.rs +++ b/crates/zrx-stream/src/stream/operator/join.rs @@ -48,7 +48,7 @@ use super::Operator; /// Join operator. struct Join { - /// Type marker. + /// Capture types. marker: PhantomData<(T, P)>, } diff --git a/crates/zrx-stream/src/stream/operator/join_filter.rs b/crates/zrx-stream/src/stream/operator/join_filter.rs index 32f4ddd..722144a 100644 --- a/crates/zrx-stream/src/stream/operator/join_filter.rs +++ b/crates/zrx-stream/src/stream/operator/join_filter.rs @@ -51,7 +51,7 @@ use super::Operator; struct JoinFilter { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData

, } diff --git a/crates/zrx-stream/src/stream/operator/join_filter_map.rs b/crates/zrx-stream/src/stream/operator/join_filter_map.rs index 63c55df..cb24de1 100644 --- a/crates/zrx-stream/src/stream/operator/join_filter_map.rs +++ b/crates/zrx-stream/src/stream/operator/join_filter_map.rs @@ -51,7 +51,7 @@ use super::Operator; struct JoinFilterMap { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData<(U, P)>, } diff --git a/crates/zrx-stream/src/stream/operator/join_map.rs b/crates/zrx-stream/src/stream/operator/join_map.rs index 29ad052..540aa84 100644 --- a/crates/zrx-stream/src/stream/operator/join_map.rs +++ b/crates/zrx-stream/src/stream/operator/join_map.rs @@ -51,7 +51,7 @@ use super::Operator; struct JoinMap { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData<(U, P)>, } diff --git a/crates/zrx-stream/src/stream/operator/map.rs b/crates/zrx-stream/src/stream/operator/map.rs index e93a6ae..73ad9ee 100644 --- a/crates/zrx-stream/src/stream/operator/map.rs +++ b/crates/zrx-stream/src/stream/operator/map.rs @@ -46,7 +46,7 @@ use super::{Operator, OperatorExt}; struct Map { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData, /// Concurrency. concurrency: Option, diff --git a/crates/zrx-stream/src/stream/operator/reduce.rs b/crates/zrx-stream/src/stream/operator/reduce.rs index 2b32f0e..b92dcae 100644 --- a/crates/zrx-stream/src/stream/operator/reduce.rs +++ b/crates/zrx-stream/src/stream/operator/reduce.rs @@ -53,7 +53,7 @@ struct Reduce { function: F, /// Store of items. store: HashMap, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/sample.rs b/crates/zrx-stream/src/stream/operator/sample.rs index b8f5b6f..3aea376 100644 --- a/crates/zrx-stream/src/stream/operator/sample.rs +++ b/crates/zrx-stream/src/stream/operator/sample.rs @@ -47,7 +47,7 @@ use super::{Operator, OperatorExt}; struct Sample { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/throttle.rs b/crates/zrx-stream/src/stream/operator/throttle.rs index 8ba56e5..3081021 100644 --- a/crates/zrx-stream/src/stream/operator/throttle.rs +++ b/crates/zrx-stream/src/stream/operator/throttle.rs @@ -47,7 +47,7 @@ use super::{Operator, OperatorExt}; struct Throttle { /// Operator function. function: F, - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/transpose.rs b/crates/zrx-stream/src/stream/operator/transpose.rs index fa437ae..d2e00ee 100644 --- a/crates/zrx-stream/src/stream/operator/transpose.rs +++ b/crates/zrx-stream/src/stream/operator/transpose.rs @@ -44,7 +44,7 @@ use super::{Operator, OperatorExt}; /// Transpose operator. struct Transpose { - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/operator/union.rs b/crates/zrx-stream/src/stream/operator/union.rs index 53450fa..1fc2b37 100644 --- a/crates/zrx-stream/src/stream/operator/union.rs +++ b/crates/zrx-stream/src/stream/operator/union.rs @@ -44,7 +44,7 @@ use super::Operator; /// Union operator. struct Union { - /// Type marker. + /// Capture types. marker: PhantomData, } diff --git a/crates/zrx-stream/src/stream/workspace/workflow/schedulable.rs b/crates/zrx-stream/src/stream/workspace/workflow/schedulable.rs index 0117463..f5746d7 100644 --- a/crates/zrx-stream/src/stream/workspace/workflow/schedulable.rs +++ b/crates/zrx-stream/src/stream/workspace/workflow/schedulable.rs @@ -47,7 +47,7 @@ use crate::stream::operator::Operator; pub struct Schedulable { /// Operator. operator: O, - /// Type marker. + /// Capture types. marker: PhantomData, } From 533ddb8f18ef12005f2033c6720d8714ac841658 Mon Sep 17 00:00:00 2001 From: squidfunk Date: Sun, 18 Jan 2026 12:49:38 +0100 Subject: [PATCH 3/8] docs: correct link in docstring Signed-off-by: squidfunk --- crates/zrx-store/src/queue.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/zrx-store/src/queue.rs b/crates/zrx-store/src/queue.rs index 95c79c9..5a04691 100644 --- a/crates/zrx-store/src/queue.rs +++ b/crates/zrx-store/src/queue.rs @@ -331,8 +331,10 @@ where /// /// This method only updates the data of the [`Item`], but does not change /// the values of [`Item::deadline`] in case the item already exists. The - /// caller might use [`Queue::insert_if_changed`] to check, if any of those - /// values should be changed deliberately. + /// caller might use [`Queue::insert_if_changed`][] to check, if any of + /// those values should be changed deliberately. + /// + /// [`Queue::insert_if_changed`]: crate::store::StoreMut::insert_if_changed /// /// # Examples /// From 602e7d2995681524a3885ffd94555294be9585ad Mon Sep 17 00:00:00 2001 From: squidfunk Date: Sun, 18 Jan 2026 13:27:40 +0100 Subject: [PATCH 4/8] docs: correct links to `Default::default` in docstrings Signed-off-by: squidfunk --- crates/zrx-store/src/queue.rs | 3 ++- crates/zrx-store/src/store/decorator/changed.rs | 6 ++++-- crates/zrx-store/src/store/decorator/indexed.rs | 3 ++- crates/zrx-store/src/store/decorator/ordered.rs | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/zrx-store/src/queue.rs b/crates/zrx-store/src/queue.rs index 5a04691..df1bc14 100644 --- a/crates/zrx-store/src/queue.rs +++ b/crates/zrx-store/src/queue.rs @@ -661,12 +661,13 @@ impl Default for Queue> where K: Key, { - /// Creates a queue with [`HashMap::default`] as a store. + /// Creates a queue with [`HashMap::default`][] as a store. /// /// Note that this method does not allow to customize the [`BuildHasher`][], /// but uses [`ahash`] by default, which is the fastest known hasher. /// /// [`BuildHasher`]: std::hash::BuildHasher + /// [`HashMap::default`]: Default::default /// /// # Examples /// diff --git a/crates/zrx-store/src/store/decorator/changed.rs b/crates/zrx-store/src/store/decorator/changed.rs index 7d1c34e..8b3863e 100644 --- a/crates/zrx-store/src/store/decorator/changed.rs +++ b/crates/zrx-store/src/store/decorator/changed.rs @@ -49,10 +49,11 @@ use crate::store::{ /// recorded chronologically, but always returned in random order, because of /// the use of [`HashSet`] as a data structure for change management. /// -/// Note that it's a good idea to use [`Changed::default`], since it leverages +/// Note that it's a good idea to use [`Changed::default`][], since it leverages /// [`ahash`] as a [`BuildHasher`][], which is the fastest known hasher. /// /// [`BuildHasher`]: std::hash::BuildHasher +/// [`Changed::default`]: Default::default /// /// # Examples /// @@ -579,12 +580,13 @@ impl Default for Changed> where K: Key, { - /// Creates a tracking decorator with [`HashMap::default`] as a store. + /// Creates a tracking decorator with [`HashMap::default`][] as a store. /// /// Note that this method does not allow to customize the [`BuildHasher`][], /// but uses [`ahash`] by default, which is the fastest known hasher. /// /// [`BuildHasher`]: std::hash::BuildHasher + /// [`HashMap::default`]: Default::default /// /// # Examples /// diff --git a/crates/zrx-store/src/store/decorator/indexed.rs b/crates/zrx-store/src/store/decorator/indexed.rs index 09f3881..554fc23 100644 --- a/crates/zrx-store/src/store/decorator/indexed.rs +++ b/crates/zrx-store/src/store/decorator/indexed.rs @@ -56,7 +56,7 @@ pub use iter::IntoIter; /// implemented, so updating and removing values is supported, while ensuring /// the ordering stays intact. /// -/// Note that it's a good idea to use [`Indexed::default`], since it leverages +/// Note that it's a good idea to use [`Indexed::default`][], since it leverages /// [`ahash`] as a [`BuildHasher`][], which is the fastest known hasher. /// /// __Warning__: the affected ranges for insertions and deletions only cover the @@ -76,6 +76,7 @@ pub use iter::IntoIter; /// /// [`BTreeMap`]: std::collections::BTreeMap /// [`BuildHasher`]: std::hash::BuildHasher +/// [`Indexed::default`]: Default::default /// [`Ordered`]: crate::store::decorator::Ordered /// [`StoreMutRef`]: crate::store::StoreMutRef /// diff --git a/crates/zrx-store/src/store/decorator/ordered.rs b/crates/zrx-store/src/store/decorator/ordered.rs index 9fe9c7d..b2230d0 100644 --- a/crates/zrx-store/src/store/decorator/ordered.rs +++ b/crates/zrx-store/src/store/decorator/ordered.rs @@ -52,11 +52,12 @@ pub use iter::IntoIter; /// /// This implementation uses a [`BTreeMap`] over a [`BinaryHeap`][], because the /// latter does not expose an efficient API for maintaining the heap invariant. -/// Note that it's a good idea to use [`Ordered::default`], since it leverages +/// Note that it's a good idea to use [`Ordered::default`][], since it leverages /// [`ahash`] as a [`BuildHasher`][], which is the fastest known hasher. /// /// [`BinaryHeap`]: std::collections::BinaryHeap /// [`BuildHasher`]: std::hash::BuildHasher +/// [`Ordered::default`]: Default::default /// /// # Examples /// From 879a8f45e015e20aedaae36b19c5d1c59346465e Mon Sep 17 00:00:00 2001 From: squidfunk Date: Sun, 18 Jan 2026 14:10:02 +0100 Subject: [PATCH 5/8] refactor!: change behavior of `Changes::clear` to drop changes Signed-off-by: squidfunk --- crates/zrx-store/src/store/decorator/changed.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/crates/zrx-store/src/store/decorator/changed.rs b/crates/zrx-store/src/store/decorator/changed.rs index 8b3863e..dfb8ca7 100644 --- a/crates/zrx-store/src/store/decorator/changed.rs +++ b/crates/zrx-store/src/store/decorator/changed.rs @@ -223,7 +223,7 @@ where impl StoreMut for Changed where K: Key, - S: StoreMut + StoreKeys, + S: StoreMut, { /// Updates the value identified by the key. /// @@ -336,8 +336,13 @@ where /// Clears the store, removing all items. /// - /// Unfortunately, this operation has O(n) compexity, as all keys need to - /// be recorded as changed, which requires iterating over the entire store. + /// Note that this also clears all recorded changes. In order to know which + /// which items are cleared, iterate over the store via [`Changed::keys`][] + /// or [`Changed::iter`][] before clearing the store, which emits all keys + /// as well as values, if necessary. + /// + /// [`Changed::iter`]: crate::store::StoreIterable::iter + /// [`Changed::keys`]: crate::store::StoreKeys::keys /// /// # Examples /// @@ -354,11 +359,7 @@ where /// assert!(store.is_empty()); /// ``` fn clear(&mut self) { - for key in self.store.keys() { - if !self.changes.contains(key) { - self.changes.insert(key.clone()); - } - } + self.changes.clear(); self.store.clear(); } } From 98f33c54a89e22cf7a541ad2941cfbdd95f4c9a6 Mon Sep 17 00:00:00 2001 From: squidfunk Date: Mon, 19 Jan 2026 16:26:05 +0100 Subject: [PATCH 6/8] refactor: remove unnecessary lifetime trait bounds from impls Signed-off-by: squidfunk --- crates/zrx-store/src/store/collection/core.rs | 2 -- crates/zrx-store/src/store/collection/litemap.rs | 1 - 2 files changed, 3 deletions(-) diff --git a/crates/zrx-store/src/store/collection/core.rs b/crates/zrx-store/src/store/collection/core.rs index b7a34d0..c861f92 100644 --- a/crates/zrx-store/src/store/collection/core.rs +++ b/crates/zrx-store/src/store/collection/core.rs @@ -378,7 +378,6 @@ where fn keys<'a>(&'a self) -> impl Iterator where K: 'a, - V: 'a, { HashMap::keys(self) } @@ -748,7 +747,6 @@ where fn keys<'a>(&'a self) -> impl Iterator where K: 'a, - V: 'a, { BTreeMap::keys(self) } diff --git a/crates/zrx-store/src/store/collection/litemap.rs b/crates/zrx-store/src/store/collection/litemap.rs index 5e6a8a6..a57c00e 100644 --- a/crates/zrx-store/src/store/collection/litemap.rs +++ b/crates/zrx-store/src/store/collection/litemap.rs @@ -393,7 +393,6 @@ where fn keys<'a>(&'a self) -> impl Iterator where K: 'a, - V: 'a, { LiteMap::keys(self) } From bfebfca878ae1e0fc8c62b26dec5469ad4906faa Mon Sep 17 00:00:00 2001 From: squidfunk Date: Mon, 19 Jan 2026 16:26:35 +0100 Subject: [PATCH 7/8] feature: add `Store` impls for `Slab` Signed-off-by: squidfunk --- crates/zrx-store/src/store/collection.rs | 1 + crates/zrx-store/src/store/collection/slab.rs | 387 ++++++++++++++++++ 2 files changed, 388 insertions(+) create mode 100644 crates/zrx-store/src/store/collection/slab.rs diff --git a/crates/zrx-store/src/store/collection.rs b/crates/zrx-store/src/store/collection.rs index bf56d99..ebafdb2 100644 --- a/crates/zrx-store/src/store/collection.rs +++ b/crates/zrx-store/src/store/collection.rs @@ -28,6 +28,7 @@ mod core; #[cfg(feature = "litemap")] mod litemap; +mod slab; // ---------------------------------------------------------------------------- // Functions diff --git a/crates/zrx-store/src/store/collection/slab.rs b/crates/zrx-store/src/store/collection/slab.rs new file mode 100644 index 0000000..fe36e58 --- /dev/null +++ b/crates/zrx-store/src/store/collection/slab.rs @@ -0,0 +1,387 @@ +// Copyright (c) 2025-2026 Zensical and contributors + +// SPDX-License-Identifier: MIT +// All contributions are certified under the DCO + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +// ---------------------------------------------------------------------------- + +//! Store implementations for `slab`. + +use slab::Slab; +use std::borrow::Borrow; + +use crate::store::{ + Key, Store, StoreIterable, StoreIterableMut, StoreKeys, StoreMut, + StoreMutRef, StoreValues, +}; + +// ---------------------------------------------------------------------------- +// Trait implementations +// ---------------------------------------------------------------------------- + +impl Store for Slab<(K, V)> +where + K: Key, +{ + /// Returns a reference to the value identified by the key. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::{Store, StoreMut}; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Obtain reference to value + /// let value = Store::get(&store, &"key"); + /// assert_eq!(value, Some(&42)); + /// ``` + #[inline] + fn get(&self, key: &Q) -> Option<&V> + where + K: Borrow, + Q: Key, + { + Slab::iter(self).find_map(|(_, (check, value))| { + (check.borrow() == key).then_some(value) + }) + } + + /// Returns whether the store contains the key. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::{Store, StoreMut}; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Ensure presence of key + /// let check = Store::contains_key(&store, &"key"); + /// assert_eq!(check, true); + /// ``` + #[inline] + fn contains_key(&self, key: &Q) -> bool + where + K: Borrow, + Q: Key, + { + Slab::iter(self).any(|(_, (check, _))| check.borrow() == key) + } + + /// Returns the number of items in the store. + #[inline] + fn len(&self) -> usize { + Slab::len(self) + } +} + +impl StoreMut for Slab<(K, V)> +where + K: Key, +{ + /// Inserts the value identified by the key. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::StoreMut; + /// + /// // Create store and insert value + /// let mut store = HashMap::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// ``` + #[inline] + fn insert(&mut self, key: K, value: V) -> Option { + for (_, (check, prior)) in self.iter_mut() { + if check == &key { + return Some(std::mem::replace(prior, value)); + } + } + + // Insert new entry + self.insert((key, value)); + None + } + + /// Removes the value identified by the key. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::StoreMut; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Remove and return value + /// let value = StoreMut::remove(&mut store, &"key"); + /// assert_eq!(value, Some(42)); + /// ``` + #[inline] + fn remove(&mut self, key: &Q) -> Option + where + K: Borrow, + Q: Key, + { + self.remove_entry(key).map(|(_, value)| value) + } + + /// Removes the value identified by the key and returns both. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::StoreMut; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Remove and return entry + /// let entry = StoreMut::remove_entry(&mut store, &"key"); + /// assert_eq!(entry, Some(("key", 42))); + /// ``` + #[inline] + fn remove_entry(&mut self, key: &Q) -> Option<(K, V)> + where + K: Borrow, + Q: Key, + { + Slab::iter(self) + .position(|(_, (check, _))| check.borrow() == key) + .map(|index| self.remove(index)) + } + + /// Clears the store, removing all items. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::StoreMut; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Clear store + /// StoreMut::clear(&mut store); + /// assert!(store.is_empty()); + /// ``` + #[inline] + fn clear(&mut self) { + Slab::clear(self); + } +} + +impl StoreMutRef for Slab<(K, V)> +where + K: Key, +{ + /// Returns a mutable reference to the value identified by the key. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::{StoreMut, StoreMutRef}; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Obtain mutable reference to value + /// let mut value = StoreMutRef::get_mut(&mut store, &"key"); + /// assert_eq!(value, Some(&mut 42)); + /// ``` + #[inline] + fn get_mut(&mut self, key: &Q) -> Option<&mut V> + where + K: Borrow, + Q: Key, + { + Slab::iter_mut(self).find_map(|(_, entry)| { + (entry.0.borrow() == key).then_some(&mut entry.1) + }) + } + + /// Returns a mutable reference to the value or creates the default. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::StoreMutRef; + /// + /// // Create store + /// let mut store = Slab::new(); + /// # let _: Slab<(_, i32)> = store; + /// + /// // Obtain mutable reference to value + /// let value = StoreMutRef::get_or_insert_default(&mut store, &"key"); + /// assert_eq!(value, &mut 0); + /// ``` + #[inline] + fn get_or_insert_default(&mut self, key: &K) -> &mut V + where + V: Default, + { + let index = Slab::iter(self) + .position(|(_, (check, _))| check.borrow() == key) + .unwrap_or_else(|| Slab::insert(self, (key.clone(), V::default()))); + + // Return mutable reference + &mut self[index].1 + } +} + +impl StoreIterable for Slab<(K, V)> +where + K: Key, +{ + /// Creates an iterator over the store. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::{StoreIterable, StoreMut}; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Create iterator over the store + /// for (key, value) in StoreIterable::iter(&store) { + /// println!("{key}: {value}"); + /// } + /// ``` + #[inline] + fn iter<'a>(&'a self) -> impl Iterator + where + K: 'a, + V: 'a, + { + Slab::iter(self).map(|(_, (key, value))| (key, value)) + } +} + +impl StoreIterableMut for Slab<(K, V)> +where + K: Key, +{ + /// Creates a mutable iterator over the store. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::{StoreIterableMut, StoreMut}; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Create iterator over the store + /// for (key, value) in StoreIterableMut::iter_mut(&mut store) { + /// println!("{key}: {value}"); + /// } + /// ``` + #[inline] + fn iter_mut<'a>(&'a mut self) -> impl Iterator + where + K: 'a, + V: 'a, + { + Slab::iter_mut(self).map(|(_, (key, value))| (&*key, value)) + } +} + +impl StoreKeys for Slab<(K, V)> +where + K: Key, +{ + /// Creates a key iterator over the store. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::{StoreKeys, StoreMut}; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Create iterator over the store + /// for key in StoreKeys::keys(&store) { + /// println!("{key}"); + /// } + /// ``` + #[inline] + fn keys<'a>(&'a self) -> impl Iterator + where + K: 'a, + { + Slab::iter(self).map(|(_, (key, _))| key) + } +} + +impl StoreValues for Slab<(K, V)> +where + K: Key, +{ + /// Creates a key iterator over the store. + /// + /// # Examples + /// + /// ``` + /// use slab::Slab; + /// use zrx_store::{StoreKeys, StoreMut}; + /// + /// // Create store and initial state + /// let mut store = Slab::new(); + /// StoreMut::insert(&mut store, "key", 42); + /// + /// // Create iterator over the store + /// for key in StoreKeys::values(&store) { + /// println!("{key}"); + /// } + /// ``` + #[inline] + fn values<'a>(&'a self) -> impl Iterator + where + V: 'a, + { + Slab::iter(self).map(|(_, (_, value))| value) + } +} From 1b15aef51135b71d6142e43dddc9a8a45688232d Mon Sep 17 00:00:00 2001 From: squidfunk Date: Mon, 19 Jan 2026 16:30:47 +0100 Subject: [PATCH 8/8] docs: fix doctests for `Slab` impls Signed-off-by: squidfunk --- crates/zrx-store/src/store/collection/slab.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/zrx-store/src/store/collection/slab.rs b/crates/zrx-store/src/store/collection/slab.rs index fe36e58..19dc8d2 100644 --- a/crates/zrx-store/src/store/collection/slab.rs +++ b/crates/zrx-store/src/store/collection/slab.rs @@ -113,7 +113,7 @@ where /// use zrx_store::StoreMut; /// /// // Create store and insert value - /// let mut store = HashMap::new(); + /// let mut store = Slab::new(); /// StoreMut::insert(&mut store, "key", 42); /// ``` #[inline] @@ -366,14 +366,14 @@ where /// /// ``` /// use slab::Slab; - /// use zrx_store::{StoreKeys, StoreMut}; + /// use zrx_store::{StoreValues, StoreMut}; /// /// // Create store and initial state /// let mut store = Slab::new(); /// StoreMut::insert(&mut store, "key", 42); /// /// // Create iterator over the store - /// for key in StoreKeys::values(&store) { + /// for key in StoreValues::values(&store) { /// println!("{key}"); /// } /// ```