pub trait KVStore {
// Required methods
fn read(
&self,
primary_namespace: &str,
secondary_namespace: &str,
key: &str,
) -> AsyncResult<'static, Vec<u8>, Error>;
fn write(
&self,
primary_namespace: &str,
secondary_namespace: &str,
key: &str,
buf: Vec<u8>,
) -> AsyncResult<'static, (), Error>;
fn remove(
&self,
primary_namespace: &str,
secondary_namespace: &str,
key: &str,
lazy: bool,
) -> AsyncResult<'static, (), Error>;
fn list(
&self,
primary_namespace: &str,
secondary_namespace: &str,
) -> AsyncResult<'static, Vec<String>, Error>;
}Expand description
Provides an interface that allows storage and retrieval of persisted values that are associated with given keys.
In order to avoid collisions the key space is segmented based on the given primary_namespaces
and secondary_namespaces. Implementations of this trait are free to handle them in different
ways, as long as per-namespace key uniqueness is asserted.
Keys and namespaces are required to be valid ASCII strings in the range of
KVSTORE_NAMESPACE_KEY_ALPHABET and no longer than KVSTORE_NAMESPACE_KEY_MAX_LEN. Empty
primary namespaces and secondary namespaces ("") are assumed to be a valid, however, if
primary_namespace is empty, secondary_namespace is required to be empty, too. This means
that concerns should always be separated by primary namespace first, before secondary
namespaces are used. While the number of primary namespaces will be relatively small and is
determined at compile time, there may be many secondary namespaces per primary namespace. Note
that per-namespace uniqueness needs to also hold for keys and namespaces in any given
namespace, i.e., conflicts between keys and equally named
primary namespaces/secondary namespaces must be avoided.
Note: Users migrating custom persistence backends from the pre-v0.0.117 KVStorePersister
interface can use a concatenation of [{primary_namespace}/[{secondary_namespace}/]]{key} to
recover a key compatible with the data model previously assumed by KVStorePersister::persist.
For a synchronous version of this trait, see KVStoreSync.
This is not exported to bindings users as async is only supported in Rust.
Required Methods§
Sourcefn read(
&self,
primary_namespace: &str,
secondary_namespace: &str,
key: &str,
) -> AsyncResult<'static, Vec<u8>, Error>
fn read( &self, primary_namespace: &str, secondary_namespace: &str, key: &str, ) -> AsyncResult<'static, Vec<u8>, Error>
Returns the data stored for the given primary_namespace, secondary_namespace, and
key.
Returns an ErrorKind::NotFound if the given key could not be found in the given
primary_namespace and secondary_namespace.
Sourcefn write(
&self,
primary_namespace: &str,
secondary_namespace: &str,
key: &str,
buf: Vec<u8>,
) -> AsyncResult<'static, (), Error>
fn write( &self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: Vec<u8>, ) -> AsyncResult<'static, (), Error>
Persists the given data under the given key.
The order of multiple writes to the same key needs to be retained while persisting
asynchronously. In other words, if two writes to the same key occur, the state (as seen by
Self::read) must either see the first write then the second, or only ever the second,
no matter when the futures complete (and must always contain the second write once the
second future completes). The state should never contain the first write after the second
write’s future completes, nor should it contain the second write, then contain the first
write at any point thereafter (even if the second write’s future hasn’t yet completed).
One way to ensure this requirement is met is by assigning a version number to each write before returning the future, and then during asynchronous execution, ensuring that the writes are executed in the correct order.
Note that no ordering requirements exist for writes to different keys.
Will create the given primary_namespace and secondary_namespace if not already present in the store.
Sourcefn remove(
&self,
primary_namespace: &str,
secondary_namespace: &str,
key: &str,
lazy: bool,
) -> AsyncResult<'static, (), Error>
fn remove( &self, primary_namespace: &str, secondary_namespace: &str, key: &str, lazy: bool, ) -> AsyncResult<'static, (), Error>
Removes any data that had previously been persisted under the given key.
If the lazy flag is set to true, the backend implementation might choose to lazily
remove the given key at some point in time after the method returns, e.g., as part of an
eventual batch deletion of multiple keys. As a consequence, subsequent calls to
KVStoreSync::list might include the removed key until the changes are actually persisted.
Note that while setting the lazy flag reduces the I/O burden of multiple subsequent
remove calls, it also influences the atomicity guarantees as lazy removes could
potentially get lost on crash after the method returns. Therefore, this flag should only be
set for remove operations that can be safely replayed at a later time.
All removal operations must complete in a consistent total order with Self::writes
to the same key. Whether a removal operation is lazy or not, Self::write operations
to the same key which occur before a removal completes must cancel/overwrite the pending
removal.
Returns successfully if no data will be stored for the given primary_namespace,
secondary_namespace, and key, independently of whether it was present before its
invokation or not.
Sourcefn list(
&self,
primary_namespace: &str,
secondary_namespace: &str,
) -> AsyncResult<'static, Vec<String>, Error>
fn list( &self, primary_namespace: &str, secondary_namespace: &str, ) -> AsyncResult<'static, Vec<String>, Error>
Returns a list of keys that are stored under the given secondary_namespace in
primary_namespace.
Returns the keys in arbitrary order, so users requiring a particular order need to sort the
returned keys. Returns an empty list if primary_namespace or secondary_namespace is unknown.
Implementors§
impl<K: Deref> KVStore for KVStoreSyncWrapper<K>where
K::Target: KVStoreSync,
This is not exported to bindings users as async is only supported in Rust.