1extern crate alloc;
2use crate::drivers::device::BlockDevice;
3use alloc::collections::BTreeMap;
4use alloc::sync::Arc;
5use alloc::vec::Vec;
6use spin::RwLock;
7
8pub struct BlockCache {
9 device: Arc<dyn BlockDevice>,
10 cache: RwLock<BTreeMap<usize, Vec<u8>>>,
11}
12
13impl BlockCache {
14 pub fn new(device: Arc<dyn BlockDevice>) -> Self {
15 Self {
16 device,
17 cache: RwLock::new(BTreeMap::new()),
18 }
19 }
20
21 pub fn read_block(&self, block_id: usize) -> Option<Vec<u8>> {
22 {
23 let cache = self.cache.read();
24 if let Some(data) = cache.get(&block_id) {
25 return Some(data.clone());
26 }
27 }
28
29 let block_size = self.device.block_size();
30 let mut buf = alloc::vec![0; block_size];
31
32 if self.device.read_blocks(block_id, 1, &mut buf).is_ok() {
33 let mut cache = self.cache.write();
34 cache.insert(block_id, buf.clone());
35 Some(buf)
36 } else {
37 None
38 }
39 }
40
41 pub fn write_block(&self, block_id: usize, data: &[u8]) -> bool {
42 if self.device.write_blocks(block_id, 1, data).is_ok() {
43 let mut cache = self.cache.write();
44 cache.insert(block_id, data.to_vec());
45 true
46 } else {
47 false
48 }
49 }
50
51 pub fn sync(&self) {}
52}