pub struct StateBTreeMap<K, V, const M: usize = 8> { /* private fields */ }
Expand description

An ordered map based on B-Tree, where each node is stored separately in the low-level key-value store.

It can be seen as an extension adding tracking of the keys ordering on top of StateMap to provide functions such as higher and lower. This results in some overhead when inserting and deleting entries from the map compared to using StateMap.

OperationPerformance
get / get_mutO(k)
insertO(k + log(n))
removeO(k + log(n))
higher/lowerO(k + log(n))

Where k is the byte size of the serialized keys and n is the number of entries in the map.

§Type parameters

The map StateBTreeMap<K, V, M> is parametrized by the types:

  • K: Keys used in the map. Most operations on the map require this to implement Serialize. Keys cannot contain references to the low-level state, such as types containing StateBox, StateMap and StateSet.
  • V: Values stored in the map. Most operations on the map require this to implement Serial and DeserialWithState<StateApi>.
  • M: A const usize determining the minimum degree of the B-tree. Must be a value of 2 or above for the tree to work. This can be used to tweak the height of the tree vs size of each node in the tree. The default is set to 8, which seems to perform well on benchmarks. These benchmarks ran operations on a collection of 1000 elements, some using keys of 4 bytes others 16 bytes.

§Usage

New maps can be constructed using the new_btree_map method on the StateBuilder.

/// In an init method:
let mut map1 = state_builder.new_btree_map();

/// In a receive method:
let mut map2 = host.state_builder().new_btree_map();

§Caution

StateBTreeMaps must be explicitly deleted when they are no longer needed, otherwise they will remain in the contract’s state, albeit unreachable.

struct MyState {
    inner: StateBTreeMap<u64, u64>,
}
fn incorrect_replace(state_builder: &mut StateBuilder, state: &mut MyState) {
    // The following is incorrect. The old value of `inner` is not properly deleted.
    // from the state.
    state.inner = state_builder.new_btree_map(); // ⚠️
}

Instead, either the map should be cleared or explicitly deleted.

fn correct_replace(state_builder: &mut StateBuilder, state: &mut MyState) {
    state.inner.clear_flat();
}

Or alternatively

fn correct_replace(state_builder: &mut StateBuilder, state: &mut MyState) {
    let old_map = mem::replace(&mut state.inner, state_builder.new_btree_map());
    old_map.delete()
}

Implementations§

source§

impl<const M: usize, K, V> StateBTreeMap<K, V, M>

source

pub fn insert(&mut self, key: K, value: V) -> Option<V>

Insert a key-value pair into the map. Returns the previous value if the key was already in the map.

Caution: If Option<V> is to be deleted and contains a data structure prefixed with State (such as StateBox or StateMap), then it is important to call Deletable::delete on the value returned when you’re finished with it. Otherwise, it will remain in the contract state.

source

pub fn remove_and_get(&mut self, key: &K) -> Option<V>

Remove a key from the map, returning the value at the key if the key was previously in the map.

Caution: If V is a StateBox, StateMap, then it is important to call Deletable::delete on the value returned when you’re finished with it. Otherwise, it will remain in the contract state.

source

pub fn remove(&mut self, key: &K)

Remove a key from the map. This also deletes the value in the state.

source

pub fn get(&self, key: &K) -> Option<StateRef<'_, V>>

Get a reference to the value corresponding to the key.

source

pub fn get_mut(&mut self, key: &K) -> Option<StateRefMut<'_, V, StateApi>>

Get a mutable reference to the value corresponding to the key.

source

pub fn contains_key(&self, key: &K) -> bool
where K: Serialize + Ord,

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

source

pub fn higher(&self, key: &K) -> Option<StateRef<'_, K>>
where K: Serialize + Ord,

Returns the smallest key in the map that is strictly larger than the provided key. None meaning no such key is present in the map.

source

pub fn eq_or_higher(&self, key: &K) -> Option<StateRef<'_, K>>
where K: Serialize + Ord,

Returns the smallest key in the map that is equal or larger than the provided key. None meaning no such key is present in the map.

source

pub fn lower(&self, key: &K) -> Option<StateRef<'_, K>>
where K: Serialize + Ord,

Returns the largest key in the map that is strictly smaller than the provided key. None meaning no such key is present in the map.

source

pub fn eq_or_lower(&self, key: &K) -> Option<StateRef<'_, K>>
where K: Serialize + Ord,

Returns the largest key in the map that is equal or smaller than the provided key. None meaning no such key is present in the map.

source

pub fn first_key(&self) -> Option<StateRef<'_, K>>
where K: Serialize + Ord,

Returns a reference to the first key in the map, if any. This key is always the minimum of all keys in the map.

source

pub fn last_key(&self) -> Option<StateRef<'_, K>>
where K: Serialize + Ord,

Returns a reference to the last key in the map, if any. This key is always the maximum of all keys in the map.

source

pub fn len(&self) -> u32

Return the number of elements in the map.

source

pub fn is_empty(&self) -> bool

Returns true is the map contains no elements.

source

pub fn iter(&self) -> StateBTreeMapIter<'_, '_, K, V, M>

Create an iterator over the entries of StateBTreeMap. Ordered by K ascending.

source

pub fn clear(&mut self)

Clears the map, removing all key-value pairs. This also includes values pointed at, if V, for example, is a StateBox. If applicable use clear_flat instead.

source

pub fn clear_flat(&mut self)
where K: Serialize, V: Serialize,

Clears the map, removing all key-value pairs. This should be used over clear if it is applicable. It avoids recursive deletion of values since the values are required to be flat.

Unfortunately it is not possible to automatically choose between these implementations. Once Rust gets trait specialization then this might be possible.

Trait Implementations§

source§

impl<const M: usize, K, V> Deletable for StateBTreeMap<K, V, M>

source§

fn delete(self)

Delete all items that this type owns in the state.
source§

impl<const M: usize, K, V> DeserialWithState<ExternStateApi> for StateBTreeMap<K, V, M>

source§

fn deserial_with_state<R: Read>( state: &StateApi, source: &mut R ) -> ParseResult<Self>

Attempt to read a structure from a given source and state, failing if an error occurs during deserialization or reading.
source§

impl<K, V, const M: usize> Serial for StateBTreeMap<K, V, M>
where K: Serial, V: Serial,

source§

fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err>

Attempt to write the structure into the provided writer, failing if only part of the structure could be written. Read more

Auto Trait Implementations§

§

impl<K, V, const M: usize> Freeze for StateBTreeMap<K, V, M>

§

impl<K, V, const M: usize> RefUnwindSafe for StateBTreeMap<K, V, M>

§

impl<K, V, const M: usize> Send for StateBTreeMap<K, V, M>
where K: Send, V: Send,

§

impl<K, V, const M: usize> Sync for StateBTreeMap<K, V, M>
where K: Sync, V: Sync,

§

impl<K, V, const M: usize> Unpin for StateBTreeMap<K, V, M>
where K: Unpin, V: Unpin,

§

impl<K, V, const M: usize> UnwindSafe for StateBTreeMap<K, V, M>
where K: UnwindSafe, V: UnwindSafe,

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