mindb 0.1.2

Lightweight embedded key–value store with write-ahead log and zstd compression.
Documentation
//! Storage subsystem primitives for MindB.
//! This module exposes the shared traits and error types used by the
//! segment, manifest, and compaction submodules.
#![allow(dead_code)]
#![allow(unused_imports)]

pub mod compaction;
pub mod manifest;
pub mod segment;

use std::path::Path;

use manifest::{CompactionMetadata, SegmentTier};

/// Convenient result alias for the storage subsystem.
pub type Result<T> = std::result::Result<T, StorageError>;

/// Common error enumeration returned by storage components.
#[derive(Debug, thiserror::Error)]
pub enum StorageError {
    /// Wrapper for lower level IO errors.
    #[error("io error: {0}")]
    Io(#[from] std::io::Error),

    /// Raised when a data page checksum does not match the expected value.
    #[error("checksum mismatch for page {page} in segment {segment}")]
    ChecksumMismatch { segment: String, page: usize },

    /// Returned when a segment does not satisfy the configured minimum size.
    #[error("segment too small: {0} bytes")]
    SegmentTooSmall(u64),

    /// Returned when a segment exceeds the configured maximum size.
    #[error("segment too large: {0} bytes (expected at most 256 MiB)")]
    SegmentTooLarge(u64),

    /// Raised on errors while serialising or deserialising metadata.
    #[error("manifest serialization error: {0}")]
    ManifestSerde(#[from] serde_json::Error),

    /// Returned when an unsupported or invalid storage format is encountered.
    #[error("invalid storage format: {0}")]
    InvalidFormat(String),

    /// Raised when a compression backend fails.
    #[error("compression error: {0}")]
    Compression(String),
}

/// Representation of an immutable segment on disk.
pub trait Segment: Send + Sync {
    /// Returns immutable metadata for the segment.
    fn metadata(&self) -> &segment::SegmentMetadata;

    /// Opens a new reader for the underlying segment file.
    fn open_reader(&self) -> Result<segment::SegmentReader>;
}

/// High-level API for the durable segment manifest.
pub trait Manifest: Send + Sync {
    /// Registers a new segment in the manifest at the provided tier.
    fn register_segment(
        &mut self,
        tier: SegmentTier,
        metadata: segment::SegmentMetadata,
    ) -> Result<()>;

    /// Marks a set of segments as superseded by a compaction output segment.
    fn record_compaction(
        &mut self,
        output_tier: SegmentTier,
        output: segment::SegmentMetadata,
        retired: Vec<String>,
        metadata: CompactionMetadata,
    ) -> Result<()>;

    /// Persists the manifest state to disk.
    fn persist(&self) -> Result<()>;
}

/// Helper used by tests to determine whether a path points at a persisted manifest.
pub fn manifest_exists(path: &Path) -> bool {
    path.exists()
}

/// Validates that the provided length conforms to the segment size contract.
pub fn validate_segment_length(length: u64) -> Result<()> {
    if length == 0 {
        return Err(StorageError::SegmentTooSmall(length));
    }

    const MAX: u64 = 256 * 1024 * 1024;

    if length > MAX {
        return Err(StorageError::SegmentTooLarge(length));
    }

    Ok(())
}

/// Describes the compression mode used by a segment and the concrete helpers
/// that operate on them.
pub use segment::{CompressionCodec, FileSegment, SegmentMetadata, SegmentReader, SegmentWriter};

/// Concrete manifest implementation backed by a JSON file.
pub use manifest::FileManifest;

/// Background compactor implementation.
pub use compaction::{CompactionJob, Compactor};