bark/persist/adaptor/
memory.rs1use std::collections::{BTreeMap, HashMap};
8
9use crate::persist::adaptor::{Query, QueryRange, Record, StorageAdaptor, StorageAdaptorWrapper};
10
11#[derive(Debug, Default)]
38pub struct MemoryStorageAdaptor {
39 partitions: HashMap<u8, BTreeMap<Vec<u8>, Record>>,
41}
42
43impl MemoryStorageAdaptor {
44 pub fn new() -> Self {
46 Self::default()
47 }
48
49 pub fn partitions(&self) -> &HashMap<u8, BTreeMap<Vec<u8>, Record>> {
50 &self.partitions
51 }
52}
53
54impl StorageAdaptorWrapper<MemoryStorageAdaptor> {
55 pub fn new_memory() -> Self {
56 Self::new(MemoryStorageAdaptor::new())
57 }
58}
59
60#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
61#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
62impl StorageAdaptor for MemoryStorageAdaptor {
63 async fn put(&mut self, record: Record) -> anyhow::Result<()> {
64 let partition = self.partitions.entry(record.partition).or_default();
65 partition.insert(record.pk.clone(), record);
66 Ok(())
67 }
68
69 async fn get(&self, partition: u8, pk: &[u8]) -> anyhow::Result<Option<Record>> {
70 if let Some(partition) = self.partitions.get(&partition) {
71 if let Some(record) = partition.get(pk) {
72 return Ok(Some(record.clone()));
73 }
74 }
75 Ok(None)
76 }
77
78 async fn delete(&mut self, partition: u8, pk: &[u8]) -> anyhow::Result<Option<Record>> {
79 if let Some(partition) = self.partitions.get_mut(&partition) {
80 return Ok(partition.remove(pk))
81 }
82
83 Ok(None)
84 }
85
86 async fn query_sorted<R: QueryRange>(&self, query: Query<R>) -> anyhow::Result<Vec<Record>> {
87 let Some(partition) = self.partitions.get(&query.partition) else {
88 return Ok(Vec::new());
89 };
90
91 let mut results: Vec<_> = partition
92 .values()
93 .filter(|r| {
94 let Some(sort_key) = &r.sort_key else {
96 return false;
97 };
98
99 query.range.contains(sort_key)
100 })
101 .cloned()
102 .collect();
103
104 results.sort_by(|a, b| {
106 match (&a.sort_key, &b.sort_key) {
107 (Some(ka), Some(kb)) => ka.cmp(kb),
108 _ => unreachable!("all records should have sort keys after filtering"),
109 }
110 });
111
112 if let Some(limit) = query.limit {
114 results.truncate(limit);
115 }
116
117 Ok(results)
118 }
119
120 async fn get_all(&self, partition: u8) -> anyhow::Result<Vec<Record>> {
121 let Some(partition_map) = self.partitions.get(&partition) else {
122 return Ok(Vec::new());
123 };
124
125 Ok(partition_map.values().cloned().collect())
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use crate::persist::adaptor::test_suite;
133
134 #[tokio::test]
136 async fn memory_adaptor_full_test_suite() {
137 let mut storage = MemoryStorageAdaptor::new();
138 test_suite::run_all(&mut storage).await;
139 }
140}