1use std::collections::HashMap;
7
8use anyhow::{Result, bail};
9
10use crate::traits::{SlotArena, SwapStore};
11
12pub struct VecSlotArena {
16 buf: Vec<u8>,
17 slot_bytes: usize,
18 n: usize,
19}
20
21impl VecSlotArena {
22 pub fn new(slot_bytes: usize, num_slots: usize) -> Self {
23 Self {
24 buf: vec![0u8; slot_bytes * num_slots],
25 slot_bytes,
26 n: num_slots,
27 }
28 }
29}
30
31impl SlotArena for VecSlotArena {
32 fn slot_bytes(&self) -> usize {
33 self.slot_bytes
34 }
35 fn num_slots(&self) -> usize {
36 self.n
37 }
38 fn read_slot(&self, slot: usize, out: &mut [u8]) -> Result<()> {
39 if slot >= self.n || out.len() != self.slot_bytes {
40 bail!("VecSlotArena::read_slot({slot}) out of range / size mismatch");
41 }
42 let o = slot * self.slot_bytes;
43 out.copy_from_slice(&self.buf[o..o + self.slot_bytes]);
44 Ok(())
45 }
46 fn write_slot(&mut self, slot: usize, bytes: &[u8]) -> Result<()> {
47 if slot >= self.n || bytes.len() != self.slot_bytes {
48 bail!("VecSlotArena::write_slot({slot}) out of range / size mismatch");
49 }
50 let o = slot * self.slot_bytes;
51 self.buf[o..o + self.slot_bytes].copy_from_slice(bytes);
52 Ok(())
53 }
54}
55
56pub struct MemSwapStore {
60 recs: HashMap<usize, Vec<u8>>,
61 record_bytes: usize,
62}
63
64impl MemSwapStore {
65 pub fn new(record_bytes: usize) -> Self {
66 Self {
67 recs: HashMap::new(),
68 record_bytes,
69 }
70 }
71}
72
73impl SwapStore for MemSwapStore {
74 fn record_bytes(&self) -> usize {
75 self.record_bytes
76 }
77 fn write_record(&mut self, disk_slot: usize, bytes: &[u8]) -> Result<()> {
78 if bytes.len() != self.record_bytes {
79 bail!(
80 "MemSwapStore::write_record: {} bytes, expected {}",
81 bytes.len(),
82 self.record_bytes
83 );
84 }
85 self.recs.insert(disk_slot, bytes.to_vec());
86 Ok(())
87 }
88 fn read_record(&self, disk_slot: usize, out: &mut [u8]) -> Result<()> {
89 match self.recs.get(&disk_slot) {
90 Some(v) => {
91 out.copy_from_slice(v);
92 Ok(())
93 }
94 None => bail!("MemSwapStore: no record {disk_slot}"),
95 }
96 }
97 fn discard_record(&mut self, disk_slot: usize) {
98 self.recs.remove(&disk_slot);
99 }
100}