Skip to main content

Database

Struct Database 

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

A database handle.

Database handles provide methods for inserting, retrieving, and deleting records. A database belongs to a single environment.

§Example

use noxu_db::{Environment, EnvironmentConfig, DatabaseConfig, DatabaseEntry};
use std::path::PathBuf;

let env_config = EnvironmentConfig::new(PathBuf::from("/tmp/mydb"))
    .allow_create(true);
let env = Environment::open(env_config).unwrap();

let db_config = DatabaseConfig::new().allow_create(true);
let db = env.open_database(None, "mydb", &db_config).unwrap();

let key = DatabaseEntry::from_bytes(b"key1");
let value = DatabaseEntry::from_bytes(b"value1");
db.put( &key, &value).unwrap();

db.close().unwrap();
env.close().unwrap();

Implementations§

Source§

impl Database

Source

pub fn get(&self, key: impl AsRef<[u8]>) -> Result<Option<Bytes>, NoxuError>

Retrieves a record by key, auto-committing the read.

Idiomatic Rust lookup: Some(value) if found, None if the key is absent, Err only on a real failure (review P0-3). Keys accept any impl AsRef<[u8]> (review P1-3) — b"k", &str, Vec<u8>, Bytes, etc., no DatabaseEntry wrapper required.

For an explicit transaction use Self::get_in; for zero-alloc buffer reuse or partial reads use Self::get_into.

§Errors

Returns an error if the database is closed or the environment failed.

Source

pub fn get_in( &self, txn: &Transaction, key: impl AsRef<[u8]>, ) -> Result<Option<Bytes>, NoxuError>

Retrieves a record by key within an explicit transaction (review P0-2: auto-commit vs transactional is a named choice, not a bare None).

§Errors

Returns an error if the database is closed, the environment failed, or a transactional handle is used against a non-transactional DB.

Source

pub fn get_into( &self, txn: Option<&Transaction>, key: impl AsRef<[u8]>, data: &mut DatabaseEntry, ) -> Result<bool, NoxuError>

Zero-alloc / partial-read escape hatch (review P0-3, P1-3).

Reads into a caller-owned DatabaseEntry so the buffer can be reused across calls, and honours data.is_partial() for partial reads (the offset/length machinery that DatabaseEntry exists for). Returns true if the record was found.

txn is Option here because this is the low-level escape hatch; the idiomatic named-choice surface is Self::get / Self::get_in.

§Errors

Returns an error if the database is closed or the environment failed.

Source

pub fn get_with_options( &self, txn: Option<&Transaction>, key: impl AsRef<[u8]>, opts: &ReadOptions, ) -> Result<Option<Bytes>, NoxuError>

Retrieves a record with per-operation read options (escape hatch; review P0-3 returns Result<Option<Bytes>>, P1-3 takes impl AsRef<[u8]>).

Mirrors Cursor.get() with ReadOptions applied:

  • LockMode::ReadUncommitted — dirty read, no lock acquired
  • LockMode::ReadCommitted — read-committed isolation (standard locking)
  • LockMode::Rmw — acquire write lock for read-modify-write
  • LockMode::Default — environment default isolation

CacheMode in ReadOptions is advisory (accepted but not yet honored): the per-operation hint does not reach the evictor and has no effect today. See crate::CacheMode for the tracking note.

§Arguments
  • txn - Optional transaction handle
  • key - The search key
  • opts - Per-operation read options (isolation, cache hints)
§Returns

Some(value) if found, None otherwise.

Source

pub fn put( &self, key: impl AsRef<[u8]>, data: impl AsRef<[u8]>, ) -> Result<(), NoxuError>

Inserts or updates a record, auto-committing the write (review P0-2: auto-commit is the unadorned put; the transactional form is the named Self::put_in). Keys and values accept any impl AsRef<[u8]> (review P1-3).

§Errors

Returns an error if the database is closed or read-only.

Source

pub fn put_in( &self, txn: &Transaction, key: impl AsRef<[u8]>, data: impl AsRef<[u8]>, ) -> Result<(), NoxuError>

Inserts or updates a record within an explicit transaction (review P0-2).

§Errors

Returns an error if the database is closed, read-only, or a transactional handle is used against a non-transactional DB.

Source

pub fn put_partial( &self, txn: Option<&Transaction>, key: impl AsRef<[u8]>, data: &DatabaseEntry, ) -> Result<(), NoxuError>

Partial-read/-write escape hatch (review P1-3: DatabaseEntry is retained only where the offset/length actually matter).

data must be configured with DatabaseEntry::set_partial; the existing record’s bytes outside [offset, offset+length) are preserved and only the specified range is replaced (JE LN.combinePuts()). The supplied data length must equal the configured partial length.

§Errors

Returns NoxuError::IllegalArgument if the data length does not match the partial length, or if the database is closed / read-only.

Source

pub fn put_with_options( &self, txn: Option<&Transaction>, key: impl AsRef<[u8]>, data: impl AsRef<[u8]>, opts: &WriteOptions, ) -> Result<(), NoxuError>

Inserts or updates a record with per-operation write options (escape hatch; review P1-3 takes impl AsRef<[u8]>).

Extends put() with WriteOptions support:

  • ttl — if > 0, sets a per-record TTL expiration (hours from now); the record will be treated as expired and invisible after the TTL elapses.
  • update_ttl — if true and the record already exists, refreshes its TTL.
  • cache_mode — advisory cache hint, accepted but not yet honored (no effect today; see crate::CacheMode).
§Arguments
  • txn - Optional transaction handle
  • key - The key to insert/update
  • data - The data to store
  • opts - Per-operation write options (TTL, cache hints)
Source

pub fn put_no_overwrite( &self, key: impl AsRef<[u8]>, data: impl AsRef<[u8]>, ) -> Result<bool, NoxuError>

Inserts a record, failing if the key already exists; auto-commits (review P0-2/P0-3/P1-3).

Returns Ok(true) if the record was inserted, Ok(false) if the key already existed (the prior OperationStatus::KeyExists collapses to the boolean per review P0-3).

§Errors

Returns an error if the database is closed or read-only.

Source

pub fn put_no_overwrite_in( &self, txn: &Transaction, key: impl AsRef<[u8]>, data: impl AsRef<[u8]>, ) -> Result<bool, NoxuError>

Inserts a record within an explicit transaction, failing if the key already exists (review P0-2). Ok(true) = inserted.

§Errors

Returns an error if the database is closed, read-only, or a transactional handle is used against a non-transactional DB.

Source

pub fn delete(&self, key: impl AsRef<[u8]>) -> Result<bool, NoxuError>

Deletes a record by key, auto-committing (review P0-2/P0-3/P1-3).

Returns Ok(true) if a record was deleted, Ok(false) if the key was absent (the prior OperationStatus::NotFound collapses to the boolean per review P0-3).

§Errors

Returns an error if the database is closed or read-only.

Source

pub fn delete_in( &self, txn: &Transaction, key: impl AsRef<[u8]>, ) -> Result<bool, NoxuError>

Deletes a record by key within an explicit transaction (review P0-2). Ok(true) = deleted.

§Errors

Returns an error if the database is closed, read-only, or a transactional handle is used against a non-transactional DB.

Source

pub fn open_cursor( &self, config: Option<&CursorConfig>, ) -> Result<Cursor<'static>, NoxuError>

Opens an auto-commit cursor for iterating over database records (review P0-1: returns Cursor<'_>; review P0-2: auto-commit is the unadorned form, the transactional form is Self::open_cursor_in).

In auto-commit mode each cursor write is its own transaction and is fsynced before returning.

§Arguments
  • config - Optional cursor configuration
§Errors

Returns an error if the database is closed.

Source

pub fn open_cursor_in<'txn>( &self, txn: &'txn Transaction, config: Option<&CursorConfig>, ) -> Result<Cursor<'txn>, NoxuError>

Opens a cursor bound to an explicit transaction (review P0-1/P0-2).

The cursor binds to the transaction’s Locker: every cursor get acquires shared locks tracked by the txn, every cursor put/delete acquires exclusive locks and is rolled back if the txn aborts.

The returned Cursor<'txn> borrows txn, so the borrow checker rejects any attempt to commit or drop the transaction while the cursor is still alive — the old “close the cursor before commit” prose invariant is now a compile error.

§Arguments
  • txn - the transaction the cursor participates in
  • config - Optional cursor configuration
§Errors

Returns an error if the database is closed or a transactional handle is used against a non-transactional database.

Source

pub fn iter<'txn>( &self, txn: Option<&'txn Transaction>, ) -> Result<DbIter<'txn>, NoxuError>

Returns a lazy forward iterator over all records in the database.

Records are fetched one at a time (the underlying cursor advances on each next() call). The full database is not eagerly materialised into memory.

Pass txn = Some(&txn) to iterate within an explicit transaction; pass None for an auto-commit (non-transactional) scan.

§Example
for result in db.iter(None)? {
    let (key, val) = result?;
    println!("{:?} => {:?}", key, val);
}
§Errors

Returns an error if the database is closed.

Source

pub fn range<'txn, K>( &self, txn: Option<&'txn Transaction>, range: impl RangeBounds<K>, ) -> Result<DbRange<'txn>, NoxuError>
where K: AsRef<[u8]>,

Returns a lazy iterator over the records whose keys fall within range.

The iterator is positioned at the first key that satisfies the lower bound (using SearchGte) and stops once the key exceeds the upper bound. All standard RangeBounds variants are supported: .., lo.., ..=hi, lo..hi, lo..=hi, etc.

Pass txn = Some(&txn) to iterate within an explicit transaction; pass None for a non-transactional scan.

§Example
let lo = b"key010";
let hi = b"key020";
for result in db.range(None, lo.as_ref()..=hi.as_ref())? {
    let (key, _val) = result?;
    assert!(key.as_slice() >= lo.as_slice());
}
§Errors

Returns an error if the database is closed.

Source

pub fn open_sequence<'db>( &'db self, key: &DatabaseEntry, config: SequenceConfig, ) -> Result<Sequence<'db>, NoxuError>

§Arguments
  • key - The database key under which the sequence record is stored.
  • config - Sequence configuration (use SequenceConfig::new() for defaults).
§Errors

Returns an error if the database is closed, the config is invalid, or allow_create is false and the sequence does not exist.

Source

pub fn close(&self) -> Result<(), NoxuError>

Closes the database handle.

§Errors

Returns an error if the database is already closed

Source

pub fn name(&self) -> &str

Returns the database name.

Source

pub fn config(&self) -> &DatabaseConfig

Returns the database configuration.

Source

pub fn sorted_duplicates(&self) -> bool

Returns whether this database was created with sorted duplicates.

Unlike config().sorted_duplicates — which reflects the DatabaseConfig the caller passed to open_database — this reads the property stored in the opened DatabaseImpl, so it is correct even when an existing database is reopened without restating its dup-sort flag (as noxu-admin dump does). Mirrors JE Database.getConfig().getSortedDuplicates() after DbInternal.setUseExistingConfig.

Source

pub fn count(&self) -> Result<u64, NoxuError>

Returns an approximate count of records in the database.

reads the per-database AtomicU64 entry counter, giving O(1) performance analogous to an O(1) counter.

The counter is incremented on every new insert and decremented on every delete (including transaction aborts that undo inserts).

§Errors

Returns an error if the database is closed

Source

pub fn scan_all_kv(&self) -> Result<Vec<(Vec<u8>, Vec<u8>)>, NoxuError>

Returns all records as (key_bytes, data_bytes) pairs in key order.

This is a helper for schema evolution: it uses the lower-level CursorImpl directly so each iteration yields raw Vec<u8> pairs without allocating a pair of DatabaseEntry values per record.

§Errors

Returns an error if the database is closed or a cursor operation fails.

Source

pub fn is_valid(&self) -> bool

Returns whether the database handle is valid.

Source

pub fn state(&self) -> DbState

Returns the current state of the database handle.

Source

pub fn sync(&self) -> Result<(), NoxuError>

Flushes all pending writes for this database to stable storage.

Implements Database.sync() — issues an fdatasync on the log file, ensuring that all writes made by non-transactional or deferred-sync operations are durable before returning.

§Returns

Ok(()) on success. Acts as a no-op for non-transactional / in-memory environments where no log manager is configured.

§Errors

Returns an error if the database is closed or the underlying log-manager flush fails.

Source

pub fn preload(&self, config: &PreloadConfig) -> Result<PreloadStats, NoxuError>

Preloads the database into cache by scanning the B-tree.

Walks the tree, touching each internal-node and BIN level so they are pulled into the in-memory cache. Useful for warming the cache before a workload begins.

§Limitations
  • The current implementation warms the BIN/IN structure only; PreloadConfig::load_lns therefore makes lns_loaded report the number of LN slots in the tree rather than the number of LNs actually fetched off disk. Full LN warming is tracked as a future-work item; the engine has no public single-shot LN fetch API today, so the only way to warm an LN is to position a cursor on its slot.
  • PreloadConfig::max_millis is honoured: the call returns early once the wall-clock budget is exceeded, with the partial results in the returned PreloadStats.
§Arguments
  • config - Controls limits on preload duration and memory
§Returns

Statistics about what was preloaded.

Source

pub fn stats( &self, config: Option<&StatsConfig>, ) -> Result<DatabaseStats, NoxuError>

Returns B-tree statistics for this database.

Implements Database.getStats(StatsConfig).

When config.fast is true, only the O(1) entry-count is returned and no tree traversal is performed. When fast is false (default), the full tree is walked to populate all node-count fields.

§Errors

Returns an error if the database is closed.

Source

pub fn verify(&self, config: &VerifyConfig) -> Result<VerifyResult, NoxuError>

Verifies the structural integrity of this database’s B-tree.

Walks the B-tree from root to BIN leaves and checks:

  • Each upper IN’s children are accessible (non-null child references).
  • Each BIN entry that is not known-deleted has a valid (non-NULL) LSN.
  • The BIN’s first key is >= the parent routing key (key-range containment).

Mirrors Database.verify(VerifyConfig) — calls BtreeVerifier on the underlying tree.

§Arguments
  • config - Verification options (which checks to run, max errors, etc.)
§Returns

A VerifyResult with any structural errors and the count of records verified.

§Errors

Returns an error if the database is closed.

Source

pub fn join<'db>( &'db self, cursors: Vec<SecondaryCursor<'db>>, config: Option<JoinConfig>, ) -> Result<JoinCursor<'db>, NoxuError>

Creates a join cursor that returns records matching all secondary-key constraints expressed by the pre-positioned cursors.

Mirrors Database.join(SecondaryCursor[], JoinConfig).

Each cursor in cursors must already be positioned at the desired secondary key value (e.g. via SecondaryCursor::get_search_key). The join algorithm iterates through all candidate primary keys from cursors[0] and probes cursors[1..n] to confirm each candidate also appears in their secondary keys. Candidates that pass all probes are returned by JoinCursor::get_next.

Unless config.no_sort is true, the cursor array is re-ordered by ascending duplicate-count estimate before the join starts, matching JE’s optimisation for minimum candidate-set size.

The returned JoinCursor owns the cursors for its lifetime.

§Errors

Returns an error if this database handle is closed.

Source§

impl Database

Source

pub fn open_disk_ordered_cursor( &self, config: DiskOrderedCursorConfig, ) -> Result<DiskOrderedCursor<'_>, NoxuError>

Opens a single-database disk-ordered cursor.

This is a convenience for the common case; for a multi-database scan use open_disk_ordered_cursor_multi.

Trait Implementations§

Source§

impl Drop for Database

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§

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more