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}