use crate::{
config::TxStrategy,
error::PERes,
id::{RecRef, SegmentId},
journal::JournalEntry,
util::io::{InfallibleWrite, InfallibleWriteVarInt, ReadVarInt},
};
#[cfg(feature = "experimental_inspect")]
use std::fmt::Debug;
use std::{io::Read, str};
#[derive(Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct Start {}
impl JournalEntry for Start {
fn get_type(&self) -> u8 {
1
}
fn write(&self, _: &mut dyn InfallibleWrite) -> PERes<()> {
Ok(())
}
fn read_new(_: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
Ok(Start::default())
}
}
#[derive(Clone, Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct NewSegmentPage {
pub segment: SegmentId,
pub page: u64,
pub previous: u64,
}
impl NewSegmentPage {
pub fn new(segment: SegmentId, page: u64, previous: u64) -> NewSegmentPage {
NewSegmentPage {
segment,
page,
previous,
}
}
}
impl JournalEntry for NewSegmentPage {
fn get_type(&self) -> u8 {
13
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
self.segment.write_varint(buffer);
buffer.write_varint_u64(self.page);
buffer.write_varint_u64(self.previous);
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let segment = SegmentId::read_varint(buffer)?;
let page = buffer.read_varint_u64()?;
let previous = buffer.read_varint_u64()?;
Ok(NewSegmentPage {
segment,
page,
previous,
})
}
}
#[derive(Clone, Default)]
pub struct InsertRecord {
pub segment: SegmentId,
pub recref: RecRef,
pub record_page: u64,
}
#[cfg(feature = "experimental_inspect")]
impl Debug for InsertRecord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("InsertRecord")
.field("segment", &self.segment)
.field("recref", &format!("{}", &self.recref))
.field("record_page", &self.record_page)
.finish()
}
}
impl InsertRecord {
pub fn new(segment: SegmentId, rec_ref: &RecRef, record: u64) -> InsertRecord {
InsertRecord {
segment,
recref: *rec_ref,
record_page: record,
}
}
}
impl JournalEntry for InsertRecord {
fn get_type(&self) -> u8 {
2
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
self.segment.write_varint(buffer);
buffer.write_varint_u64(self.recref.page);
buffer.write_varint_u32(self.recref.pos);
buffer.write_varint_u64(self.record_page);
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let segment = SegmentId::read_varint(buffer)?;
let recref_page = buffer.read_varint_u64()?;
let recref_pos = buffer.read_varint_u32()?;
let record_page = buffer.read_varint_u64()?;
Ok(InsertRecord {
segment,
recref: RecRef::new(recref_page, recref_pos),
record_page,
})
}
}
#[derive(Clone, Default)]
pub struct UpdateRecord {
pub segment: SegmentId,
pub recref: RecRef,
pub record_page: u64,
pub version: u16,
}
#[cfg(feature = "experimental_inspect")]
impl Debug for UpdateRecord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("UpdateRecord")
.field("segment", &self.segment)
.field("recref", &format!("{}", self.recref))
.field("record_page", &self.record_page)
.finish()
}
}
impl UpdateRecord {
pub fn new(segment: SegmentId, rec_ref: &RecRef, record: u64, version: u16) -> UpdateRecord {
UpdateRecord {
segment,
recref: *rec_ref,
record_page: record,
version,
}
}
}
impl JournalEntry for UpdateRecord {
fn get_type(&self) -> u8 {
5
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
self.segment.write_varint(buffer);
buffer.write_varint_u64(self.recref.page);
buffer.write_varint_u32(self.recref.pos);
buffer.write_varint_u64(self.record_page);
buffer.write_varint_u16(self.version);
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let segment = SegmentId::read_varint(buffer)?;
let recref_page = buffer.read_varint_u64()?;
let recref_pos = buffer.read_varint_u32()?;
let record_page = buffer.read_varint_u64()?;
let version = buffer.read_varint_u16()?;
Ok(UpdateRecord {
segment,
recref: RecRef::new(recref_page, recref_pos),
record_page,
version,
})
}
}
#[derive(Clone, Default)]
pub struct ReadRecord {
pub segment: SegmentId,
pub recref: RecRef,
pub version: u16,
}
#[cfg(feature = "experimental_inspect")]
impl Debug for ReadRecord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ReadRecord")
.field("segment", &self.segment)
.field("recref", &format!("{}", self.recref))
.field("version", &self.version)
.finish()
}
}
impl ReadRecord {
pub fn new(segment: SegmentId, recref: &RecRef, version: u16) -> ReadRecord {
ReadRecord {
segment,
recref: *recref,
version,
}
}
}
impl JournalEntry for ReadRecord {
fn get_type(&self) -> u8 {
10
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
self.segment.write_varint(buffer);
buffer.write_varint_u64(self.recref.page);
buffer.write_varint_u32(self.recref.pos);
buffer.write_varint_u16(self.version);
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let segment = SegmentId::read_varint(buffer)?;
let recref_page = buffer.read_varint_u64()?;
let recref_pos = buffer.read_varint_u32()?;
let version = buffer.read_varint_u16()?;
Ok(ReadRecord {
segment,
recref: RecRef::new(recref_page, recref_pos),
version,
})
}
}
#[derive(Clone, Default)]
pub struct DeleteRecord {
pub segment: SegmentId,
pub recref: RecRef,
pub version: u16,
}
#[cfg(feature = "experimental_inspect")]
impl Debug for DeleteRecord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DeleteRecord")
.field("segment", &self.segment)
.field("recref", &format!("{}", self.recref))
.field("version", &self.version)
.finish()
}
}
impl DeleteRecord {
pub fn new(segment: SegmentId, rec_ref: &RecRef, version: u16) -> DeleteRecord {
DeleteRecord {
segment,
recref: *rec_ref,
version,
}
}
}
impl JournalEntry for DeleteRecord {
fn get_type(&self) -> u8 {
6
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
self.segment.write_varint(buffer);
buffer.write_varint_u64(self.recref.page);
buffer.write_varint_u32(self.recref.pos);
buffer.write_varint_u16(self.version);
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let segment = SegmentId::read_varint(buffer)?;
let recref_page = buffer.read_varint_u64()?;
let recref_pos = buffer.read_varint_u32()?;
let version = buffer.read_varint_u16()?;
Ok(DeleteRecord {
segment,
recref: RecRef::new(recref_page, recref_pos),
version,
})
}
}
#[derive(Clone, Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct CreateSegment {
pub name: String,
pub segment_id: SegmentId,
pub first_page: u64,
}
impl CreateSegment {
pub fn new(name: &str, segment_id: SegmentId, first_page: u64) -> CreateSegment {
CreateSegment {
name: name.into(),
segment_id,
first_page,
}
}
}
impl JournalEntry for CreateSegment {
fn get_type(&self) -> u8 {
8
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
self.segment_id.write_varint(buffer);
buffer.write_varint_u64(self.first_page);
buffer.write_varint_u16(self.name.len() as u16);
buffer.write_all(self.name.as_bytes());
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let segment_id = SegmentId::read_varint(buffer)?;
let first_page = buffer.read_varint_u64()?;
let string_size = buffer.read_varint_u16()?;
let mut slice: Vec<u8> = vec![0; string_size as usize];
buffer.read_exact(&mut slice[0..string_size as usize])?;
let name = str::from_utf8(&slice[0..string_size as usize])?.into();
Ok(CreateSegment {
name,
segment_id,
first_page,
})
}
}
#[derive(Clone, Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct DropSegment {
pub name: String,
pub segment_id: SegmentId,
}
impl DropSegment {
pub fn new(name: &str, segment_id: SegmentId) -> DropSegment {
DropSegment {
name: name.into(),
segment_id,
}
}
}
impl JournalEntry for DropSegment {
fn get_type(&self) -> u8 {
9
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
self.segment_id.write_varint(buffer);
buffer.write_varint_u16(self.name.len() as u16);
buffer.write_all(self.name.as_bytes());
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let segment_id = SegmentId::read_varint(buffer)?;
let string_size = buffer.read_varint_u16()?;
let mut slice: Vec<u8> = vec![0; string_size as usize];
buffer.read_exact(&mut slice[0..string_size as usize])?;
let name = str::from_utf8(&slice[0..string_size as usize])?.into();
Ok(DropSegment { name, segment_id })
}
}
#[derive(Clone, PartialEq, Debug, PartialOrd, Ord, Eq, Default)]
pub struct FreedPage {
pub page: u64,
}
impl FreedPage {
pub fn new(page: u64) -> FreedPage {
FreedPage { page }
}
}
impl JournalEntry for FreedPage {
fn get_type(&self) -> u8 {
12
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
buffer.write_varint_u64(self.page);
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let page = buffer.read_varint_u64()?;
Ok(FreedPage { page })
}
}
#[derive(Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct PrepareCommit {}
impl PrepareCommit {
pub fn new() -> PrepareCommit {
PrepareCommit {}
}
}
impl JournalEntry for PrepareCommit {
fn get_type(&self) -> u8 {
3
}
fn write(&self, _: &mut dyn InfallibleWrite) -> PERes<()> {
Ok(())
}
fn read_new(_: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
Ok(PrepareCommit {})
}
}
#[derive(Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct Commit {}
impl Commit {
pub fn new() -> Commit {
Commit {}
}
}
impl JournalEntry for Commit {
fn get_type(&self) -> u8 {
4
}
fn write(&self, _: &mut dyn InfallibleWrite) -> PERes<()> {
Ok(())
}
fn read_new(_: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
Ok(Commit {})
}
}
#[derive(Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct Cleanup {}
impl Cleanup {
pub fn new() -> Cleanup {
Cleanup {}
}
}
impl JournalEntry for Cleanup {
fn get_type(&self) -> u8 {
14
}
fn write(&self, _: &mut dyn InfallibleWrite) -> PERes<()> {
Ok(())
}
fn read_new(_: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
Ok(Cleanup {})
}
}
#[derive(Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct Rollback {}
impl Rollback {
pub fn new() -> Rollback {
Rollback {}
}
}
impl JournalEntry for Rollback {
fn get_type(&self) -> u8 {
7
}
fn write(&self, _: &mut dyn InfallibleWrite) -> PERes<()> {
Ok(())
}
fn read_new(_: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
Ok(Rollback {})
}
}
#[derive(Default)]
#[cfg_attr(feature = "experimental_inspect", derive(Debug))]
pub struct Metadata {
pub strategy: TxStrategy,
pub meta_id: Vec<u8>,
}
impl Metadata {
pub fn new(strategy: &TxStrategy, meta_id: Vec<u8>) -> Metadata {
Metadata {
strategy: strategy.clone(),
meta_id,
}
}
}
impl JournalEntry for Metadata {
fn get_type(&self) -> u8 {
11
}
fn write(&self, write: &mut dyn InfallibleWrite) -> PERes<()> {
write.write_varint_u8(self.strategy.value());
let len = self.meta_id.len();
write.write_varint_u16(len as u16);
write.write_all(&self.meta_id);
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let strategy = TxStrategy::from_value(buffer.read_varint_u8()?);
let len = buffer.read_varint_u16()?;
let mut slice: Vec<u8> = vec![0; len as usize];
buffer.read_exact(&mut slice[0..len as usize])?;
let meta_id = slice;
Ok(Metadata { strategy, meta_id })
}
}
#[derive(Clone, PartialEq, PartialOrd, Ord, Eq, Default)]
pub struct RollbackPage {
pub segment: SegmentId,
pub recref: RecRef,
pub record_page: u64,
}
#[cfg(feature = "experimental_inspect")]
impl Debug for RollbackPage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RollbackPage")
.field("segment", &self.segment)
.field("recref", &format!("{}", self.recref))
.field("record_page", &self.record_page)
.finish()
}
}
impl RollbackPage {
pub fn new(segment: SegmentId, rec_ref: &RecRef, record: u64) -> Self {
Self {
segment,
recref: *rec_ref,
record_page: record,
}
}
}
impl JournalEntry for RollbackPage {
fn get_type(&self) -> u8 {
15
}
fn write(&self, buffer: &mut dyn InfallibleWrite) -> PERes<()> {
self.segment.write_varint(buffer);
buffer.write_varint_u64(self.recref.page);
buffer.write_varint_u32(self.recref.pos);
buffer.write_varint_u64(self.record_page);
Ok(())
}
fn read_new(buffer: &mut dyn Read) -> PERes<Self>
where
Self: Sized,
{
let segment = SegmentId::read_varint(buffer)?;
let recref_page = buffer.read_varint_u64()?;
let recref_pos = buffer.read_varint_u32()?;
let record_page = buffer.read_varint_u64()?;
Ok(RollbackPage {
segment,
recref: RecRef::new(recref_page, recref_pos),
record_page,
})
}
}