rings_core/storage/
sled.rs1#![warn(missing_docs)]
2
3use async_trait::async_trait;
6use itertools::Itertools;
7use serde::de::DeserializeOwned;
8use serde::Serialize;
9
10use crate::error::Error;
11use crate::error::Result;
12use crate::storage::KvStorageInterface;
13
14#[allow(dead_code)]
16pub struct SledStorage {
17 db: sled::Db,
18 cap: u32,
19 path: String,
20}
21
22impl SledStorage {
23 pub async fn new_with_cap_and_path<P>(cap: u32, path: P) -> Result<Self>
27 where P: AsRef<std::path::Path> {
28 let db = sled::Config::new()
29 .path(path.as_ref())
30 .mode(sled::Mode::HighThroughput)
31 .cache_capacity(cap as u64)
32 .open()
33 .map_err(Error::SledError)?;
34 Ok(Self {
35 db,
36 cap,
37 path: path.as_ref().to_string_lossy().to_string(),
38 })
39 }
40}
41
42#[async_trait]
43impl<V> KvStorageInterface<V> for SledStorage
44where V: Serialize + DeserializeOwned + Sync
45{
46 async fn get(&self, key: &str) -> Result<Option<V>> {
47 let v = self.db.get(key).map_err(Error::SledError)?;
48 if let Some(v) = v {
49 let v = v.as_ref();
50 return bincode::deserialize(v)
51 .map_err(Error::BincodeDeserialize)
52 .map(|r| Some(r));
53 }
54 Ok(None)
55 }
56
57 async fn put(&self, key: &str, value: &V) -> Result<()> {
58 let data = bincode::serialize(&value).map_err(Error::BincodeSerialize)?;
59 tracing::debug!("Try inserting key: {:?}", key);
60 self.db.insert(key, data).map_err(Error::SledError)?;
61 Ok(())
62 }
63
64 async fn get_all(&self) -> Result<Vec<(String, V)>> {
65 let iter = self.db.iter();
66 Ok(iter
67 .flatten()
68 .flat_map(|(k, v)| {
69 Some((
70 std::str::from_utf8(k.as_ref()).ok()?.to_string(),
71 bincode::deserialize(v.as_ref()).ok()?,
72 ))
73 })
74 .collect_vec())
75 }
76
77 async fn remove(&self, key: &str) -> Result<()> {
78 self.db
79 .remove(key.to_string().as_bytes())
80 .map_err(Error::SledError)?;
81 Ok(())
82 }
83
84 async fn clear(&self) -> Result<()> {
85 self.db.clear().map_err(Error::SledError)?;
86 Ok(())
87 }
88
89 async fn count(&self) -> Result<u32> {
90 Ok(self.db.len() as u32)
91 }
92}
93
94impl std::fmt::Debug for SledStorage {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 f.debug_struct("SledStorage")
97 .field("cap", &self.cap)
98 .field("path", &self.path)
99 .finish()
100 }
101}
102
103#[cfg(test)]
104mod test {
105 use serde::Deserialize;
106 use serde::Serialize;
107
108 use super::*;
109
110 #[derive(Debug, Serialize, Deserialize)]
111 struct TestStorageStruct {
112 content: String,
113 }
114
115 #[tokio::test]
116 async fn test_kv_storage_put_delete() {
117 let storage = SledStorage::new_with_cap_and_path(4096, "tmp/test_db")
118 .await
119 .unwrap();
120 let key1 = "test1".to_owned();
121 let data1 = TestStorageStruct {
122 content: "test1".to_string(),
123 };
124 storage.put(&key1, &data1).await.unwrap();
125 let count1 =
126 <SledStorage as KvStorageInterface<TestStorageStruct>>::count::<'_, '_>(&storage)
127 .await
128 .unwrap();
129 assert!(count1 == 1, "expect count1.1 is {}, got {}", 1, count1);
130 let got_v1: TestStorageStruct = storage.get(&key1).await.unwrap().unwrap();
131 assert!(
132 got_v1.content.eq(data1.content.as_str()),
133 "expect value1 is {}, got {}",
134 data1.content,
135 got_v1.content
136 );
137
138 let key2 = "test2".to_owned();
139 let data2 = TestStorageStruct {
140 content: "test2".to_string(),
141 };
142
143 storage.put(&key2, &data2).await.unwrap();
144
145 let count_got_2 =
146 <SledStorage as KvStorageInterface<TestStorageStruct>>::count::<'_, '_>(&storage)
147 .await
148 .unwrap();
149 assert!(count_got_2 == 2, "expect count 2, got {count_got_2}");
150
151 let all_entries: Vec<(String, TestStorageStruct)> = storage.get_all().await.unwrap();
152 assert!(
153 all_entries.len() == 2,
154 "all_entries len expect 2, got {}",
155 all_entries.len()
156 );
157
158 let keys = [key1, key2];
159 let values = [data1.content, data2.content];
160
161 assert!(
162 all_entries
163 .iter()
164 .any(|(k, v)| { keys.contains(k) && values.contains(&v.content) }),
165 "not found items"
166 );
167 let data3: u64 = 101;
168 let key3 = "key3".to_owned();
169 storage.put(&key3, &data3).await.unwrap();
170 let got_d3: u64 = storage.get(&key3).await.unwrap().unwrap();
171 assert!(data3 == got_d3, "expect {data3}, got {got_d3}");
172
173 <SledStorage as KvStorageInterface<TestStorageStruct>>::clear::<'_, '_>(&storage)
175 .await
176 .unwrap();
177 let count1 =
178 <SledStorage as KvStorageInterface<TestStorageStruct>>::count::<'_, '_>(&storage)
179 .await
180 .unwrap();
181 assert!(count1 == 0, "expect count1 is 0, got {count1}");
182 storage.db.flush_async().await.unwrap();
183
184 drop(storage)
185 }
186}