segments/memory/
segment.rs

1use std::fmt::Debug;
2
3/// Segment of a disk. Writes go through a buffer writers to
4/// reduce number of system calls. Reads are directly read from
5/// the file as seek on buffer reader will dump the buffer anyway
6/// Also multiple readers might be operating on a given segment
7/// which makes the cursor movement very dynamic
8#[derive(Debug)]
9pub struct Segment<T> {
10    base_offset: u64,
11    size: usize,
12    pub(crate) file: Vec<T>,
13}
14
15impl<T: Debug + Clone> Segment<T> {
16    pub fn new(base_offset: u64) -> Segment<T> {
17        let file = Vec::with_capacity(10000);
18
19        Segment {
20            base_offset,
21            file,
22            size: 0,
23        }
24    }
25
26    pub fn base_offset(&self) -> u64 {
27        self.base_offset
28    }
29
30    pub fn size(&self) -> usize {
31        self.size
32    }
33
34    pub fn len(&self) -> usize {
35        self.file.len()
36    }
37
38    /// Appends record to the file and return next offset
39    pub fn append(&mut self, record: T, len: usize) -> u64 {
40        self.file.push(record);
41        self.size += len;
42
43        // return current offset after incrementing next offset
44        self.base_offset + self.file.len() as u64
45    }
46
47    /// Reads at an absolute offset
48    pub fn read(&self, offset: u64) -> Option<T> {
49        if offset < self.base_offset {
50            return None;
51        }
52
53        let offset = offset - self.base_offset;
54        match self.file.get(offset as usize) {
55            Some(record) => Some(record.clone()),
56            None => None,
57        }
58    }
59
60    /// Reads multiple data from an offset to the end of segment
61    pub fn readv(&self, offset: u64, out: &mut Vec<T>) -> usize {
62        if offset < self.base_offset {
63            return 0;
64        }
65
66        // Protects file indexing below from overflow
67        if offset > self.base_offset + self.file.len() as u64 {
68            return 0;
69        }
70
71        let offset = offset - self.base_offset;
72        let slice = &self.file[offset as usize..];
73        out.extend_from_slice(slice);
74        slice.len()
75    }
76}