//! Whole transaction reservation in logical journal slots, before any I/O. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Error { Capacity, RecordCount, Full } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Reservation { pub start: u16, pub slots: u16, pub records: u16 } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Space { capacity: u16, used: u16 } impl Space { pub fn new(capacity: u16, used: u16) -> Result { if capacity < 5 || used > capacity { return Err(Error::Capacity); } Ok(Self {capacity, used}) } pub const fn used(&self) -> u16 { self.used } pub const fn remaining(&self) -> u16 { self.capacity - self.used } pub fn reserve(&mut self, records: u16) -> Result { if !(1..=3).contains(&records) { return Err(Error::RecordCount); } let needed = records + 2; // Header and commit each require a slot. if needed > self.capacity - self.used { return Err(Error::Full); } let reservation = Reservation {start: self.used, slots: needed, records}; self.used += needed; Ok(reservation) } }