pub struct MerkleIndex { /* private fields */ }Expand description
In-memory file-hash index loaded from / saved to a JSON cache file.
Concurrency model: the orchestrator holds an Arc<MerkleIndex> and
records new entries as chunks arrive from rayon-parallel sources.
Paths are sharded across [MERKLE_SHARDS] mutex-protected maps so
concurrent updates rarely contend.
Implementations§
Source§impl MerkleIndex
impl MerkleIndex
Sourcepub fn load_with_spec_report(
path: &Path,
expected_spec_hash: &[u8; 32],
) -> MerkleLoadReport
pub fn load_with_spec_report( path: &Path, expected_spec_hash: &[u8; 32], ) -> MerkleLoadReport
Load the spec-gated index and report whether the cache was trusted.
Source§impl MerkleIndex
impl MerkleIndex
Sourcepub fn empty() -> Self
pub fn empty() -> Self
Construct a fresh, empty MerkleIndex with no cached entries and
the default entry cap ([MERKLE_DEFAULT_MAX_ENTRIES]).
Sourcepub fn new() -> Self
pub fn new() -> Self
Construct a fresh, empty MerkleIndex.
Sourcepub fn record_chunk_at_offset_and_check_unchanged(
&self,
path: PathBuf,
chunk_offset: u64,
mtime_ns: u64,
ctime_ns: u64,
size: u64,
content: &[u8],
) -> bool
pub fn record_chunk_at_offset_and_check_unchanged( &self, path: PathBuf, chunk_offset: u64, mtime_ns: u64, ctime_ns: u64, size: u64, content: &[u8], ) -> bool
Record one observed chunk at its absolute byte offset and return true
when the same (path, chunk_offset) previously held the same content.
Sourcepub fn record_chunk_path_at_offset_and_check_unchanged(
&self,
path: &Path,
chunk_offset: u64,
mtime_ns: u64,
ctime_ns: u64,
size: u64,
content: &[u8],
) -> bool
pub fn record_chunk_path_at_offset_and_check_unchanged( &self, path: &Path, chunk_offset: u64, mtime_ns: u64, ctime_ns: u64, size: u64, content: &[u8], ) -> bool
Borrowing variant for hot dispatch loops that already hold a path
string/reference. The index still owns the persisted key, but callers do
not need to allocate a temporary PathBuf before handing it off.
Sourcepub fn metadata_unchanged(
&self,
path: &Path,
mtime_ns: u64,
ctime_ns: u64,
size: u64,
) -> bool
pub fn metadata_unchanged( &self, path: &Path, mtime_ns: u64, ctime_ns: u64, size: u64, ) -> bool
Returns true when the stored entry for path carries exactly this
(mtime_ns, ctime_ns, size) identity. This is the fast-path skip -
it avoids reading the file at all, which is the dominant cost on
cold-cache disk. A false return means “either we’ve never seen this
path, or metadata differs - caller must read + hash to decide.”
The change time is part of the identity: a userspace tamper can restore
mtime and size over modified content, but the kernel-owned inode change
time moves on any write and cannot be set back. An entry recorded
without one (0: legacy v4 cache row, or a platform whose stat has no
change time) is never trusted here.
Sourcepub fn forget(&self, path: &Path)
pub fn forget(&self, path: &Path)
Remove path from the index so the next scan treats it as new and
re-reads + re-scans it.
This is how incremental mode keeps its core safety guarantee: a file that produced ANY finding is never cached, so a secret in an otherwise unchanged file still surfaces on every later run instead of being silently skipped (the failure this module’s own header warns about). Clean files - the 99% - stay cached, so the 10-100x speedup is unaffected, and because we store the ABSENCE of an entry rather than the finding, no secret value ever touches the on-disk index.
Trait Implementations§
Source§impl Debug for MerkleIndex
impl Debug for MerkleIndex
Auto Trait Implementations§
impl !Freeze for MerkleIndex
impl !RefUnwindSafe for MerkleIndex
impl Send for MerkleIndex
impl Sync for MerkleIndex
impl Unpin for MerkleIndex
impl UnsafeUnpin for MerkleIndex
impl UnwindSafe for MerkleIndex
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more