Struct lsmlite_rs::LsmCursor

source ·
pub struct LsmCursor<'a> { /* private fields */ }
Expand description

This is the main cursor structure.

Trait Implementations§

source§

impl Cursor for LsmCursor<'_>

Custom implementation of Cursor for LsmCursor.

source§

fn close(&mut self) -> Result<(), LsmErrorCode>

This function closes an existing cursor over the underlying database. A call to Disk::cursor_open must be paired up (in the end) with a call to Cursor::close. Otherwise the database won’t be cleanly closed (due to the snapshot that belongs to the cursor), and a recovery process will be spawn the next time the database file is opened.

For completeness, LsmCursor also implements Drop so that a cursor gets automatically released once it goes out of scope (thus releasing resources).

Closing an uninitialized LsmCursor is considered LsmErrorCode::LsmMisuse.

source§

fn valid(&self) -> Result<(), LsmErrorCode>

Tests whether the cursor is currently pointing to a valid database record. When operating a cursor, this function has to be called before extracting records from it (key and/or value) to make sure that the values can be trusted. That is, a cursor might internally retain the last output value for a while after it has become invalid (say moved past the end of the database), or empty values can be extracted from it before positioning the cursor on a valid record.

Testing for validity of an uninitialized uninitialized LsmCursor is considered LsmErrorCode::LsmMisuse.

source§

fn first(&mut self) -> Result<(), LsmErrorCode>

Moves the cursor to the very first record in the database. Positioning an uninitialized LsmCursor is considered LsmErrorCode::LsmMisuse.

Example
use lsmlite_rs::*;

let db_conf = DbConf::new(
                          "/tmp/",
                          "my_db_h".to_string(),
);

let mut db: LsmDb = Default::default();
let rc = db.initialize(db_conf);
let rc = db.connect();

// Insert data into the database, so that something gets traversed.
let key: usize = 1;
let key_serial = key.to_be_bytes();
// 1 KB zeroed payload.
let value = vec![0; 1024];
let rc = db.persist(&key_serial, &value)?;

let key: usize = 2;
let key_serial = key.to_be_bytes();
let rc = db.persist(&key_serial, &value)?;

let mut cursor = db.cursor_open()?;

let rc = cursor.first();
assert!(rc.is_ok());

let mut num_records = 0;
while cursor.valid().is_ok() {
    num_records += 1;
    let current_key = Cursor::get_key(&cursor)?;
    let current_value = Cursor::get_value(&cursor)?;
    cursor.next()?;
}
assert_eq!(num_records, 2);

// EOF
assert!(cursor.valid().is_err());
source§

fn last(&mut self) -> Result<(), LsmErrorCode>

Moves the cursor to the very last record in the database. Positioning an uninitialized LsmCursor is considered LsmErrorCode::LsmMisuse.

Example
use lsmlite_rs::*;

let db_conf = DbConf::new(
                          "/tmp/",
                          "my_db_i".to_string(),
);

let mut db: LsmDb = Default::default();
let rc = db.initialize(db_conf);
let rc = db.connect();

// Insert data into the database, so that something gets traversed.
let key: usize = 1;
let key_serial = key.to_be_bytes();
// 1 KB zeroed payload.
let value = vec![0; 1024];
let rc = db.persist(&key_serial, &value)?;

let key: usize = 2;
let key_serial = key.to_be_bytes();
let rc = db.persist(&key_serial, &value)?;

let mut cursor = db.cursor_open()?;

let rc = cursor.last();
assert!(rc.is_ok());

let mut num_records = 0;
while cursor.valid().is_ok() {
    num_records += 1;
    let current_key = Cursor::get_key(&cursor)?;
    let current_value = Cursor::get_value(&cursor)?;
    cursor.prev()?;
}
assert_eq!(num_records, 2);

// EOF
assert!(cursor.valid().is_err());
source§

fn seek( &mut self, key: &[u8], mode: LsmCursorSeekOp ) -> Result<(), LsmErrorCode>

This positions the cursor on an entry of the database that depends on the seek mode provided:

  1. If LsmCursorSeekOp::LsmCursorSeekLe is given, then the cursor will be positioned at the entry that is less or equal than the provided key depending on whether the key is found in the database or not.
  2. If LsmCursorSeekOp::LsmCursorSeekEq is given, then the cursor will be positioned at the entry that corresponding to the given key, or at the end of the database depending on whether the entry is found or not. If the entry is found, a call to valid on the cursor will return success, and otherwise an error.
  3. If LsmCursorSeekOp::LsmCursorSeekGe is given, then the cursor will be positioned at the entry that is greater or equal than the provided key depending on whether the key is found in the database or not.
source§

fn next(&mut self) -> Result<(), LsmErrorCode>

Once a cursor is position at a valid entry, this function moves it to the next entry. This function can be called only when moving forward on the database. That is, when starting from Cursor::first or when seeking with LsmCursorSeekOp::LsmCursorSeekGe. Otherwise an error will be issued.

source§

fn prev(&mut self) -> Result<(), LsmErrorCode>

Similar to Cursor::next, but moving to the previous entry. This function can be called only when moving backwards on the database. That is, when starting from Cursor::last or when seeking with LsmCursorSeekOp::LsmCursorSeekLe. Otherwise an error will be issued.

source§

fn get_key(&self) -> Result<Vec<u8>, LsmErrorCode>

If the cursor is Cursor::valid, then this function retrieves the key of the entry the cursor is currently pointing to. The memory the key uses belongs to the parent call. If the cursor is not valid, an error is returned.

source§

fn get_value(&self) -> Result<Vec<u8>, LsmErrorCode>

If the cursor is Cursor::valid, then this function retrieves the value of the entry the cursor is currently pointing to. The memory the key uses belongs to the parent call. If the cursor is not valid, an error is returned.

source§

fn compare(&self, key: &[u8]) -> Result<Ordering, LsmErrorCode>

If the cursor is Cursor::valid, then this function compares the key of the entry the cursor is currently pointing to, with the given key. On success, the result of the comparison is returned. The comparison happens as per memcmp, that is, if the cursor’s key is Ordering::Less, Ordering::Equal, or Ordering::Greater than the provided key, then the corresponding Ordering will be returned. On prefix comparison, that is, the given key is a strict prefix of the cursor key, Ordering::Greater will be returned.

This function is useful when probing the database for a range.

Example
use std::cmp::Ordering;
use lsmlite_rs::*;

let db_conf = DbConf::new(
                          "/tmp/",
                          "my_db_j".to_string(),
);

let mut db: LsmDb = Default::default();
let rc = db.initialize(db_conf);
let rc = db.connect();

// Insert data into the database, so that something gets traversed.
let key: usize = 1;
let key_serial = key.to_be_bytes();
// 1 KB zeroed payload.
let value = vec![0; 1024];
let rc = db.persist(&key_serial, &value)?;

let key: usize = 2;
let key_serial = key.to_be_bytes();
let rc = db.persist(&key_serial, &value)?;

let mut cursor = db.cursor_open()?;

let rc = cursor.first();
assert!(rc.is_ok());

// Assume the very first record is smaller than this.
let key_ub_value: usize = 2;
let key_ub_serial = key_ub_value.to_be_bytes();
// `Ordering::Less` tells that the key of the cursor is smaller
// than `key_ub_value`.
let mut key_cmp = cursor.compare(&key_ub_serial)?;

let mut num_records = 0;
while cursor.valid().is_ok() && key_cmp < Ordering::Equal {
   num_records += 1;
   cursor.next()?;
   key_cmp = cursor.compare(&key_ub_serial)?;
}

assert_eq!(num_records, 1);

// We either exhausted the database or found a key >= than `key_ub_value`.
source§

impl Default for LsmCursor<'_>

A default cursor. This cursor is not useful by itself as it is not bound to any database. This construction is provided to be used in cases in which a cursor needs to be declared ahead of time, only to be later assigned a cursor bound to a database.

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Drop for LsmCursor<'_>

Drop for LsmCursor so that it gets properly terminated when it goes out of scope for example.

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for LsmCursor<'a>

§

impl<'a> !Send for LsmCursor<'a>

§

impl<'a> !Sync for LsmCursor<'a>

§

impl<'a> Unpin for LsmCursor<'a>

§

impl<'a> UnwindSafe for LsmCursor<'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> 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, U> TryFrom<U> for T
where U: Into<T>,

§

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

§

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