sled

Struct Db

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

The sled embedded database! Implements Deref<Target = sled::Tree> to refer to a default keyspace / namespace / bucket.

Implementations§

Source§

impl Db

Source

pub fn open_tree<V: AsRef<[u8]>>(&self, name: V) -> Result<Tree>

Open or create a new disk-backed Tree with its own keyspace, accessible from the Db via the provided identifier.

Source

pub fn drop_tree<V: AsRef<[u8]>>(&self, name: V) -> Result<bool>

Remove a disk-backed collection.

Source

pub fn tree_names(&self) -> Vec<IVec>

Returns the trees names saved in this Db.

Source

pub fn was_recovered(&self) -> bool

Returns true if the database was recovered from a previous process. Note that database state is only guaranteed to be present up to the last call to flush! Otherwise state is synced to disk periodically if the sync_every_ms configuration option is set to Some(number_of_ms_between_syncs) or if the IO buffer gets filled to capacity before being rotated.

Source

pub fn generate_id(&self) -> Result<u64>

Generate a monotonic ID. Not guaranteed to be contiguous. Written to disk every idgen_persist_interval operations, followed by a blocking flush. During recovery, we take the last recovered generated ID and add 2x the idgen_persist_interval to it. While persisting, if the previous persisted counter wasn’t synced to disk yet, we will do a blocking flush to fsync the latest counter, ensuring that we will never give out the same counter twice.

Source

pub fn export( &self, ) -> Vec<(Vec<u8>, Vec<u8>, impl Iterator<Item = Vec<Vec<u8>>>)>

A database export method for all collections in the Db, for use in sled version upgrades. Can be used in combination with the import method below on a database running a later version.

§Panics

Panics if any IO problems occur while trying to perform the export.

§Examples

If you want to migrate from one version of sled to another, you need to pull in both versions by using version renaming:

Cargo.toml:

[dependencies]
sled = "0.32"
old_sled = { version = "0.31", package = "sled" }

and in your code, remember that old versions of sled might have a different way to open them than the current sled::open method:

let old = old_sled::open("my_old_db")?;

// may be a different version of sled,
// the export type is version agnostic.
let new = sled::open("my_new_db")?;

let export = old.export();
new.import(export);

assert_eq!(old.checksum()?, new.checksum()?);
Source

pub fn import( &self, export: Vec<(Vec<u8>, Vec<u8>, impl Iterator<Item = Vec<Vec<u8>>>)>, )

Imports the collections from a previous database.

§Panics

Panics if any IO problems occur while trying to perform the import.

§Examples

If you want to migrate from one version of sled to another, you need to pull in both versions by using version renaming:

Cargo.toml:

[dependencies]
sled = "0.32"
old_sled = { version = "0.31", package = "sled" }

and in your code, remember that old versions of sled might have a different way to open them than the current sled::open method:

let old = old_sled::open("my_old_db")?;

// may be a different version of sled,
// the export type is version agnostic.
let new = sled::open("my_new_db")?;

let export = old.export();
new.import(export);

assert_eq!(old.checksum()?, new.checksum()?);
Source

pub fn checksum(&self) -> Result<u32>

Returns the CRC32 of all keys and values in this Db.

This is O(N) and locks all underlying Trees for the duration of the entire scan.

Source

pub fn size_on_disk(&self) -> Result<u64>

Returns the on-disk size of the storage files for this database.

Methods from Deref<Target = Tree>§

Source

pub fn insert<K, V>(&self, key: K, value: V) -> Result<Option<IVec>>
where K: AsRef<[u8]>, V: Into<IVec>,

Insert a key to a new value, returning the last value if it was set.

§Examples
assert_eq!(db.insert(&[1, 2, 3], vec![0]), Ok(None));
assert_eq!(db.insert(&[1, 2, 3], vec![1]), Ok(Some(sled::IVec::from(&[0]))));
Source

pub fn transaction<F, A, E>(&self, f: F) -> TransactionResult<A, E>

Perform a multi-key serializable transaction.

§Examples
// Use write-only transactions as a writebatch:
db.transaction(|tx_db| {
    tx_db.insert(b"k1", b"cats")?;
    tx_db.insert(b"k2", b"dogs")?;
    Ok(())
})?;

// Atomically swap two items:
db.transaction(|tx_db| {
    let v1_option = tx_db.remove(b"k1")?;
    let v1 = v1_option.unwrap();
    let v2_option = tx_db.remove(b"k2")?;
    let v2 = v2_option.unwrap();

    tx_db.insert(b"k1", v2)?;
    tx_db.insert(b"k2", v1)?;

    Ok(())
})?;

assert_eq!(&db.get(b"k1")?.unwrap(), b"dogs");
assert_eq!(&db.get(b"k2")?.unwrap(), b"cats");

A transaction may return information from an intentionally-cancelled transaction by using the abort function inside the closure in combination with the try operator.

use sled::{transaction::{abort, TransactionError, TransactionResult}, Config};

#[derive(Debug, PartialEq)]
struct MyBullshitError;

fn main() -> TransactionResult<(), MyBullshitError> {
    let config = Config::new().temporary(true);
    let db = config.open()?;

    // Use write-only transactions as a writebatch:
    let res = db.transaction(|tx_db| {
        tx_db.insert(b"k1", b"cats")?;
        tx_db.insert(b"k2", b"dogs")?;
        // aborting will cause all writes to roll-back.
        if true {
            abort(MyBullshitError)?;
        }
        Ok(42)
    }).unwrap_err();

    assert_eq!(res, TransactionError::Abort(MyBullshitError));
    assert_eq!(db.get(b"k1")?, None);
    assert_eq!(db.get(b"k2")?, None);

    Ok(())
}

Transactions also work on tuples of Trees, preserving serializable ACID semantics! In this example, we treat two trees like a work queue, atomically apply updates to data and move them from the unprocessed Tree to the processed Tree.

use sled::Transactional;

let unprocessed = db.open_tree(b"unprocessed items")?;
let processed = db.open_tree(b"processed items")?;

// An update somehow gets into the tree, which we
// later trigger the atomic processing of.
unprocessed.insert(b"k3", b"ligers")?;

// Atomically process the new item and move it
// between `Tree`s.
(&unprocessed, &processed)
    .transaction(|(tx_unprocessed, tx_processed)| {
        let unprocessed_item = tx_unprocessed.remove(b"k3")?.unwrap();
        let mut processed_item = b"yappin' ".to_vec();
        processed_item.extend_from_slice(&unprocessed_item);
        tx_processed.insert(b"k3", processed_item)?;
        Ok(())
    })?;

assert_eq!(unprocessed.get(b"k3").unwrap(), None);
assert_eq!(&processed.get(b"k3").unwrap().unwrap(), b"yappin' ligers");
Source

pub fn apply_batch(&self, batch: Batch) -> Result<()>

Create a new batched update that can be atomically applied.

It is possible to apply a Batch in a transaction as well, which is the way you can apply a Batch to multiple Trees atomically.

§Examples
db.insert("key_0", "val_0")?;

let mut batch = sled::Batch::default();
batch.insert("key_a", "val_a");
batch.insert("key_b", "val_b");
batch.insert("key_c", "val_c");
batch.remove("key_0");

db.apply_batch(batch)?;
// key_0 no longer exists, and key_a, key_b, and key_c
// now do exist.
Source

pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<IVec>>

Retrieve a value from the Tree if it exists.

§Examples
db.insert(&[0], vec![0])?;
assert_eq!(db.get(&[0]), Ok(Some(sled::IVec::from(vec![0]))));
assert_eq!(db.get(&[1]), Ok(None));
Source

pub fn remove<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<IVec>>

Delete a value, returning the old value if it existed.

§Examples
db.insert(&[1], vec![1]);
assert_eq!(db.remove(&[1]), Ok(Some(sled::IVec::from(vec![1]))));
assert_eq!(db.remove(&[1]), Ok(None));
Source

pub fn compare_and_swap<K, OV, NV>( &self, key: K, old: Option<OV>, new: Option<NV>, ) -> Result<Result<(), CompareAndSwapError>>
where K: AsRef<[u8]>, OV: AsRef<[u8]>, NV: Into<IVec>,

Compare and swap. Capable of unique creation, conditional modification, or deletion. If old is None, this will only set the value if it doesn’t exist yet. If new is None, will delete the value if old is correct. If both old and new are Some, will modify the value if old is correct.

It returns Ok(Ok(())) if operation finishes successfully.

If it fails it returns: - Ok(Err(CompareAndSwapError(current, proposed))) if operation failed to setup a new value. CompareAndSwapError contains current and proposed values. - Err(Error::Unsupported) if the database is opened in read-only mode.

§Examples
// unique creation
assert_eq!(
    db.compare_and_swap(&[1], None as Option<&[u8]>, Some(&[10])),
    Ok(Ok(()))
);

// conditional modification
assert_eq!(
    db.compare_and_swap(&[1], Some(&[10]), Some(&[20])),
    Ok(Ok(()))
);

// failed conditional modification -- the current value is returned in
// the error variant
let operation = db.compare_and_swap(&[1], Some(&[30]), Some(&[40]));
assert!(operation.is_ok()); // the operation succeeded
let modification = operation.unwrap();
assert!(modification.is_err());
let actual_value = modification.unwrap_err();
assert_eq!(actual_value.current.map(|ivec| ivec.to_vec()), Some(vec![20]));

// conditional deletion
assert_eq!(
    db.compare_and_swap(&[1], Some(&[20]), None as Option<&[u8]>),
    Ok(Ok(()))
);
assert_eq!(db.get(&[1]), Ok(None));
Source

pub fn update_and_fetch<K, V, F>(&self, key: K, f: F) -> Result<Option<IVec>>
where K: AsRef<[u8]>, F: FnMut(Option<&[u8]>) -> Option<V>, V: Into<IVec>,

Fetch the value, apply a function to it and return the result.

§Note

This may call the function multiple times if the value has been changed from other threads in the meantime.

§Examples
use sled::{Config, Error, IVec};
use std::convert::TryInto;

let config = Config::new().temporary(true);
let db = config.open()?;

fn u64_to_ivec(number: u64) -> IVec {
    IVec::from(number.to_be_bytes().to_vec())
}

let zero = u64_to_ivec(0);
let one = u64_to_ivec(1);
let two = u64_to_ivec(2);
let three = u64_to_ivec(3);

fn increment(old: Option<&[u8]>) -> Option<Vec<u8>> {
    let number = match old {
        Some(bytes) => {
            let array: [u8; 8] = bytes.try_into().unwrap();
            let number = u64::from_be_bytes(array);
            number + 1
        }
        None => 0,
    };

    Some(number.to_be_bytes().to_vec())
}

assert_eq!(db.update_and_fetch("counter", increment), Ok(Some(zero)));
assert_eq!(db.update_and_fetch("counter", increment), Ok(Some(one)));
assert_eq!(db.update_and_fetch("counter", increment), Ok(Some(two)));
assert_eq!(db.update_and_fetch("counter", increment), Ok(Some(three)));
Source

pub fn fetch_and_update<K, V, F>(&self, key: K, f: F) -> Result<Option<IVec>>
where K: AsRef<[u8]>, F: FnMut(Option<&[u8]>) -> Option<V>, V: Into<IVec>,

Fetch the value, apply a function to it and return the previous value.

§Note

This may call the function multiple times if the value has been changed from other threads in the meantime.

§Examples
use sled::{Config, Error, IVec};
use std::convert::TryInto;

let config = Config::new().temporary(true);
let db = config.open()?;

fn u64_to_ivec(number: u64) -> IVec {
    IVec::from(number.to_be_bytes().to_vec())
}

let zero = u64_to_ivec(0);
let one = u64_to_ivec(1);
let two = u64_to_ivec(2);

fn increment(old: Option<&[u8]>) -> Option<Vec<u8>> {
    let number = match old {
        Some(bytes) => {
            let array: [u8; 8] = bytes.try_into().unwrap();
            let number = u64::from_be_bytes(array);
            number + 1
        }
        None => 0,
    };

    Some(number.to_be_bytes().to_vec())
}

assert_eq!(db.fetch_and_update("counter", increment), Ok(None));
assert_eq!(db.fetch_and_update("counter", increment), Ok(Some(zero)));
assert_eq!(db.fetch_and_update("counter", increment), Ok(Some(one)));
assert_eq!(db.fetch_and_update("counter", increment), Ok(Some(two)));
Source

pub fn watch_prefix<P: AsRef<[u8]>>(&self, prefix: P) -> Subscriber

Subscribe to Events that happen to keys that have the specified prefix. Events for particular keys are guaranteed to be witnessed in the same order by all threads, but threads may witness different interleavings of Events across different keys. If subscribers don’t keep up with new writes, they will cause new writes to block. There is a buffer of 1024 items per Subscriber. This can be used to build reactive and replicated systems.

Subscriber implements both Iterator<Item = Event> and Future<Output=Option<Event>>

§Examples

Synchronous, blocking subscriber:

// watch all events by subscribing to the empty prefix
let mut subscriber = db.watch_prefix(vec![]);

let tree_2 = db.clone();
let thread = std::thread::spawn(move || {
    db.insert(vec![0], vec![1])
});

// `Subscription` implements `Iterator<Item=Event>`
for event in subscriber.take(1) {
    match event {
        sled::Event::Insert{ key, value } => assert_eq!(key.as_ref(), &[0]),
        sled::Event::Remove {key } => {}
    }
}

Aynchronous, non-blocking subscriber:

Subscription implements Future<Output=Option<Event>>.

while let Some(event) = (&mut subscriber).await { /* use it */ }

Source

pub fn flush(&self) -> Result<usize>

Synchronously flushes all dirty IO buffers and calls fsync. If this succeeds, it is guaranteed that all previous writes will be recovered if the system crashes. Returns the number of bytes flushed during this call.

Flushing can take quite a lot of time, and you should measure the performance impact of using it on realistic sustained workloads running on realistic hardware.

Source

pub async fn flush_async(&self) -> Result<usize>

Asynchronously flushes all dirty IO buffers and calls fsync. If this succeeds, it is guaranteed that all previous writes will be recovered if the system crashes. Returns the number of bytes flushed during this call.

Flushing can take quite a lot of time, and you should measure the performance impact of using it on realistic sustained workloads running on realistic hardware.

Source

pub fn contains_key<K: AsRef<[u8]>>(&self, key: K) -> Result<bool>

Returns true if the Tree contains a value for the specified key.

§Examples
db.insert(&[0], vec![0])?;
assert!(db.contains_key(&[0])?);
assert!(!db.contains_key(&[1])?);
Source

pub fn get_lt<K>(&self, key: K) -> Result<Option<(IVec, IVec)>>
where K: AsRef<[u8]>,

Retrieve the key and value before the provided key, if one exists.

§Examples
use sled::IVec;
for i in 0..10 {
    db.insert(&[i], vec![i])
        .expect("should write successfully");
}

assert_eq!(db.get_lt(&[]), Ok(None));
assert_eq!(db.get_lt(&[0]), Ok(None));
assert_eq!(
    db.get_lt(&[1]),
    Ok(Some((IVec::from(&[0]), IVec::from(&[0]))))
);
assert_eq!(
    db.get_lt(&[9]),
    Ok(Some((IVec::from(&[8]), IVec::from(&[8]))))
);
assert_eq!(
    db.get_lt(&[10]),
    Ok(Some((IVec::from(&[9]), IVec::from(&[9]))))
);
assert_eq!(
    db.get_lt(&[255]),
    Ok(Some((IVec::from(&[9]), IVec::from(&[9]))))
);
Source

pub fn get_gt<K>(&self, key: K) -> Result<Option<(IVec, IVec)>>
where K: AsRef<[u8]>,

Retrieve the next key and value from the Tree after the provided key.

§Note

The order follows the Ord implementation for Vec<u8>:

[] < [0] < [255] < [255, 0] < [255, 255] ...

To retain the ordering of numerical types use big endian reprensentation

§Examples
use sled::IVec;
for i in 0..10 {
    db.insert(&[i], vec![i])?;
}

assert_eq!(
    db.get_gt(&[]),
    Ok(Some((IVec::from(&[0]), IVec::from(&[0]))))
);
assert_eq!(
    db.get_gt(&[0]),
    Ok(Some((IVec::from(&[1]), IVec::from(&[1]))))
);
assert_eq!(
    db.get_gt(&[1]),
    Ok(Some((IVec::from(&[2]), IVec::from(&[2]))))
);
assert_eq!(
    db.get_gt(&[8]),
    Ok(Some((IVec::from(&[9]), IVec::from(&[9]))))
);
assert_eq!(db.get_gt(&[9]), Ok(None));

db.insert(500u16.to_be_bytes(), vec![10]);
assert_eq!(
    db.get_gt(&499u16.to_be_bytes()),
    Ok(Some((IVec::from(&500u16.to_be_bytes()), IVec::from(&[10]))))
);
Source

pub fn merge<K, V>(&self, key: K, value: V) -> Result<Option<IVec>>
where K: AsRef<[u8]>, V: AsRef<[u8]>,

Merge state directly into a given key’s value using the configured merge operator. This allows state to be written into a value directly, without any read-modify-write steps. Merge operators can be used to implement arbitrary data structures.

Calling merge will return an Unsupported error if it is called without first setting a merge operator function.

Merge operators are shared by all instances of a particular Tree. Different merge operators may be set on different Trees.

§Examples
use sled::IVec;

fn concatenate_merge(
  _key: &[u8],               // the key being merged
  old_value: Option<&[u8]>,  // the previous value, if one existed
  merged_bytes: &[u8]        // the new bytes being merged in
) -> Option<Vec<u8>> {       // set the new value, return None to delete
  let mut ret = old_value
    .map(|ov| ov.to_vec())
    .unwrap_or_else(|| vec![]);

  ret.extend_from_slice(merged_bytes);

  Some(ret)
}

db.set_merge_operator(concatenate_merge);

let k = b"k1";

db.insert(k, vec![0]);
db.merge(k, vec![1]);
db.merge(k, vec![2]);
assert_eq!(db.get(k), Ok(Some(IVec::from(vec![0, 1, 2]))));

// Replace previously merged data. The merge function will not be called.
db.insert(k, vec![3]);
assert_eq!(db.get(k), Ok(Some(IVec::from(vec![3]))));

// Merges on non-present values will cause the merge function to be called
// with `old_value == None`. If the merge function returns something (which it
// does, in this case) a new value will be inserted.
db.remove(k);
db.merge(k, vec![4]);
assert_eq!(db.get(k), Ok(Some(IVec::from(vec![4]))));
Source

pub fn set_merge_operator(&self, merge_operator: impl MergeOperator + 'static)

Sets a merge operator for use with the merge function.

Merge state directly into a given key’s value using the configured merge operator. This allows state to be written into a value directly, without any read-modify-write steps. Merge operators can be used to implement arbitrary data structures.

§Panics

Calling merge will panic if no merge operator has been configured.

§Examples
use sled::IVec;

fn concatenate_merge(
  _key: &[u8],               // the key being merged
  old_value: Option<&[u8]>,  // the previous value, if one existed
  merged_bytes: &[u8]        // the new bytes being merged in
) -> Option<Vec<u8>> {       // set the new value, return None to delete
  let mut ret = old_value
    .map(|ov| ov.to_vec())
    .unwrap_or_else(|| vec![]);

  ret.extend_from_slice(merged_bytes);

  Some(ret)
}

db.set_merge_operator(concatenate_merge);

let k = b"k1";

db.insert(k, vec![0]);
db.merge(k, vec![1]);
db.merge(k, vec![2]);
assert_eq!(db.get(k), Ok(Some(IVec::from(vec![0, 1, 2]))));

// Replace previously merged data. The merge function will not be called.
db.insert(k, vec![3]);
assert_eq!(db.get(k), Ok(Some(IVec::from(vec![3]))));

// Merges on non-present values will cause the merge function to be called
// with `old_value == None`. If the merge function returns something (which it
// does, in this case) a new value will be inserted.
db.remove(k);
db.merge(k, vec![4]);
assert_eq!(db.get(k), Ok(Some(IVec::from(vec![4]))));
Source

pub fn iter(&self) -> Iter

Create a double-ended iterator over the tuples of keys and values in this tree.

§Examples
use sled::IVec;
db.insert(&[1], vec![10]);
db.insert(&[2], vec![20]);
db.insert(&[3], vec![30]);
let mut iter = db.iter();
assert_eq!(
    iter.next().unwrap(),
    Ok((IVec::from(&[1]), IVec::from(&[10])))
);
assert_eq!(
    iter.next().unwrap(),
    Ok((IVec::from(&[2]), IVec::from(&[20])))
);
assert_eq!(
    iter.next().unwrap(),
    Ok((IVec::from(&[3]), IVec::from(&[30])))
);
assert_eq!(iter.next(), None);
Source

pub fn range<K, R>(&self, range: R) -> Iter
where K: AsRef<[u8]>, R: RangeBounds<K>,

Create a double-ended iterator over tuples of keys and values, where the keys fall within the specified range.

§Examples
use sled::IVec;
db.insert(&[0], vec![0])?;
db.insert(&[1], vec![10])?;
db.insert(&[2], vec![20])?;
db.insert(&[3], vec![30])?;
db.insert(&[4], vec![40])?;
db.insert(&[5], vec![50])?;

let start: &[u8] = &[2];
let end: &[u8] = &[4];
let mut r = db.range(start..end);
assert_eq!(r.next().unwrap(), Ok((IVec::from(&[2]), IVec::from(&[20]))));
assert_eq!(r.next().unwrap(), Ok((IVec::from(&[3]), IVec::from(&[30]))));
assert_eq!(r.next(), None);

let mut r = db.range(start..end).rev();
assert_eq!(r.next().unwrap(), Ok((IVec::from(&[3]), IVec::from(&[30]))));
assert_eq!(r.next().unwrap(), Ok((IVec::from(&[2]), IVec::from(&[20]))));
assert_eq!(r.next(), None);
Source

pub fn scan_prefix<P>(&self, prefix: P) -> Iter
where P: AsRef<[u8]>,

Create an iterator over tuples of keys and values, where the all the keys starts with the given prefix.

§Examples
use sled::IVec;
db.insert(&[0, 0, 0], vec![0, 0, 0])?;
db.insert(&[0, 0, 1], vec![0, 0, 1])?;
db.insert(&[0, 0, 2], vec![0, 0, 2])?;
db.insert(&[0, 0, 3], vec![0, 0, 3])?;
db.insert(&[0, 1, 0], vec![0, 1, 0])?;
db.insert(&[0, 1, 1], vec![0, 1, 1])?;

let prefix: &[u8] = &[0, 0];
let mut r = db.scan_prefix(prefix);
assert_eq!(
    r.next(),
    Some(Ok((IVec::from(&[0, 0, 0]), IVec::from(&[0, 0, 0]))))
);
assert_eq!(
    r.next(),
    Some(Ok((IVec::from(&[0, 0, 1]), IVec::from(&[0, 0, 1]))))
);
assert_eq!(
    r.next(),
    Some(Ok((IVec::from(&[0, 0, 2]), IVec::from(&[0, 0, 2]))))
);
assert_eq!(
    r.next(),
    Some(Ok((IVec::from(&[0, 0, 3]), IVec::from(&[0, 0, 3]))))
);
assert_eq!(r.next(), None);
Source

pub fn first(&self) -> Result<Option<(IVec, IVec)>>

Returns the first key and value in the Tree, or None if the Tree is empty.

Source

pub fn last(&self) -> Result<Option<(IVec, IVec)>>

Returns the last key and value in the Tree, or None if the Tree is empty.

Source

pub fn pop_max(&self) -> Result<Option<(IVec, IVec)>>

Atomically removes the maximum item in the Tree instance.

§Examples
db.insert(&[0], vec![0])?;
db.insert(&[1], vec![10])?;
db.insert(&[2], vec![20])?;
db.insert(&[3], vec![30])?;
db.insert(&[4], vec![40])?;
db.insert(&[5], vec![50])?;

assert_eq!(&db.pop_max()?.unwrap().0, &[5]);
assert_eq!(&db.pop_max()?.unwrap().0, &[4]);
assert_eq!(&db.pop_max()?.unwrap().0, &[3]);
assert_eq!(&db.pop_max()?.unwrap().0, &[2]);
assert_eq!(&db.pop_max()?.unwrap().0, &[1]);
assert_eq!(&db.pop_max()?.unwrap().0, &[0]);
assert_eq!(db.pop_max()?, None);
Source

pub fn pop_min(&self) -> Result<Option<(IVec, IVec)>>

Atomically removes the minimum item in the Tree instance.

§Examples
db.insert(&[0], vec![0])?;
db.insert(&[1], vec![10])?;
db.insert(&[2], vec![20])?;
db.insert(&[3], vec![30])?;
db.insert(&[4], vec![40])?;
db.insert(&[5], vec![50])?;

assert_eq!(&db.pop_min()?.unwrap().0, &[0]);
assert_eq!(&db.pop_min()?.unwrap().0, &[1]);
assert_eq!(&db.pop_min()?.unwrap().0, &[2]);
assert_eq!(&db.pop_min()?.unwrap().0, &[3]);
assert_eq!(&db.pop_min()?.unwrap().0, &[4]);
assert_eq!(&db.pop_min()?.unwrap().0, &[5]);
assert_eq!(db.pop_min()?, None);
Source

pub fn len(&self) -> usize

Returns the number of elements in this tree.

Beware: performs a full O(n) scan under the hood.

§Examples
db.insert(b"a", vec![0]);
db.insert(b"b", vec![1]);
assert_eq!(db.len(), 2);
Source

pub fn is_empty(&self) -> bool

Returns true if the Tree contains no elements.

Source

pub fn clear(&self) -> Result<()>

Clears the Tree, removing all values.

Note that this is not atomic.

Source

pub fn name(&self) -> IVec

Returns the name of the tree.

Source

pub fn checksum(&self) -> Result<u32>

Returns the CRC32 of all keys and values in this Tree.

This is O(N) and locks the underlying tree for the duration of the entire scan.

Trait Implementations§

Source§

impl Clone for Db

Source§

fn clone(&self) -> Db

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Db

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Deref for Db

Source§

type Target = Tree

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Tree

Dereferences the value.
Source§

impl Send for Db

Source§

impl Sync for Db

Auto Trait Implementations§

§

impl Freeze for Db

§

impl !RefUnwindSafe for Db

§

impl Unpin for Db

§

impl !UnwindSafe for Db

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> 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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. 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.