haematite 0.6.1

Content-addressed, branchable, actor-native storage engine
Documentation
//! Offline storage inventory & vacuum (STORAGE-VACUUM.md, pair-certified r15).
//!
//! v1 is OFFLINE-ONLY (§1): the vacuum runs with no live writer process,
//! holds the A4 data-dir writer lock itself for its entire run, and refuses
//! to start if the lock is held. It constructs NO `Database` — `Database::
//! open` spawns actors/schedulers the vacuum must not have (§6).
//!
//! Two deliverables, strictly ordered: [`vacuum_stats`] (report-only — zero
//! deletions, zero writes to the store) ships FIRST and is proven against
//! the operator's actual store before any sweep exists. The sweep, the
//! manifest write authority, and the four `haem manifest` operations are the
//! next unit.
//!
//! Report-only has exactly one named write exception (⟨r4, M5⟩): acquiring
//! the advisory lock on a valid legacy dir creates one empty `writer.lock`
//! anchor; the report names it when that happens.
//!
//! There is NO age-based or keep-N-recent deletion anywhere in this design
//! (§2, test-enforced): retention is exactly the union of resolvable pin
//! sources — WAL committed roots (M1), HBR1 anchors/heads (M2), and named
//! snapshot roots (M3).

mod consult;
mod error;
mod inventory;
pub mod manifest;
mod mark;
mod metadata;
mod report;
mod stats;

#[cfg(test)]
mod test_support;

#[cfg(test)]
#[path = "stats_tests.rs"]
mod stats_tests;

#[cfg(test)]
#[path = "refusal_tests.rs"]
mod refusal_tests;

#[cfg(test)]
#[path = "metadata_tests.rs"]
mod metadata_tests;

#[cfg(test)]
#[path = "codec_corpus_tests.rs"]
mod codec_corpus_tests;

#[cfg(test)]
#[path = "access_tests.rs"]
mod access_tests;

#[cfg(test)]
#[path = "guard_tests.rs"]
mod guard_tests;

use std::path::PathBuf;

pub use error::{MarkSourceId, VacuumError};
pub use report::{
    EntryKind, MalformedEntry, ManifestEntryReport, ManifestReport, MarkTallies, MetadataOrigin,
    MetadataReport, MetadataSourceKind, MetadataSourceReport, NodeTotals, ShardPresence,
    ShardReport, SweepBlocker, UninventoriedEntry, VacuumMode, VacuumReport,
};

/// Canonical in-dir refs-dir location the facade wiring uses (§3).
pub const CANONICAL_REFS_DIR: &str = "branches";
/// Canonical in-dir snapshot-registry location (§3).
pub const CANONICAL_SNAPSHOT_REGISTRY: &str = "snapshots.hsr";

/// Options for one vacuum run (§7). No config-file surface: there are no
/// silent defaults to invent, so options are explicit per call.
#[derive(Debug, Clone)]
pub struct VacuumOptions {
    pub data_dir: PathBuf,
    /// Extra refs-dir locations beyond the canonical in-dir one (§3), for
    /// deployments that placed metadata elsewhere.
    pub refs_dirs: Vec<PathBuf>,
    /// Extra snapshot-registry files beyond the canonical in-dir one (§3).
    pub snapshot_files: Vec<PathBuf>,
    /// ⟨r2, B1⟩ Sweep-only: the operator asserts that the canonical plus
    /// supplied paths are ALL metadata that exists for this data dir, AND
    /// (⟨r11⟩) that its metadata history was written entirely under the
    /// supported durability contract (Unix, local filesystem) with no
    /// unresolved post-mutation durability failures outstanding (⟨r12⟩).
    /// This is the operator's considered responsibility, stated in those
    /// words. Ignored by stats (reported, not consumed).
    pub attest_metadata_complete: bool,
}

impl VacuumOptions {
    /// Options naming only the data dir: canonical metadata locations,
    /// nothing supplied, no attestation.
    pub const fn new(data_dir: PathBuf) -> Self {
        Self {
            data_dir,
            refs_dirs: Vec::new(),
            snapshot_files: Vec::new(),
            attest_metadata_complete: false,
        }
    }
}

/// Report-only storage inventory (§7).
///
/// Full strict enumeration, verified reachability walk from every durable
/// pin source, and a report whose numbers reconcile as
/// `enumerated = marked + unmarked`, with debris and uninventoried entries
/// each accounted separately.
///
/// Zero deletions, zero writes to the store; the single named exception is
/// the advisory lock anchor on a legacy dir, reported when created.
pub fn vacuum_stats(options: &VacuumOptions) -> Result<VacuumReport, VacuumError> {
    stats::run(options)
}