Skip to main content

ReadOnlyDatabase

Struct ReadOnlyDatabase 

Source
pub struct ReadOnlyDatabase { /* private fields */ }
Expand description

A read-only database handle backed by a memory-mapped snapshot See the module docs. Send + Sync — share it across threads behind a reference or an Arc.

Implementations§

Source§

impl ReadOnlyDatabase

Source

pub fn recall(&self, q: RecallQuery<'_>) -> Result<RecallResult, HostError>

Runs a recall. Same semantics as Database::recall minus the embedder: a text-only query is not auto-embedded, so pass a vector for the vector source.

Source

pub fn get(&self, id: FactId) -> Option<FactSnapshot>

An owned copy of one fact, or None for unknown/tombstoned ids.

Source

pub fn stats(&self) -> Stats

Engine size counters.

Source

pub fn verify(&self) -> Result<(), HostError>

Runs the on-demand integrity check — the equivalent of SQLite’s integrity_check. A read-only open validates only the metadata (the mapped text and vector pools stay non-resident); this sweeps them and reports any latent corruption. Reads the whole image, so it residents the pools it checks.

§Errors

HostError::Engine for the first inconsistency found.

Source

pub fn scrub(&self) -> Result<Scrub, HostError>

A resumable byte-level container scrub of the snapshot file, with the default slice budget (— the ZFS-scrub model). See Scrub and ReadOnlyDatabase::scrub_with_budget.

§Errors

HostError::Locked/HostError::Io/HostError::Engine if the file cannot be locked, mapped, or structurally parsed for the scan.

Source

pub fn scrub_with_budget(&self, budget: usize) -> Result<Scrub, HostError>

A resumable container scrub hashing at most budget bytes per Iterator::next.

The returned Scrub owns its own map and its own shared advisory lock over the same file, so it holds a reader’s lock for its whole life (a writer is refused with HostError::Locked while any scrub or read-only handle lives) and can be moved to its own thread — the caller paces the scan (next, pause, resume, cancel) exactly like the core ScrubCursor. Dropping it releases the lock.

It is independent of self: the scrub keeps running after this handle is dropped. A non-empty journal is not an obstacle — the scrub checks the on-disk snapshot container as-is.

§Errors

As ReadOnlyDatabase::scrub.

Source

pub fn export(&self) -> Vec<ExportedFact>

Dumps the currently-open facts for a human-readable backup See ExportedFact. Collects the whole set; for a large database prefer export_each.

Source

pub fn export_each(&self, f: impl FnMut(ExportedFact))

Streams the currently-open facts, calling f once per fact under the map — the whole dump is never materialized (the zero-copy analog of Database::export_each).

Source

pub fn path(&self) -> &Path

The database base path.

Source

pub fn generation(&self) -> u64

The snapshot generation this handle is pinned to — the point in time it reads “as of”. Monotonic: a writer’s checkpoint publishes a strictly higher number. Compare it against a later call, or drive your own freshness policy around refresh with it.

Source

pub fn refresh(&mut self) -> Result<bool, HostError>

Advances this handle to the writer’s latest published generation, if there is a newer one. Returns true when it re-mapped onto a newer snapshot (subsequent reads now observe it), false when nothing changed.

This is the only way a read-only handle moves forward in time: an open handle is a point-in-time snapshot and never advances on its own (see the module docs). It exists for a reader watching another process’s writer; a single process that reads and writes uses one Database handle and sees its own writes instantly, with no refresh at all.

It is cheap to call speculatively — the freshness check is a read of the tiny fixed-size manifest (a handful of bytes), and the mmap re-map happens only when the writer has actually published a newer generation. In steady state (no new checkpoint) it does no mapping and returns false for the cost of that manifest read, so calling it before each read is a reasonable “always fresh” policy; batching (refresh every N reads, or on a timer) trades a bounded staleness for even fewer manifest reads. Re-mapping borrows the new generation’s pages lazily — no whole-file copy, no journal replay, no index rebuild — and drops the old map, so RAM does not grow.

The freshness policy is intentionally left to the caller: an autorefresh baked into every read would forfeit snapshot isolation for callers who need a stable view across a series of queries. Keep the reader stable by not calling this; advance it by calling it.

§Errors

HostError::Io if the newer generation cannot be mapped; HostError::Engine for a corrupt image. On any error the handle is left untouched on its current generation (the re-map is built before it replaces the live one).

Trait Implementations§

Source§

impl Debug for ReadOnlyDatabase

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Summary only — the contents are the user’s memory.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.