rex/storage.rs
1use std::sync::Arc;
2
3use dashmap::DashMap;
4use parking_lot::FairMutex;
5
6use crate::{node::Node, Kind, Rex, StateId};
7
8/// [`StateStore`] is the storage layer for all state machines associated with a given manager.
9/// Every state tree is associated with a particular Mutex
10/// this allows separate state hirearchies to be acted upon concurrently
11/// while making operations in a particular tree blocking
12pub struct StateStore<Id, S> {
13 trees: DashMap<Id, Arc<FairMutex<Node<Id, S>>>>,
14}
15
16impl<K> Default for StateStore<StateId<K>, K::State>
17where
18 K: Rex,
19{
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25/// Entries are distinguished from Nodes
26/// by the [`Arc<FairMutex<_>>`] that contains a given node.
27/// Every child node in a particular tree should have
28/// should be represented by `N` additional [`StoreTree`]s
29/// in a given [`StateStore`] indexed by that particular node's `id` field.
30pub(crate) type Tree<K> = Arc<FairMutex<Node<StateId<K>, <K as Kind>::State>>>;
31
32impl<K: Rex> StateStore<StateId<K>, K::State> {
33 #[must_use]
34 pub fn new() -> Self {
35 Self {
36 trees: DashMap::new(),
37 }
38 }
39
40 /// # Panics
41 ///
42 /// Will panic if [`StateId`] is nil
43 pub fn new_tree(node: Node<StateId<K>, K::State>) -> Tree<K> {
44 assert!(!node.id.is_nil());
45 Arc::new(FairMutex::new(node))
46 }
47
48 /// insert node creates a new reference to the same node
49 /// # Panics
50 ///
51 /// Will panic if [`StateId`] is nil
52 pub fn insert_ref(&self, id: StateId<K>, node: Tree<K>) {
53 assert!(!id.is_nil());
54 self.trees.insert(id, node);
55 }
56
57 // decrements the reference count on a given `Node`
58 /// # Panics
59 ///
60 /// Will panic if [`StateId`] is nil
61 pub fn remove_ref(&self, id: StateId<K>) {
62 assert!(!id.is_nil());
63 self.trees.remove(&id);
64 }
65
66 /// # Panics
67 ///
68 /// Will panic if [`StateId`] is nil
69 pub fn get_tree(&self, id: StateId<K>) -> Option<Tree<K>> {
70 assert!(!id.is_nil());
71 let node = self.trees.get(&id);
72 node.map(|n| n.value().clone())
73 }
74}