Skip to main content

vfs/engine/mem/
block_store.rs

1use crate::engine::block::BlockStore;
2use crate::engine::error::{VfsError, VfsResult};
3use crate::engine::types::BlockKey;
4use async_trait::async_trait;
5use std::collections::BTreeMap;
6use std::sync::{Arc, Mutex};
7
8#[derive(Debug, Clone, Default)]
9pub struct MemoryBlockStore {
10    blocks: Arc<Mutex<BTreeMap<BlockKey, Vec<u8>>>>,
11}
12
13impl MemoryBlockStore {
14    pub fn new() -> Self {
15        Self::default()
16    }
17
18    pub fn len(&self) -> usize {
19        self.blocks.lock().expect("block mutex poisoned").len()
20    }
21
22    pub fn is_empty(&self) -> bool {
23        self.blocks.lock().expect("block mutex poisoned").is_empty()
24    }
25}
26
27#[async_trait]
28impl BlockStore for MemoryBlockStore {
29    async fn get(&self, key: &BlockKey) -> VfsResult<Vec<u8>> {
30        self.blocks
31            .lock()
32            .expect("block mutex poisoned")
33            .get(key)
34            .cloned()
35            .ok_or_else(|| VfsError::enoent(&key.0))
36    }
37
38    async fn get_range(&self, key: &BlockKey, off: u64, len: u64) -> VfsResult<Vec<u8>> {
39        let data = self.get(key).await?;
40        let start = usize::try_from(off)
41            .map_err(|_| VfsError::einval(format!("range offset is too large: {off}")))?;
42        let len = usize::try_from(len)
43            .map_err(|_| VfsError::einval(format!("range length is too large: {len}")))?;
44        if start >= data.len() {
45            return Ok(Vec::new());
46        }
47        let end = start.saturating_add(len).min(data.len());
48        Ok(data[start..end].to_vec())
49    }
50
51    async fn put(&self, key: &BlockKey, data: &[u8]) -> VfsResult<()> {
52        self.blocks
53            .lock()
54            .expect("block mutex poisoned")
55            .insert(key.clone(), data.to_vec());
56        Ok(())
57    }
58
59    async fn exists(&self, key: &BlockKey) -> VfsResult<bool> {
60        Ok(self
61            .blocks
62            .lock()
63            .expect("block mutex poisoned")
64            .contains_key(key))
65    }
66
67    async fn delete_many(&self, keys: &[BlockKey]) -> VfsResult<()> {
68        let mut blocks = self.blocks.lock().expect("block mutex poisoned");
69        for key in keys {
70            blocks.remove(key);
71        }
72        Ok(())
73    }
74
75    async fn copy(&self, src: &BlockKey, dst: &BlockKey) -> VfsResult<()> {
76        let data = self.get(src).await?;
77        self.put(dst, &data).await
78    }
79}