Skip to main content

powdb_storage/
mvcc.rs

1/// Pointer into the undo log.
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub struct UndoPtr(pub usize);
4
5/// A single undo log entry: the old version of a row before an update.
6#[derive(Debug, Clone)]
7pub struct UndoEntry {
8    pub tx_id: u64,
9    pub data: Vec<u8>,
10    pub prev: Option<UndoPtr>, // previous version (undo chain)
11}
12
13/// Append-only undo log. Entries are never modified, only appended.
14/// Old entries are reclaimed by advancing the purge watermark.
15pub struct UndoLog {
16    entries: Vec<UndoEntry>,
17}
18
19impl Default for UndoLog {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl UndoLog {
26    pub fn new() -> Self {
27        UndoLog {
28            entries: Vec::new(),
29        }
30    }
31
32    pub fn push(&mut self, tx_id: u64, data: &[u8]) -> UndoPtr {
33        self.push_with_prev(tx_id, data, None)
34    }
35
36    pub fn push_with_prev(&mut self, tx_id: u64, data: &[u8], prev: Option<UndoPtr>) -> UndoPtr {
37        let ptr = UndoPtr(self.entries.len());
38        self.entries.push(UndoEntry {
39            tx_id,
40            data: data.to_vec(),
41            prev,
42        });
43        ptr
44    }
45
46    pub fn get(&self, ptr: UndoPtr) -> Option<&UndoEntry> {
47        self.entries.get(ptr.0)
48    }
49
50    pub fn len(&self) -> usize {
51        self.entries.len()
52    }
53
54    pub fn is_empty(&self) -> bool {
55        self.entries.is_empty()
56    }
57}