Skip to main content

WorkspaceLease

Struct WorkspaceLease 

Source
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>§

Source

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.

Source

pub fn reembed_with_batch( &self, now: u64, batch_size: usize, ) -> Result<ReembedReport, HostError>

As Database::reembed, with an explicit provider batch bound.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn revise( &self, target: FactId, input: RememberInput<'_>, ) -> Result<RememberOutcome, HostError>

Revises target (same auto-embedding rule as remember).

Source

pub fn forget(&self, now: u64, id: FactId) -> Result<bool, HostError>

Tombstones a fact.

Upserts a typed edge.

Closes a typed edge. Returns false when the edge is already absent.

Source

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

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

Source

pub fn tags_of(&self, id: FactId) -> Vec<String>

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.

Source

pub fn list_tags(&self, query: TagQuery<'_>) -> Result<TagPage, HostError>

One bounded, cursor-stable page of current tags.

Source

pub fn remove_tag( &self, now: u64, tag: &str, ) -> Result<RemoveTagReport, HostError>

Removes a tag from every current fact by creating successor revisions.

Source

pub fn stats(&self) -> Stats

Engine size counters.

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, which streams.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn maintain_with_options( &self, now: u64, options: MaintenanceOptions, ) -> Result<MaintainReport, HostError>

Runs a maintenance pass with explicit policy.

Source

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).

Source

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.

Source

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

As Database::scrub_with_budget.

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 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.

Trait Implementations§

Source§

impl Deref for WorkspaceLease<'_>

Source§

type Target = Database

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl Drop for WorkspaceLease<'_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for WorkspaceLease<'a>

§

impl<'a> !UnwindSafe for WorkspaceLease<'a>

§

impl<'a> Freeze for WorkspaceLease<'a>

§

impl<'a> Send for WorkspaceLease<'a>

§

impl<'a> Sync for WorkspaceLease<'a>

§

impl<'a> Unpin for WorkspaceLease<'a>

§

impl<'a> UnsafeUnpin for WorkspaceLease<'a>

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> ErasedDestructor for T
where T: 'static,

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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
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.