Skip to main content

Store

Struct Store 

Source
pub struct Store { /* private fields */ }

Implementations§

Source§

impl Store

Source

pub fn open_snapshot(dir: &Path, cfg: Config) -> Result<Store>

2f: open a SNAPSHOT READER on dir. Serves the newest PUBLISHED generation (the last checkpoint’s roots) and nothing later: the WAL tail is deliberately not replayed – replay writes, and this store cannot write. Correct beside a live writer with zero coordination: published pages are immutable (the writer shadows instead of editing, and page numbers are never reused), so everything reachable from a published root stays byte-identical for as long as this reader lives. Sacrifice (Law 4): staleness up to one checkpoint cadence.

Source

pub fn pool_ref(&self) -> &BufferPool

The pool, for probes and tests (2n).

Source

pub fn create_limited( dir: &Path, cfg: Config, limits: ResourceLimits, ) -> Result<Store>

Create a new constrained entry store. Commit publishes durable metadata; external-sort/graft and in-place repair require a separate workspace. Existing directories are refused, so policy cannot be applied halfway.

Source

pub fn resource_limits(&self) -> Option<ResourceLimits>

Source

pub fn create(dir: &Path, cfg: Config) -> Result<Store>

Source

pub fn open(dir: &Path, cfg: Config) -> Result<Store>

Source

pub fn io_mode(&self) -> IoMode

Source

pub fn put(&mut self, k: &[u8], v: &[u8]) -> Result<()>

Source

pub fn put_empty_batch(&mut self, keys: &[Vec<u8>]) -> Result<()>

Write up to 64 empty-valued index rows under one WAL frame and one B-tree handle. Key order is preserved exactly. This is not bulk-load: it appends to the existing shared tree and participates in the caller’s ordinary commit/recovery boundary.

Source

pub fn delete(&mut self, k: &[u8]) -> Result<bool>

Source

pub fn delete_prefix(&mut self, prefix: &[u8]) -> Result<u64>

Delete every key starting with prefix (2h A4). One WAL record, idempotent on replay; leaves wholly inside the range are cleared in ONE page write instead of per-slot removals – the fold’s head erase was 8M row deletes (~20 minutes at 1M docs) and is now ~one write per leaf. Returns the number of keys removed.

Source

pub fn get(&self, k: &[u8]) -> Result<Option<Vec<u8>>>

Source

pub fn scan(&self, from: &[u8]) -> Result<RangeIter<'_>>

Source

pub fn scan_reverse(&self, to: &[u8]) -> Result<ReverseRangeIter<'_>>

Descending scan of keys strictly below to.

Source

pub fn commit(&mut self) -> Result<()>

SyncMode is a promise about what reached the medium, so the three modes must issue three different things. An earlier draft had Full and Normal both call one sync() – which made the label decorative, and a decorative durability label is worse than none, because every benchmark carrying it becomes unattributable. It is worse than that on macOS specifically: std::fs::File::sync_data (what the single sync() used) issues fcntl(F_FULLFSYNC) there, so Normal would have silently been Full’s ~65x-costlier barrier on this machine while meaning something cheaper on Linux – the same code looking wildly different speeds for reasons the label never states.

Nothing in the committed suite failed if this collapsed back into one call for both arms – barriers exists so something does.

Source

pub fn commit_with_checkpoint( &mut self, wal_bytes: u64, page_bytes: u64, ) -> Result<bool>

Commit with an explicit byte-based publication policy. Limits are triggers checked at the transaction boundary, NOT disk quotas. Both WAL bytes and allocated/shadow pages matter: logical WAL records are much smaller than the pages scattered updates cause us to copy.

On the checkpoint branch, the data + metadata barriers establish the commit’s durability; a redundant WAL barrier is avoided. Checkpoint errors remain errors and preserve the WAL for reopening. This opt-in API does not change ordinary commit() or snapshot staleness defaults.

Source

pub fn dir(&self) -> &Path

The exact primitive SyncMode::Full issues on this platform, so a measurement can name it instead of implying it.

Source

pub fn published_root(&self) -> u32

The published root of the main tree. For structural verification of a live database — see verify::verify_published_tree.

Source

pub fn main_tree_id(&self) -> u16

The main tree’s identity, so a verifier can prove every page belongs to it.

Source

pub fn sync_full_primitive(&self) -> &'static str

Source

pub fn pool_stats(&self) -> PoolStats

The pool’s own counters, including how many sync_data/sync_full barriers it has actually issued. Real observability API, not test instrumentation – PoolStats and BufferPool::stats are already public and ungated – so this needs no #[cfg(test)] and the test that reads it can live in kernel/tests/durability.rs like any other public-API test.

Source

pub fn tag_hints(&self) -> &TagHints

The per-keyspace append hints, for diagnostics and for the oracle that runs one workload with them and once without.

Source

pub fn io_stats(&self) -> Option<&IoStats>

Data-file counters only; the WAL keeps its own.

Source

pub fn sweep_steps(&self) -> u64

Source

pub fn set_sync(&mut self, s: SyncMode)

Runtime durability change (SQL SET WAL_SYNC): applies to every subsequent commit/checkpoint barrier.

Source

pub fn sync_mode(&self) -> SyncMode

The level in force right now. A caller that raises durability for one operation has to be able to put back what it found – without this it could only guess, and guessing wrong silently re-levels every later commit.

Source

pub fn generation(&self) -> u64

The published generation this handle currently serves.

Source

pub fn checkpoint(&mut self) -> Result<()>

Source

pub fn bulk_load<I>(&mut self, items: I) -> Result<()>
where I: Iterator<Item = (Vec<u8>, Vec<u8>)>,

Build the tree from scratch by external sort and pack.

The new tree replaces the old one, but the old one’s PAGES are not reclaimed – page reclamation is deferred in Phase 1, so calling this on a non-empty store leaves the previous tree’s pages allocated and unreachable. Intended for loading into a fresh store; on a populated one the file grows by the size of both trees.

Unlike put/delete, this writes pages straight into the pool and never through the WAL – logging every bulk-loaded record before packing it would reintroduce the per-record write this task exists to remove. That means there is nothing in the log for recovery to replay, so this makes itself durable before returning rather than leaving that to a caller who may reasonably assume bulk_load behaves like any other write the engine accepted: pack, then checkpoint(). Without this, bulk_load followed only by commit() followed by a crash loses everything – the superblock still names the OLD root, and the log holds a commit record describing nothing – while the caller was told Ok twice. checkpoint() also rotates the log, so this discards prior log state; correct for a whole-tree replacement, not something an incremental write may do.

SACRIFICE (Law 4): publication adds one sequential read traversal of the packed tree. It retains only 16 verification pages and tree-height state; ordinary queries and writes do not use this path.

Source

pub fn graft_range<I>(&mut self, items: I) -> Result<()>
where I: Iterator<Item = (Vec<u8>, Vec<u8>)>,

Sort and pack an empty key interval, independently reopen and verify it, then splice it into the shared tree through a copy-on-write parent path. Packed pages bypass the per-record WAL because they are unreachable until the checkpoint publishes the new root.

The sort arena is fixed at 64 MiB. Inputs larger than that spill checksummed runs, so RAM is independent of corpus size; the named cost is scratch space approximately twice the index size plus one readback verification pass. Packed leaves are 90% full, leaving room for the first later live write before ordinary split policy takes over.

Source

pub fn graft_sorted_range<I>( &mut self, sorted: I, expected_rows: u64, min: Vec<u8>, max: Vec<u8>, scratch_dir: &Path, ) -> Result<()>
where I: Iterator<Item = Result<(Vec<u8>, Vec<u8>, bool)>>,

Publish a caller’s already-sorted, checksummed run stream. This is the lower half of [graft_range]: late-index builders that already paid for an external sort use it directly instead of materialising or sorting the same keys a second time.

expected_rows, min, and max are trusted only for the preflight overlap probe. pack_range recomputes all three and this method refuses a mismatch before publication.

Source

pub fn graft_sorted_range_deferred<I>( &mut self, sorted: I, expected_rows: u64, min: Vec<u8>, max: Vec<u8>, scratch_dir: &Path, ) -> Result<()>
where I: Iterator<Item = Result<(Vec<u8>, Vec<u8>, bool)>>,

Install an independently verified packed range in this writer’s unpublished root. The caller must finish its other namespace changes and issue one checkpoint; until then snapshot readers continue to use the previous generation. This is the transaction form of graft_sorted_range.

Source

pub fn prepare_graft_candidate<I>( &mut self, sorted: I, expected_rows: u64, min: Vec<u8>, max: Vec<u8>, scratch_dir: &Path, ) -> Result<PreparedGraft>
where I: Iterator<Item = Result<(Vec<u8>, Vec<u8>, bool)>>,

Pack and independently verify a candidate without publishing it. The returned descriptor is self-checksummable and sufficient for a later process to publish the already-written pages without sorting or packing again. The standing root is unchanged on every return path.

Source

pub fn publish_existing_candidate( &mut self, prepared: &PreparedGraft, ) -> Result<()>

Verify and publish an already-packed candidate discovered on reopen. Calling it after the candidate’s checkpoint but before scratch cleanup is idempotent: the published generation and exact inserted interval are checked, then no second root flip occurs.

Auto Trait Implementations§

§

impl !Freeze for Store

§

impl !RefUnwindSafe for Store

§

impl !Sync for Store

§

impl !UnwindSafe for Store

§

impl Send for Store

§

impl Unpin for Store

§

impl UnsafeUnpin for Store

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.