Skip to content

Commit c85d149

Browse files
committed
add shared and sharedMap to stratum apps
1 parent 143c852 commit c85d149

5 files changed

Lines changed: 147 additions & 0 deletions

File tree

integration-tests/Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

miner-apps/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

stratum-apps/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ utoipa-swagger-ui = { version = "9.0.2", features = ["axum"], optional = true }
5555
# Common external dependencies that roles always need
5656
ext-config = { version = "0.14.0", features = ["toml"], package = "config" }
5757
shellexpand = "3.1.1"
58+
dashmap = "6.1.0"
5859

5960
[features]
6061
default = ["network", "config", "std"]

stratum-apps/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,6 @@ pub mod coinbase_output_constraints;
7878

7979
/// Fallback coordinator
8080
pub mod fallback_coordinator;
81+
82+
/// Synchronous and shared data structure wrapper
83+
pub mod shared;

stratum-apps/src/shared.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
use std::{hash::Hash, sync::Arc};
2+
3+
use dashmap::DashMap;
4+
use std::sync::Mutex;
5+
6+
#[derive(Debug)]
7+
pub struct Shared<T>(Arc<Mutex<T>>);
8+
9+
impl<T> Clone for Shared<T> {
10+
fn clone(&self) -> Self {
11+
Shared(Arc::clone(&self.0))
12+
}
13+
}
14+
15+
impl<T> Shared<T> {
16+
pub fn new(v: T) -> Self {
17+
Shared(Arc::new(Mutex::new(v)))
18+
}
19+
20+
pub fn with<F, R>(&self, f: F) -> R
21+
where
22+
F: FnOnce(&mut T) -> R,
23+
{
24+
let mut lock = self.0.lock().unwrap();
25+
let return_value = f(&mut *lock);
26+
drop(lock);
27+
return_value
28+
}
29+
30+
pub fn get(&self) -> T
31+
where
32+
T: Clone,
33+
{
34+
self.with(|v| v.clone())
35+
}
36+
37+
pub fn set(&self, value: T) {
38+
self.with(|v| *v = value);
39+
}
40+
}
41+
pub struct SharedMap<K: Eq + Clone + Hash, V>(Arc<DashMap<K, V>>);
42+
43+
impl<K: Eq + Clone + Hash, V> Clone for SharedMap<K, V> {
44+
fn clone(&self) -> Self {
45+
SharedMap(Arc::clone(&self.0))
46+
}
47+
}
48+
49+
impl<K: Eq + Hash + Clone, V> SharedMap<K, V> {
50+
pub fn new() -> Self {
51+
SharedMap(Arc::new(DashMap::new()))
52+
}
53+
54+
pub fn with<F, R>(&self, key: &K, f: F) -> Option<R>
55+
where
56+
F: FnOnce(&V) -> R,
57+
{
58+
let guard = self.0.get(key)?;
59+
let result = f(guard.value());
60+
drop(guard);
61+
Some(result)
62+
}
63+
64+
pub fn with_mut<F, R>(&self, key: &K, f: F) -> Option<R>
65+
where
66+
F: FnOnce(&mut V) -> R,
67+
{
68+
let mut guard = self.0.get_mut(key)?;
69+
let result = f(guard.value_mut());
70+
Some(result)
71+
}
72+
73+
pub fn for_each<F, Ret>(&self, mut f: F)
74+
where
75+
F: FnMut(K, &V) -> Ret,
76+
{
77+
for entry in self.0.iter() {
78+
f(entry.key().clone(), entry.value());
79+
}
80+
}
81+
82+
pub fn for_each_mut<F, Ret>(&self, mut f: F)
83+
where
84+
F: FnMut(K, &mut V) -> Ret,
85+
{
86+
for mut entry in self.0.iter_mut() {
87+
f(entry.key().clone(), entry.value_mut());
88+
}
89+
}
90+
91+
pub fn try_for_each_mut<F, E>(&self, mut f: F) -> Result<(), E>
92+
where
93+
F: FnMut(K, &mut V) -> Result<(), E>,
94+
{
95+
for mut entry in self.0.iter_mut() {
96+
f(entry.key().clone(), entry.value_mut())?;
97+
}
98+
Ok(())
99+
}
100+
101+
pub fn insert(&self, key: K, value: V) -> Option<V> {
102+
self.0.insert(key, value)
103+
}
104+
105+
pub fn remove(&self, key: &K) -> Option<(K, V)> {
106+
self.0.remove(key)
107+
}
108+
109+
pub fn contains_key(&self, key: &K) -> bool {
110+
self.0.contains_key(key)
111+
}
112+
113+
pub fn retain<F>(&self, f: F)
114+
where
115+
F: FnMut(&K, &mut V) -> bool,
116+
{
117+
self.0.retain(f);
118+
}
119+
120+
pub fn keys(&self) -> Vec<K>
121+
where
122+
K: Clone,
123+
{
124+
self.0.iter().map(|e| e.key().clone()).collect()
125+
}
126+
127+
pub fn len(&self) -> usize {
128+
self.0.len()
129+
}
130+
131+
pub fn is_empty(&self) -> bool {
132+
self.0.is_empty()
133+
}
134+
}
135+
136+
impl<K: Eq + Hash + Clone, V> Default for SharedMap<K, V> {
137+
fn default() -> Self {
138+
Self::new()
139+
}
140+
}

0 commit comments

Comments
 (0)