use crate::checkpoint::writer::CheckpointMeta;
use serde::{Deserialize, Serialize};
pub const MANIFEST_MAGIC: u32 = 0x4145_4442;
pub const MANIFEST_FORMAT_VERSION: u16 = 2;
pub const MIN_SUPPORTED_FORMAT_VERSION: u16 = 2;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SegmentMeta {
pub filename: String,
pub segment_seq: u64,
#[serde(default)]
pub sha256_hex: String,
#[serde(default)]
pub size_bytes: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct Manifest {
#[serde(default)]
pub magic: u32,
#[serde(default)]
pub format_version: u16,
#[serde(default)]
pub feature_flags: u64,
pub durable_seq: u64,
pub visible_seq: u64,
pub active_segment_seq: u64,
pub checkpoints: Vec<CheckpointMeta>,
pub segments: Vec<SegmentMeta>,
}
impl Manifest {
pub fn stamp_current_header(&mut self) {
self.magic = MANIFEST_MAGIC;
self.format_version = MANIFEST_FORMAT_VERSION;
}
pub fn validate_header(&self) -> Result<(), crate::error::AedbError> {
if self.magic == 0 {
return Err(crate::error::AedbError::Unavailable {
message: format!(
"legacy database predates on-disk format version {MIN_SUPPORTED_FORMAT_VERSION} \
and must be recreated"
),
});
}
if self.magic != MANIFEST_MAGIC {
return Err(crate::error::AedbError::IntegrityError {
message: format!(
"manifest magic mismatch: expected {MANIFEST_MAGIC:#010x}, found {:#010x}",
self.magic
),
});
}
if self.format_version < MIN_SUPPORTED_FORMAT_VERSION {
return Err(crate::error::AedbError::Unavailable {
message: format!(
"database on-disk format version {} is older than the minimum supported {} \
and must be recreated",
self.format_version, MIN_SUPPORTED_FORMAT_VERSION
),
});
}
if self.format_version > MANIFEST_FORMAT_VERSION {
return Err(crate::error::AedbError::Unavailable {
message: format!(
"manifest format version {} is newer than supported {}",
self.format_version, MANIFEST_FORMAT_VERSION
),
});
}
Ok(())
}
}