Skip to main content

rings_core/storage/
memory.rs

1use async_trait::async_trait;
2use dashmap::DashMap;
3
4use crate::error::Result;
5use crate::storage::KvStorageInterface;
6
7/// In-memory storage implementation backed by a concurrent map.
8#[derive(Debug, Default)]
9pub struct MemStorage<V>
10where V: Clone
11{
12    table: DashMap<String, V>,
13}
14
15impl<V> MemStorage<V>
16where V: Clone
17{
18    /// Create an empty memory storage table.
19    pub fn new() -> Self {
20        Self {
21            table: DashMap::default(),
22        }
23    }
24}
25
26#[cfg_attr(all(feature = "wasm", target_family = "wasm"), async_trait(?Send))]
27#[cfg_attr(not(all(feature = "wasm", target_family = "wasm")), async_trait)]
28impl<V> KvStorageInterface<V> for MemStorage<V>
29where V: Clone + Send + Sync
30{
31    async fn get(&self, key: &str) -> Result<Option<V>> {
32        Ok(self.table.get(&key.to_string()).map(|v| v.value().clone()))
33    }
34
35    async fn put(&self, key: &str, value: &V) -> Result<()> {
36        self.table.insert(key.to_string(), value.clone());
37        Ok(())
38    }
39
40    async fn get_all(&self) -> Result<Vec<(String, V)>> {
41        Ok(self.table.clone().into_iter().collect())
42    }
43
44    async fn remove(&self, key: &str) -> Result<()> {
45        match self.get(key).await? {
46            Some(_) => self.table.remove(key),
47            None => None,
48        };
49        Ok(())
50    }
51
52    async fn clear(&self) -> Result<()> {
53        self.table.clear();
54        Ok(())
55    }
56
57    async fn count(&self) -> Result<u32> {
58        Ok(self.table.len() as u32)
59    }
60}
61
62#[cfg(not(all(feature = "wasm", target_family = "wasm")))]
63#[cfg(test)]
64mod tests {
65    use super::*;
66    use crate::ecc::SecretKey;
67
68    #[tokio::test]
69    async fn test_memstorage_basic_interface_should_work() {
70        let store = MemStorage::new();
71        let addr = SecretKey::random().address().to_string();
72
73        assert_eq!(store.get(&addr).await.unwrap(), None);
74
75        store.put(&addr, &"value 1".to_string()).await.unwrap();
76        assert_eq!(store.get(&addr).await.unwrap(), Some("value 1".into()));
77
78        store.put(&addr, &"value 2".to_string()).await.unwrap();
79        assert_eq!(store.get(&addr).await.unwrap(), Some("value 2".into()));
80    }
81}