pub struct Store { /* private fields */ }Implementations§
Source§impl Store
impl Store
Sourcepub fn open_snapshot(dir: &Path, cfg: Config) -> Result<Store>
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.
Sourcepub fn pool_ref(&self) -> &BufferPool
pub fn pool_ref(&self) -> &BufferPool
The pool, for probes and tests (2n).
Sourcepub fn create_limited(
dir: &Path,
cfg: Config,
limits: ResourceLimits,
) -> Result<Store>
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.
pub fn resource_limits(&self) -> Option<ResourceLimits>
pub fn create(dir: &Path, cfg: Config) -> Result<Store>
pub fn open(dir: &Path, cfg: Config) -> Result<Store>
pub fn io_mode(&self) -> IoMode
pub fn put(&mut self, k: &[u8], v: &[u8]) -> Result<()>
Sourcepub fn put_empty_batch(&mut self, keys: &[Vec<u8>]) -> Result<()>
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.
pub fn delete(&mut self, k: &[u8]) -> Result<bool>
Sourcepub fn delete_prefix(&mut self, prefix: &[u8]) -> Result<u64>
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.
pub fn get(&self, k: &[u8]) -> Result<Option<Vec<u8>>>
pub fn scan(&self, from: &[u8]) -> Result<RangeIter<'_>>
Sourcepub fn scan_reverse(&self, to: &[u8]) -> Result<ReverseRangeIter<'_>>
pub fn scan_reverse(&self, to: &[u8]) -> Result<ReverseRangeIter<'_>>
Descending scan of keys strictly below to.
Sourcepub fn commit(&mut self) -> Result<()>
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.
Sourcepub fn commit_with_checkpoint(
&mut self,
wal_bytes: u64,
page_bytes: u64,
) -> Result<bool>
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.
Sourcepub fn dir(&self) -> &Path
pub fn dir(&self) -> &Path
The exact primitive SyncMode::Full issues on this platform, so a
measurement can name it instead of implying it.
Sourcepub fn published_root(&self) -> u32
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.
Sourcepub fn main_tree_id(&self) -> u16
pub fn main_tree_id(&self) -> u16
The main tree’s identity, so a verifier can prove every page belongs to it.
pub fn sync_full_primitive(&self) -> &'static str
Sourcepub fn pool_stats(&self) -> PoolStats
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.
Sourcepub fn tag_hints(&self) -> &TagHints
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.
pub fn sweep_steps(&self) -> u64
Sourcepub fn set_sync(&mut self, s: SyncMode)
pub fn set_sync(&mut self, s: SyncMode)
Runtime durability change (SQL SET WAL_SYNC): applies to every subsequent commit/checkpoint barrier.
Sourcepub fn sync_mode(&self) -> SyncMode
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.
Sourcepub fn generation(&self) -> u64
pub fn generation(&self) -> u64
The published generation this handle currently serves.
pub fn checkpoint(&mut self) -> Result<()>
Sourcepub fn bulk_load<I>(&mut self, items: I) -> Result<()>
pub fn bulk_load<I>(&mut self, items: I) -> Result<()>
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.
Sourcepub fn graft_range<I>(&mut self, items: I) -> Result<()>
pub fn graft_range<I>(&mut self, items: I) -> Result<()>
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.
Sourcepub fn graft_sorted_range<I>(
&mut self,
sorted: I,
expected_rows: u64,
min: Vec<u8>,
max: Vec<u8>,
scratch_dir: &Path,
) -> Result<()>
pub fn graft_sorted_range<I>( &mut self, sorted: I, expected_rows: u64, min: Vec<u8>, max: Vec<u8>, scratch_dir: &Path, ) -> Result<()>
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.
Sourcepub fn graft_sorted_range_deferred<I>(
&mut self,
sorted: I,
expected_rows: u64,
min: Vec<u8>,
max: Vec<u8>,
scratch_dir: &Path,
) -> Result<()>
pub fn graft_sorted_range_deferred<I>( &mut self, sorted: I, expected_rows: u64, min: Vec<u8>, max: Vec<u8>, scratch_dir: &Path, ) -> Result<()>
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.
Sourcepub fn prepare_graft_candidate<I>(
&mut self,
sorted: I,
expected_rows: u64,
min: Vec<u8>,
max: Vec<u8>,
scratch_dir: &Path,
) -> Result<PreparedGraft>
pub fn prepare_graft_candidate<I>( &mut self, sorted: I, expected_rows: u64, min: Vec<u8>, max: Vec<u8>, scratch_dir: &Path, ) -> Result<PreparedGraft>
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.
Sourcepub fn publish_existing_candidate(
&mut self,
prepared: &PreparedGraft,
) -> Result<()>
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.