async_kvdb/
lib.rs

1#[cfg(feature = "json")]
2mod json;
3#[cfg(feature = "proto")]
4mod proto;
5
6pub use async_trait::async_trait;
7use bytes::Bytes;
8use smol_str::SmolStr;
9use std::collections::HashMap;
10
11#[cfg(feature = "json")]
12pub use json::KvdbJsonExt;
13#[cfg(feature = "proto")]
14pub use proto::KvdbProtoExt;
15
16pub type Key = SmolStr;
17pub type Value = Bytes;
18pub type KeyValue = (Key, Value);
19pub type Filter = dyn Fn(&Key) -> bool + Send + Sync;
20
21pub enum DbOp {
22    Insert { key: Key, value: Value },
23    InsertMany { data: HashMap<Key, Value> },
24    Delete { key: Key },
25    DeleteMany { keys: Vec<Key> },
26    DeleteAll,
27}
28
29#[derive(Default)]
30pub struct DbOps {
31    pub clear: bool,
32    pub insert: HashMap<Key, Value>,
33    pub delete: Vec<Key>,
34}
35
36#[derive(Default)]
37pub struct DbOpMerger {
38    need_clear: bool,
39    ops: HashMap<Key, Option<Value>>,
40}
41impl DbOpMerger {
42    pub fn new() -> Self {
43        Self {
44            need_clear: false,
45            ops: HashMap::new(),
46        }
47    }
48    pub fn is_empty(&self) -> bool {
49        !self.need_clear && self.ops.is_empty()
50    }
51    pub fn merge(&mut self, op: DbOp) {
52        match op {
53            DbOp::Insert { key, value } => {
54                self.ops.insert(key, Some(value));
55            }
56            DbOp::InsertMany { data } => {
57                for (key, value) in data {
58                    self.ops.insert(key, Some(value));
59                }
60            }
61            DbOp::Delete { key } => {
62                self.ops.insert(key, None);
63            }
64            DbOp::DeleteMany { keys } => {
65                for key in keys {
66                    self.ops.insert(key, None);
67                }
68            }
69            DbOp::DeleteAll => {
70                self.need_clear = true;
71                self.ops.clear();
72            }
73        }
74    }
75    pub fn into_ops(self) -> DbOps {
76        let mut ops = DbOps::default();
77        for (k, v) in self.ops {
78            if let Some(v) = v {
79                ops.insert.insert(k, v);
80            } else {
81                ops.delete.push(k);
82            }
83        }
84        ops.clear = self.need_clear;
85        ops
86    }
87}
88
89#[async_trait]
90pub trait Kvdb {
91    async fn scan_keys(&self, filter: &Filter) -> Vec<Key>;
92    async fn get(&self, key: Key) -> Option<Value> {
93        let keys = Vec::from([key]);
94        self.get_many(keys).await.into_values().next()
95    }
96    async fn get_many(&self, keys: Vec<Key>) -> HashMap<Key, Value>;
97    async fn set(&self, key: Key, value: Value) {
98        let data = HashMap::from([(key, value)]);
99        self.set_many(data).await
100    }
101    async fn set_many(&self, data: HashMap<Key, Value>);
102    async fn delete(&self, key: Key) {
103        let keys = Vec::from([key]);
104        self.delete_many(keys).await
105    }
106    async fn delete_many(&self, keys: Vec<Key>);
107    async fn delete_all(&self);
108}
109
110#[test]
111fn empty(){
112    let op_merger = DbOpMerger::default();
113    assert!(op_merger.is_empty());
114}