use std::ptr;
use super::*;
pub struct Reservation<'a> {
pub iobufs: &'a IoBufs,
pub idx: usize,
pub data: Vec<u8>,
pub destination: &'a mut [u8],
pub flushed: bool,
pub reservation_offset: LogID,
}
impl<'a> Drop for Reservation<'a> {
fn drop(&mut self) {
let should_flush = !self.data.is_empty() && !self.flushed;
if should_flush {
self.flush(false);
}
}
}
impl<'a> Reservation<'a> {
pub fn abort(mut self) -> LogID {
self.flush(false)
}
pub fn complete(mut self) -> LogID {
self.flush(true)
}
pub fn log_id(&self) -> LogID {
self.reservation_offset
}
fn flush(&mut self, valid: bool) -> LogID {
if self.flushed {
panic!("flushing already-flushed reservation!");
}
self.flushed = true;
if valid {
self.destination.copy_from_slice(&*self.data);
} else {
unsafe {
ptr::write_bytes(self.destination.as_ptr() as *mut u8, 0, self.data.len());
}
}
self.iobufs.exit_reservation(self.idx);
self.log_id()
}
}