hawdb-storage 0.5.0

An embedded Rust graph database for local data-plane workloads
Documentation
// Copyright 2026 Nowledge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! WAL-tail repair protocol models shared by embedded storage facades.

use serde::{Deserialize, Serialize};

pub const WAL_DOCTOR_REPAIR_PROTOCOL: &str = "hawdb-wal-doctor-repair-v1";

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct WalDoctorOptions {
    pub max_wal_bytes: Option<u64>,
    pub max_record_bytes: Option<usize>,
    pub max_batch_operations: Option<usize>,
}

impl Default for WalDoctorOptions {
    fn default() -> Self {
        Self {
            max_wal_bytes: Some(crate::config::DEFAULT_MAX_WAL_REPLAY_BYTES),
            max_record_bytes: Some(crate::config::DEFAULT_MAX_WAL_RECORD_BYTES),
            max_batch_operations: Some(crate::config::DEFAULT_MAX_WAL_BATCH_OPERATIONS),
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum WalTailRepairReason {
    IncompleteFinalRecord,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WalTailRepairPlan {
    pub protocol: String,
    pub plan_id: String,
    pub wal_generation: u64,
    pub wal_replay_start_lsn: u64,
    pub next_lsn_after_repair: u64,
    /// Identity of the authoritative legacy manifest or exact branch head.
    /// A disposable branch runtime manifest never authorizes WAL repair.
    pub manifest_len: u64,
    pub manifest_crc32c: u64,
    pub manifest_sha256: String,
    pub original_wal_len: u64,
    pub original_wal_crc32c: u64,
    pub original_wal_sha256: String,
    pub retained_wal_len: u64,
    pub retained_wal_crc32c: u64,
    pub retained_wal_sha256: String,
    pub discarded_wal_tail_bytes: u64,
    pub reason: WalTailRepairReason,
    pub data_loss_possible: bool,
}

impl WalTailRepairPlan {
    pub fn acknowledge_potential_data_loss(&self) -> WalRepairAcknowledgement {
        WalRepairAcknowledgement {
            protocol: WAL_DOCTOR_REPAIR_PROTOCOL.to_string(),
            plan_id: self.plan_id.clone(),
            accepts_potential_data_loss: true,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WalRepairAcknowledgement {
    protocol: String,
    plan_id: String,
    accepts_potential_data_loss: bool,
}

impl WalRepairAcknowledgement {
    #[doc(hidden)]
    pub fn with_parts(
        protocol: String,
        plan_id: String,
        accepts_potential_data_loss: bool,
    ) -> Self {
        Self {
            protocol,
            plan_id,
            accepts_potential_data_loss,
        }
    }

    #[doc(hidden)]
    pub fn accepts(&self, plan: &WalTailRepairPlan) -> bool {
        self.protocol == WAL_DOCTOR_REPAIR_PROTOCOL
            && self.plan_id == plan.plan_id
            && self.accepts_potential_data_loss
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WalTailRepairReport {
    pub protocol: String,
    pub plan_id: String,
    pub wal_generation: u64,
    pub retained_wal_len: u64,
    pub discarded_wal_tail_bytes: u64,
    pub next_lsn_after_repair: u64,
    pub quarantine_file: String,
    pub repair_record_file: String,
    pub resumed_interrupted_repair: bool,
}