The Rust framework provides various storage mappers you can use. Deciding which one to use for every situation is critical for performance. There will be a comparison section after each mapper is described.
Note: All the storage mappers support additional key arguments.
General purpose mappers
SingleValueMapper
Stores a single value. Examples:
fn single_value(&self) -> SingleValueMapper<Type>;
fn single_value_with_single_key_arg(&self, key_arg: Type1) -> SingleValueMapper<Type2>;
fn single_value_with_multi_key_arg(&self, key_arg1: Type1, key_arg2: Type2) -> SingleValueMapper<Type3>;
Keep in mind there is no way of iterating over all key_args, so if you need to do that, consider using another mapper.
Available methods:
get
fn get() -> Type
Reads the value from storage and deserializes it to the given Type. For numerical types and vector types, this will return the default value for empty storage, i.e. 0 and empty vec respectively. For custom structs, this will signal an error if trying to read from empty storage.
set
fn set(value: &Type)
Sets the stored value to the provided value argument. For base Rust numerical types, the reference is not needed.
is_empty
fn is_empty() -> bool
Returns true is the storage entry is empty. Usually used when storing struct types to prevent crashes on get().
set_if_empty
fn set_if_empty(value: &Type)
Sets the value only if the storage for that value is currently empty. Usually used in #init functions to not overwrite values on contract upgrade.
clear
fn clear()
Clears the entry.
update
fn update<R, F: FnOnce(&mut Type) -> R>(f: F) -> R
Takes a closure as argument, applies that closure to the currently stored value, saves the new value, and returns any value the given closure might return. Examples:
Incrementing a value:
fn my_value(&self) -> SingleValueMapper<BigUint>;
self.my_value().update(|val| *val += 1);
Modifying a struct's field:
pub struct MyStruct {
pub field_1: u64,
pub field_2: u32
}
fn my_value(&self) -> SingleValueMapper<MyStruct>;
self.my_value().update(|val| val.field1 = 5);
Returning a value from the closure:
fn my_value(&self) -> SingleValueMapper<BigUint>;
let new_val = self.my_value().update(|val| {
*val += 1;
*val
});
raw_byte_length
fn raw_byte_length() -> usize
Returns the raw byte length of the stored value. This should be rarely used.
VecMapper
Stores elements of the same type, each under their own storage key. Allows access by index for said items. Keep in mind indexes start at 1 for VecMapper. Examples:
fn my_vec(&self) -> VecMapper<Type>;
fn my_vec_with_args(&self, arg: Type1) -> VecMapper<Type2>;
Available methods:
push
fn push(elem: &T)
Stores the element at index len and increments len afterwards.
get
fn get(index: usize) -> Type
Gets the element at the specific index. Valid indexes are 1 to len, both ends included. Attempting to read from an invalid index will signal an error.
set
fn set(index: usize, value: &Type)
Sets the element at the given index. Index must be in inclusive range 1 to len.
clear_entry
fn clear_entry(index: usize)
Clears the entry at the given index. This does not decrease the length.
is_empty
fn is_empty() -> bool
Returns true if the mapper has no elements stored.
len
fn len() -> usize
Returns the number of items stored in the mapper.
extend_from_slice
fn extend_from_slice(slice: &[Type])
Pushes all elements from the given slice at the end of the mapper. More efficient than manual for of push, as the internal length is only read and updated once.
swap_remove
fn swap_remove(index: usize)
Removes the element at index, moves the last element to index and decreases the len by 1. There is no way of removing an element and preserving the order.
clear
fn clear()
Clears all the elements from the mapper. This function can run out of gas for big collections.
iter
fn iter() -> Iter<Type>
Provides an iterator over all the elements.
SetMapper
Stores a set of values, with no duplicates being allowed. It also provides methods for checking if a value already exists in the set. Values order is given by their order of insertion.
Unless you need to maintain the order of the elements, consider using UnorderedSetMapper or WhitelistMapper instead, as they're more efficient.
Examples:
fn my_set(&self) -> SetMapper<Type>;
Available methods:
insert
fn insert(value: Type) -> bool
Insers the value into the set. Returns false if the item was already present.
remove
fn remove(value: &Type)
Removes the value from the set. Returns false if the set did not contain the value.
contains
fn contains(value: &Type) -> bool
Returns true if the mapper contains the given value.
is_empty
fn is_empty() -> bool
Returns true if the mapper has no elements stored.
len
fn len() -> usize
Returns the number of items stored in the mapper.
clear
fn clear()
Clears all the elements from the mapper. This function can run out of gas for big collections.
iter
fn iter() -> Iter<Type>
Returns an iterator over all the stored elements.
UnorderedSetMapper
Same as SetMapper, but does not guarantee the order of the items. More efficient than SetMapper, and should be used instead unless you need to maintain the order. Internally, UnorderedSetMapper uses a VecMapper to store the elements, and additionally, it stores each element's index to provide O(1) contains.
Examples:
fn my_set(&self) -> UnorderedSetMapper<Type>;
Available methods:
UnorderedSetMapper contains the same methods as SetMapper, the only difference being item removal. Instead of remove, we only have swap_remove available.
swap_remove
fn swap_remove(value: &Type) -> bool
Uses the internal VecMapper's swap_remove method to remove the element. Additionally, it overwrites the last element's stored index with the removed value's index. Returns false if the element was not present in the set.
WhitelistMapper
Stores a whitelist of items. Does not provide any means of iterating over the elements, so if you need to iterate over the elements, use UnorderedSetMapper instead. Internally, this mapper simply stores a flag in storage for each item if they're whitelisted.
Examples:
fn my_whitelist(&self) -> WhitelistMapper<Type>
Available methods:
add
fn add(value: &Type)
Adds the value to the whitelist.
remove
fn remove(value: &Type)
Removes the value from the whitelist.
contains
fn contains(value: &Type) -> bool
Returns true if the mapper contains the given value.
require_whitelisted
fn require_whitelisted(value: &Type)
Will signal an error if the item is not whitelisted. Does nothing otherwise.
LinkedListMapper
Stores a linked list, which allows fast insertion/removal of elements, as well as possibility to iterate over the whole list.
Examples:
fn my_linked_list(&self) -> LinkedListMapper<Type>
Available methods:
is_empty
fn is_empty() -> bool
Returns true if the mapper has no elements stored.
len
fn len() -> usize
Returns the number of items stored in the mapper.
clear
fn clear()
Clears all the elements from the mapper. This function can run out of gas for big collections.