pub struct WorkspaceLease<'a> { /* private fields */ }Expand description
A database borrowed from a Workspace for one operation.
Unlike Workspace::get, this value participates in the pool’s ownership
accounting. While it lives, its entry cannot be evicted, swept as idle or
explicitly released. Dropping it first drops the temporary Database
clone and then marks the pooled entry inactive, so another caller can never
evict the pool owner while an unaccounted clone still holds the file lock.
Language bindings use a lease inside one verb and never store it in their public objects. A long-lived FFI reference therefore names a memory without becoming another owner of its open file.
Methods from Deref<Target = Database>§
Sourcepub fn reembed(&self, now: u64) -> Result<ReembedReport, HostError>
pub fn reembed(&self, now: u64) -> Result<ReembedReport, HostError>
Replaces the complete vector axis with the currently configured embedder, in bounded provider batches.
This operation is deliberately separate from Database::maintain:
neither Auto nor any other maintenance mode can invoke a model. The
source generation remains readable while the provider runs. Competing
writes fail immediately with HostError::ReembedBusy, and the new
generation becomes visible in one atomic publication step.
Sourcepub fn reembed_with_batch(
&self,
now: u64,
batch_size: usize,
) -> Result<ReembedReport, HostError>
pub fn reembed_with_batch( &self, now: u64, batch_size: usize, ) -> Result<ReembedReport, HostError>
As Database::reembed, with an explicit provider batch bound.
Sourcepub fn reembed_with(
&self,
now: u64,
target: Box<dyn Embedder>,
batch_size: usize,
) -> Result<ReembedReport, HostError>
pub fn reembed_with( &self, now: u64, target: Box<dyn Embedder>, batch_size: usize, ) -> Result<ReembedReport, HostError>
Replaces the vector axis with target, then installs that embedder on
this handle after a successful atomic publication.
batch_size bounds both the request body and the temporary vectors
held in RAM. A provider output is validated against Embedder::dim
for every fact; callers do not separately supply a database dimension.
Sourcepub fn remember(
&self,
input: RememberInput<'_>,
) -> Result<RememberOutcome, HostError>
pub fn remember( &self, input: RememberInput<'_>, ) -> Result<RememberOutcome, HostError>
Remembers a fact. Without an explicit vector and with an embedder configured, the text is embedded first — outside the lock.
Sourcepub fn remember_guarded(
&self,
input: RememberInput<'_>,
) -> Result<GuardedRememberOutcome, HostError>
pub fn remember_guarded( &self, input: RememberInput<'_>, ) -> Result<GuardedRememberOutcome, HostError>
Checks the ordinary remember similarity thresholds and stores only
when no live same-entity candidate crosses one. Automatic embedding runs
before the engine lock; no other write can slip between the check and
possible journaled mutation because both share one exclusive guard.
Sourcepub fn remember_many(
&self,
inputs: Vec<RememberInput<'_>>,
) -> Result<Vec<RememberOutcome>, HostError>
pub fn remember_many( &self, inputs: Vec<RememberInput<'_>>, ) -> Result<Vec<RememberOutcome>, HostError>
Remembers a batch of facts in one shot — the bulk-write path (CLI
import). Equivalent to remember on each input in
order, but far cheaper for a batch: the texts that need embedding are
embedded together in one embedder round-trip (outside the lock), and
all facts are written under one write-guard with one post-mutation
policy pass — instead of N HTTP calls and N critical sections.
Inputs that already carry a vector are not re-embedded. Chunking is
the caller’s job: this writes the whole slice it is given, so a caller
that needs bounded memory / a bounded HTTP body passes fixed-size batches
(CLI import streams the file in --batch-sized slices).
Fail-fast: the first engine error returns Err; the facts written
before it stay written (exactly as separate remembers — the journal
replay is idempotent, so a retried bulk load is safe). Returns one
RememberOutcome per input, in order.
Sourcepub fn recall(&self, q: RecallQuery<'_>) -> Result<RecallResult, HostError>
pub fn recall(&self, q: RecallQuery<'_>) -> Result<RecallResult, HostError>
Runs a recall. With a text, no vector and an embedder configured, the query text is embedded first — outside the lock.
Sourcepub fn revise(
&self,
target: FactId,
input: RememberInput<'_>,
) -> Result<RememberOutcome, HostError>
pub fn revise( &self, target: FactId, input: RememberInput<'_>, ) -> Result<RememberOutcome, HostError>
Revises target (same auto-embedding rule as remember).
Sourcepub fn unlink(&self, input: UnlinkInput<'_>) -> Result<bool, HostError>
pub fn unlink(&self, input: UnlinkInput<'_>) -> Result<bool, HostError>
Closes a typed edge. Returns false when the edge is already absent.
Sourcepub fn get(&self, id: FactId) -> Option<FactSnapshot>
pub fn get(&self, id: FactId) -> Option<FactSnapshot>
An owned copy of one fact, or None for unknown/tombstoned ids.
One fact’s tags, or an empty vector for an unknown or tombstoned id.
FactSnapshot carries text and metadata but not tags, so without this
the only way to read one fact’s tags is Database::export — a full
scan to answer a question about a single id.
One bounded, cursor-stable page of current tags.
Sourcepub fn remove_tag(
&self,
now: u64,
tag: &str,
) -> Result<RemoveTagReport, HostError>
pub fn remove_tag( &self, now: u64, tag: &str, ) -> Result<RemoveTagReport, HostError>
Removes a tag from every current fact by creating successor revisions.
Sourcepub fn export(&self) -> Vec<ExportedFact>
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, which streams.
Sourcepub fn export_each(&self, f: impl FnMut(ExportedFact))
pub fn export_each(&self, f: impl FnMut(ExportedFact))
Streams the currently-open facts, calling f once per fact under the
read guard — the whole dump is never materialized, so a huge database
exports without a RAM spike (CLI export writes each line straight out).
See ExportedFact.
Sourcepub fn export_edges_each(&self, f: impl FnMut(&str, &str, &str, FactId))
pub fn export_edges_each(&self, f: impl FnMut(&str, &str, &str, FactId))
Streams the currently-open edges, calling f with
(source, relation, destination, provenance fact) under the read guard.
The companion to export_each: facts alone are not
the memory, and a dump without edges silently drops one of the four
recall sources. Names are borrowed, so a writer that formats them
directly allocates nothing per edge.
provenance is the fact id as this database numbers it. Ids do not
survive a re-import, so a file format that wants to keep provenance has
to translate it — see the CLI’s export/import, which rewrite it as a
position within the same file.
Sourcepub fn export_page(&self, cursor: u32, limit: NonZeroUsize) -> ExportPage
pub fn export_page(&self, cursor: u32, limit: NonZeroUsize) -> ExportPage
Inspects at most limit fact ids starting at cursor and returns the
ones that are currently open. A sparse page may therefore contain fewer
facts, including zero, while still carrying a next_cursor.
This is the pull-based counterpart to export_each:
it releases the database read guard before returning, so a boundary
caller can process the page, apply backpressure, or write to the database
without a callback running under this lock. Mutations between page calls
are visible to later pages; use a stable read-only checkpoint when
snapshot-consistent paging is required.
Sourcepub fn maintain(&self, now: u64) -> Result<MaintainReport, HostError>
pub fn maintain(&self, now: u64) -> Result<MaintainReport, HostError>
Runs a maintenance pass now (cheap no-op, purge/compaction, text reindex, and/or bounded HNSW work — for the cost model).
Disk-first (milestone H): the compacted image is written by streaming
the two big pools (vectors, text) through temp files and then re-mapped,
so peak RAM tracks the record count (metadata + graph), not the image
size — a database larger than RAM can be maintained. It writes a fresh
snapshot and clears the journal (like a checkpoint). The optional
auto-maintain policy (maintain_every_forgets) still runs in RAM inline
— it is for databases that fit.
The report’s byte counts are the on-disk image size before and after.
Sourcepub fn maintain_with_options(
&self,
now: u64,
options: MaintenanceOptions,
) -> Result<MaintainReport, HostError>
pub fn maintain_with_options( &self, now: u64, options: MaintenanceOptions, ) -> Result<MaintainReport, HostError>
Runs a maintenance pass with explicit policy.
Sourcepub fn checkpoint(&self, now: u64) -> Result<(), HostError>
pub fn checkpoint(&self, now: u64) -> Result<(), HostError>
Writes a full snapshot and clears the journal now (re-mapping the
fresh file — see Database::resnapshot).
Sourcepub fn verify(&self) -> Result<(), HostError>
pub fn verify(&self) -> Result<(), HostError>
Runs the on-demand full content-integrity check. An open validates only
the metadata, so the
large byte pools stay non-resident on an mmap’d base; this sweeps them
(text UTF-8, vector self-consistency and the fact↔slot bijection) and
reports any latent corruption. Skipping it is safe — the accessors never
panic on bad bytes; verify only turns corruption into an explicit
error.
§Errors
HostError::Engine wrapping Error::Corrupt
for the first inconsistency found.
Sourcepub fn scrub(&self) -> Result<Scrub, HostError>
pub fn scrub(&self) -> Result<Scrub, HostError>
A resumable byte-level container scrub of the current published
generation, with the default slice budget. See
Database::scrub_with_budget.
§Errors
Sourcepub fn scrub_with_budget(&self, budget: usize) -> Result<Scrub, HostError>
pub fn scrub_with_budget(&self, budget: usize) -> Result<Scrub, HostError>
A resumable container scrub hashing at most budget bytes per
Iterator::next — the writer’s counterpart to
ReadOnlyDatabase::scrub_with_budget, and the same Scrub.
It exists because a scrub is an operation on the file, not on this handle’s view of it: it hashes the published container as it stands, and the journal belongs to the generation the writer has not published yet. A writer could always have reached one by opening a second, read-only handle on the same path — but that maps the whole image again, takes a second lock and reconciles the config, all to hash bytes this handle already knows the path of.
The returned Scrub is independent of this handle: it owns its map
and a shared lock on the generation it pins, so it outlives the
database, can be moved to its own thread, and keeps this generation
safe from the writer’s own GC until it is dropped.
§Errors
HostError::NeedsCheckpoint when nothing has been published yet;
HostError::Io if the generation cannot be opened or mapped;
HostError::Engine if its container will not parse.