Line data Source code
1 : use std::collections::HashMap;
2 :
3 : const BLOCK_SIZE: usize = 8192;
4 :
5 : /// A simple in-memory implementation of a block storage. Can be used to implement external
6 : /// storage in tests.
7 : pub struct BlockStorage {
8 : blocks: HashMap<u64, [u8; BLOCK_SIZE]>,
9 : }
10 :
11 : impl Default for BlockStorage {
12 0 : fn default() -> Self {
13 0 : Self::new()
14 0 : }
15 : }
16 :
17 : impl BlockStorage {
18 10613 : pub fn new() -> Self {
19 10613 : BlockStorage {
20 10613 : blocks: HashMap::new(),
21 10613 : }
22 10613 : }
23 :
24 1766 : pub fn read(&self, pos: u64, buf: &mut [u8]) {
25 1766 : let mut buf_offset = 0;
26 1766 : let mut storage_pos = pos;
27 4327 : while buf_offset < buf.len() {
28 2561 : let block_id = storage_pos / BLOCK_SIZE as u64;
29 2561 : let block = self.blocks.get(&block_id).unwrap_or(&[0; BLOCK_SIZE]);
30 2561 : let block_offset = storage_pos % BLOCK_SIZE as u64;
31 2561 : let block_len = BLOCK_SIZE as u64 - block_offset;
32 2561 : let buf_len = buf.len() - buf_offset;
33 2561 : let copy_len = std::cmp::min(block_len as usize, buf_len);
34 2561 : buf[buf_offset..buf_offset + copy_len]
35 2561 : .copy_from_slice(&block[block_offset as usize..block_offset as usize + copy_len]);
36 2561 : buf_offset += copy_len;
37 2561 : storage_pos += copy_len as u64;
38 2561 : }
39 1766 : }
40 :
41 12286 : pub fn write(&mut self, pos: u64, buf: &[u8]) {
42 12286 : let mut buf_offset = 0;
43 12286 : let mut storage_pos = pos;
44 24800 : while buf_offset < buf.len() {
45 12514 : let block_id = storage_pos / BLOCK_SIZE as u64;
46 12514 : let block = self.blocks.entry(block_id).or_insert([0; BLOCK_SIZE]);
47 12514 : let block_offset = storage_pos % BLOCK_SIZE as u64;
48 12514 : let block_len = BLOCK_SIZE as u64 - block_offset;
49 12514 : let buf_len = buf.len() - buf_offset;
50 12514 : let copy_len = std::cmp::min(block_len as usize, buf_len);
51 12514 : block[block_offset as usize..block_offset as usize + copy_len]
52 12514 : .copy_from_slice(&buf[buf_offset..buf_offset + copy_len]);
53 12514 : buf_offset += copy_len;
54 12514 : storage_pos += copy_len as u64
55 : }
56 12286 : }
57 : }
|