laminar_core/cluster/control/barrier/
kv.rs1use super::{async_trait, FxHashMap, Mutex, NodeId};
4
5#[async_trait]
7pub trait ClusterKv: Send + Sync + 'static {
8 async fn write(&self, key: &str, value: String);
10 async fn write_checked(&self, key: &str, value: String) -> Result<(), String> {
20 self.write(key, value).await;
21 Ok(())
22 }
23 async fn read_from(&self, who: NodeId, key: &str) -> Option<String>;
25 async fn read_from_checked(&self, who: NodeId, key: &str) -> Result<Option<String>, String> {
31 Ok(self.read_from(who, key).await)
32 }
33 async fn scan(&self, key: &str) -> Vec<(NodeId, String)>;
35 async fn scan_checked(&self, key: &str) -> Result<Vec<(NodeId, String)>, String> {
40 Ok(self.scan(key).await)
41 }
42}
43
44#[derive(Debug)]
46pub struct InMemoryKv {
47 local_id: NodeId,
48 state: Mutex<FxHashMap<(NodeId, String), String>>,
49}
50
51impl InMemoryKv {
52 #[must_use]
54 pub fn new(local_id: NodeId) -> Self {
55 Self {
56 local_id,
57 state: Mutex::new(FxHashMap::default()),
58 }
59 }
60
61 pub fn seed(&self, peer: NodeId, key: &str, value: String) {
63 self.state.lock().insert((peer, key.to_string()), value);
64 }
65}
66
67#[async_trait]
68impl ClusterKv for InMemoryKv {
69 async fn write(&self, key: &str, value: String) {
70 self.state
71 .lock()
72 .insert((self.local_id, key.to_string()), value);
73 }
74
75 async fn read_from(&self, who: NodeId, key: &str) -> Option<String> {
76 self.state.lock().get(&(who, key.to_string())).cloned()
77 }
78
79 async fn scan(&self, key: &str) -> Vec<(NodeId, String)> {
80 self.state
81 .lock()
82 .iter()
83 .filter(|((_, k), _)| k == key)
84 .map(|((n, _), v)| (*n, v.clone()))
85 .collect()
86 }
87}