quill-sql 0.2.1

An educational Rust relational database (RDBMS) inspired by CMU 15445
Documentation
use crate::error::QuillSQLResult;
use crate::recovery::control_file::ControlFileSnapshot;
use crate::recovery::wal::codec::{
    decode_checkpoint, CheckpointPayload, ResourceManagerId, WalFrame,
};
use crate::recovery::Lsn;

#[derive(Debug, Default, Clone)]
pub struct AnalysisResult {
    pub start_lsn: Lsn,
    pub has_frames: bool,
}

pub struct AnalysisPass {
    latest: Option<(Lsn, CheckpointPayload)>,
    snapshot: Option<ControlFileSnapshot>,
    has_frames: bool,
}

impl AnalysisPass {
    pub fn new(snapshot: Option<ControlFileSnapshot>) -> Self {
        Self {
            latest: None,
            snapshot,
            has_frames: false,
        }
    }

    pub fn observe(&mut self, frame: &WalFrame) {
        self.has_frames = true;
        if frame.rmid == ResourceManagerId::Checkpoint {
            if let Ok(payload) = decode_checkpoint(&frame.body) {
                self.latest = Some((frame.lsn, payload));
            }
        }
    }

    pub fn finalize(self) -> QuillSQLResult<AnalysisResult> {
        let start_lsn = if let Some((checkpoint_lsn, payload)) = &self.latest {
            self.snapshot
                .map(|snap| snap.checkpoint_redo_start)
                .filter(|redo| *redo >= payload.last_lsn && *redo <= *checkpoint_lsn)
                .unwrap_or_else(|| {
                    payload
                        .dpt
                        .iter()
                        .map(|(_, lsn)| *lsn)
                        .min()
                        .unwrap_or(payload.last_lsn)
                })
        } else {
            0
        };

        Ok(AnalysisResult {
            start_lsn,
            has_frames: self.has_frames,
        })
    }
}