opendal/services/dashmap/
backend.rs1use dashmap::DashMap;
19use std::fmt::Debug;
20use std::fmt::Formatter;
21
22use crate::raw::adapters::typed_kv;
23use crate::raw::Access;
24use crate::services::DashmapConfig;
25use crate::*;
26
27impl Configurator for DashmapConfig {
28 type Builder = DashmapBuilder;
29 fn into_builder(self) -> Self::Builder {
30 DashmapBuilder { config: self }
31 }
32}
33
34#[doc = include_str!("docs.md")]
36#[derive(Default)]
37pub struct DashmapBuilder {
38 config: DashmapConfig,
39}
40
41impl DashmapBuilder {
42 pub fn root(mut self, path: &str) -> Self {
44 self.config.root = if path.is_empty() {
45 None
46 } else {
47 Some(path.to_string())
48 };
49
50 self
51 }
52}
53
54impl Builder for DashmapBuilder {
55 const SCHEME: Scheme = Scheme::Dashmap;
56 type Config = DashmapConfig;
57
58 fn build(self) -> Result<impl Access> {
59 let mut backend = DashmapBackend::new(Adapter {
60 inner: DashMap::default(),
61 });
62 if let Some(v) = self.config.root {
63 backend = backend.with_root(&v);
64 }
65
66 Ok(backend)
67 }
68}
69
70pub type DashmapBackend = typed_kv::Backend<Adapter>;
72
73#[derive(Clone)]
74pub struct Adapter {
75 inner: DashMap<String, typed_kv::Value>,
76}
77
78impl Debug for Adapter {
79 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
80 f.debug_struct("DashmapAdapter")
81 .field("size", &self.inner.len())
82 .finish_non_exhaustive()
83 }
84}
85
86impl typed_kv::Adapter for Adapter {
87 fn info(&self) -> typed_kv::Info {
88 typed_kv::Info::new(
89 Scheme::Dashmap,
90 "dashmap",
91 typed_kv::Capability {
92 get: true,
93 set: true,
94 scan: true,
95 delete: true,
96 shared: false,
97 },
98 )
99 }
100
101 async fn get(&self, path: &str) -> Result<Option<typed_kv::Value>> {
102 self.blocking_get(path)
103 }
104
105 fn blocking_get(&self, path: &str) -> Result<Option<typed_kv::Value>> {
106 match self.inner.get(path) {
107 None => Ok(None),
108 Some(bs) => Ok(Some(bs.value().to_owned())),
109 }
110 }
111
112 async fn set(&self, path: &str, value: typed_kv::Value) -> Result<()> {
113 self.blocking_set(path, value)
114 }
115
116 fn blocking_set(&self, path: &str, value: typed_kv::Value) -> Result<()> {
117 self.inner.insert(path.to_string(), value);
118
119 Ok(())
120 }
121
122 async fn delete(&self, path: &str) -> Result<()> {
123 self.blocking_delete(path)
124 }
125
126 fn blocking_delete(&self, path: &str) -> Result<()> {
127 self.inner.remove(path);
128
129 Ok(())
130 }
131
132 async fn scan(&self, path: &str) -> Result<Vec<String>> {
133 self.blocking_scan(path)
134 }
135
136 fn blocking_scan(&self, path: &str) -> Result<Vec<String>> {
137 let keys = self.inner.iter().map(|kv| kv.key().to_string());
138 if path.is_empty() {
139 Ok(keys.collect())
140 } else {
141 Ok(keys.filter(|k| k.starts_with(path)).collect())
142 }
143 }
144}