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(None, &key, &value).unwrap();

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

Implementations§

Source§

impl Database

Source

pub fn get( &self, txn: Option<&Transaction>, key: &DatabaseEntry, data: &mut DatabaseEntry, ) -> Result<OperationStatus, NoxuError>

Retrieves a record by key.

§Arguments
  • txn - Optional transaction handle (used to scope locks and writes to the transaction)
  • key - The search key
  • data - Output parameter to receive the data
§Returns

OperationStatus::Success if found, OperationStatus::NotFound otherwise

§Errors

Returns an error if the database is closed

Source

pub fn get_with_options( &self, txn: Option<&Transaction>, key: &DatabaseEntry, data: &mut DatabaseEntry, opts: &ReadOptions, ) -> Result<OperationStatus, NoxuError>

Retrieves a record with per-operation read options.

Mirrors Cursor.get() with ReadOptions applied:

  • LockMode::ReadUncommitted — dirty read, no lock acquired ( read-uncommitted)
  • 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 (currently informational).

§Arguments
  • txn - Optional transaction handle
  • key - The search key
  • data - Output parameter to receive the data
  • opts - Per-operation read options (isolation, cache hints)
§Returns

OperationStatus::Success if found, OperationStatus::NotFound otherwise

Source

pub fn put( &self, txn: Option<&Transaction>, key: &DatabaseEntry, data: &DatabaseEntry, ) -> Result<OperationStatus, NoxuError>

Inserts or updates a record.

§Arguments
  • txn - Optional transaction handle (used to scope locks and writes to the transaction)
  • key - The key to insert/update
  • data - The data to store
§Returns

OperationStatus::Success on success

§Errors

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

Source

pub fn put_with_options( &self, txn: Option<&Transaction>, key: &DatabaseEntry, data: &DatabaseEntry, opts: &WriteOptions, ) -> Result<OperationStatus, NoxuError>

Inserts or updates a record with per-operation write options.

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. Stored in the BIN slot as absolute hours since Unix epoch, matching the BIN.expirationInHours / IN.entryExpiration path.
  • update_ttl — if true and the record already exists, refreshes its TTL to the new value rather than leaving the original expiration.
  • cache_mode — advisory cache hint (currently informational).
§Arguments
  • txn - Optional transaction handle
  • key - The key to insert/update
  • data - The data to store
  • opts - Per-operation write options (TTL, cache hints)
§Returns

OperationStatus::Success on success

Source

pub fn put_no_overwrite( &self, txn: Option<&Transaction>, key: &DatabaseEntry, data: &DatabaseEntry, ) -> Result<OperationStatus, NoxuError>

Inserts a record, failing if the key already exists.

§Arguments
  • txn - Optional transaction handle (used to scope locks and writes to the transaction)
  • key - The key to insert
  • data - The data to store
§Returns

OperationStatus::Success if inserted, OperationStatus::KeyExists if key already exists

§Errors

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

Source

pub fn delete( &self, txn: Option<&Transaction>, key: &DatabaseEntry, ) -> Result<OperationStatus, NoxuError>

Deletes a record by key.

§Arguments
  • txn - Optional transaction handle (used to scope locks and writes to the transaction)
  • key - The key to delete
§Returns

OperationStatus::Success if deleted, OperationStatus::NotFound if key didn’t exist

§Errors

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

Source

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

Opens a cursor for iterating over database records.

When a Some(&txn) is passed, 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. When txn is None the cursor runs in auto-commit mode — each write is its own transaction and is fsynced before returning.

You must close the cursor before committing or aborting the transaction it was opened under.

§Arguments
  • txn - Optional transaction handle that the cursor should participate in.
  • config - Optional cursor configuration
§Returns

A new cursor handle

§Errors

Returns an error if the database is closed

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 get_database_name(&self) -> &str

Returns the database name.

Source

pub fn get_config(&self) -> &DatabaseConfig

Returns the database configuration.

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 get_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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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