LLFIO  v2.00
kvstore_v1_xxx::basic_key_value_store Class Referenceabstract

A possibly hardware-implemented basic key-value store. More...

#include "kvstore.hpp"

Inheritance diagram for kvstore_v1_xxx::basic_key_value_store:
kvstore_v1_xxx::basic_key_value_store::transaction

Classes

class  transaction
 

Public Types

using key_type = span< const byte >
 The key type of this store.
 
using value_type = span< byte >
 The value type of this store.
 
using uri_type = basic_key_value_store_info::uri_type
 The type of the UTF-8 URI used by this store.
 
using capacity_type = QUICKCPPLIB_NAMESPACE::integers128::uint128
 The device extent type used by this store.
 
using extent_type = llfio::file_handle::extent_type
 The value extent type used by this store.
 
using size_type = llfio::file_handle::size_type
 The memory extent type used by this store.
 
using allocator_type = QUICKCPPLIB_NAMESPACE::pmr::polymorphic_allocator< byte >
 The allocator type used by this store.
 
using handle_type = llfio::file_handle
 The handle type used by this store.
 
using mode = handle_type::mode
 The mode used by this store.
 
using creation = handle_type::creation
 The creation used by this store.
 
using caching = handle_type::caching
 The kernel caching used by this store.
 
using buffer_type = handle_type::buffer_type
 The buffer type used by this store.
 
using const_buffer_type = handle_type::const_buffer_type
 The const buffer type used by this store.
 
using buffers_type = handle_type::buffers_type
 The buffers type used by this store.
 
using const_buffers_type = handle_type::const_buffers_type
 The const buffers type used by this store.
 
template<class T >
using io_request = handle_type::io_request< T >
 The i/o request type used by this store.
 
template<class T >
using io_result = handle_type::io_result< T >
 The i/o result type used by this store.
 
using features = struct basic_key_value_store_info::features
 Features requested, or provided by, this store.
 
using filter_state_type = uint64_t
 The state type for performing a filtered match.
 

Public Member Functions

virtual result< uri_typeuri () noexcept=0
 
size_type key_size () const noexcept
 Returns the number of bytes in the key for this store.
 
size_type value_size () const noexcept
 Returns the number of bytes in the value for this store. Zero means variably sized.
 
bool frozen () const
 True if the keys and values sizes are immutable, and only values may be changed.
 
virtual bool empty () const noexcept=0
 True if the store is currently empty.
 
virtual result< capacity_typemax_size () const noexcept=0
 Returns the maximum number of key-values which could be potentially stored (estimated if using variably sized values).
 
virtual result< void > max_size (capacity_type quota) noexcept=0
 Sets the maximum number of key-values which could be potentially stored.
 
virtual result< capacity_typesize () const noexcept=0
 Returns the current number of key-values currently in the store.
 
virtual result< capacity_typemax_bytes_stored () const noexcept=0
 Returns the maximum number of bytes which could be potentially stored.
 
virtual result< void > max_bytes_stored (capacity_type quota) noexcept=0
 Sets the maximum number of bytes which could be potentially stored.
 
virtual result< capacity_typebytes_stored () const noexcept=0
 Returns the current number of bytes stored.
 
virtual result< extent_typemax_value_size () const noexcept=0
 Returns the maximum value size in bytes supported by this store.
 
allocator_typeallocator () noexcept
 Access the allocator used for this store.
 
const allocator_typeallocator () const noexcept
 Access the allocator used for this store.
 
size_type key_index_size () const noexcept
 Retrieves any MSB key index size, in bytes.
 
virtual result< void > key_index_size (size_type bytes) noexcept=0
 
virtual result< void > clear () noexcept=0
 Clears the store, possibly more quickly than deleting every key. This call may be racy.
 
virtual result< void > match (filter_state_type &state, key_type mask={}, key_type bits={}) noexcept=0
 
virtual result< handle_typeopen (key_type key, mode _mode=mode::read) noexcept=0
 
virtual io_result< buffers_typeread (io_request< buffers_type > reqs, key_type key, llfio::deadline d=llfio::deadline()) noexcept=0
 
virtual io_result< const_buffers_typewrite (key_type key, io_request< const_buffers_type > reqs, llfio::deadline d=llfio::deadline()) noexcept=0
 
virtual result< basic_key_value_storesnapshot () noexcept=0
 
virtual result< transactionbegin_transaction () noexcept=0
 

Protected Member Functions

 basic_key_value_store (const basic_key_value_store &)=delete
 
basic_key_value_storeoperator= (const basic_key_value_store &)=delete
 
 basic_key_value_store (basic_key_value_store &&o) noexcept=default
 Move constructor.
 
basic_key_value_storeoperator= (basic_key_value_store &&o) noexcept=default
 Move assignment.
 

Protected Attributes

uri_type _uri {}
 
bool _frozen {false}
 
size_type _key_size {0}
 
size_type _value_size {0}
 
size_type _key_index_size {0}
 
capacity_type _items_quota {0}
 
capacity_type _bytes_quota {0}
 
allocator_type _allocator {}
 

Detailed Description

A possibly hardware-implemented basic key-value store.

Warning
This class has not been implemented nor will be any time soon. It is here for various folk to study the API design.

Reference document https://www.snia.org/sites/default/files/technical_work/PublicReview/KV%20Storage%20API%200.16.pdf

Member Function Documentation

◆ begin_transaction()

virtual result<transaction> kvstore_v1_xxx::basic_key_value_store::begin_transaction ( )
pure virtualnoexcept

Begin a transaction on this key value store.

Transactions are a superset of snapshots in that they also allow the modification of multiple items in a store in an atomic, all-or-nothing, operation. Reading values marks that item as a dependency i.e. if that item's value is updated between the moment of opening the transaction and committing the transaction, the transaction will abort. You can mark values as dependencies without actually reading them using dependencies().

If a store implementation does not implement features::atomic_transactions, this function returns an error code comparing equal to errc::operation_not_supported.

◆ key_index_size()

virtual result<void> kvstore_v1_xxx::basic_key_value_store::key_index_size ( size_type  bytes)
pure virtualnoexcept

Sets a MSB key index size, in bytes. Some store implementations may only permit this if the store is empty. Setting a MSB key index causes filtering and search operations based on the key index to be constant rather than linear time.

◆ match()

virtual result<void> kvstore_v1_xxx::basic_key_value_store::match ( filter_state_type state,
key_type  mask = {},
key_type  bits = {} 
)
pure virtualnoexcept

Returns the first or next key in the store matching the given filter. This call is racy, and filter processing may take as much time as iterating the entire contents of the store unless the mask exactly matches any key index, in which case it shall be constant time. Note that some hardware devices perform filter matching on-device, which does not change the algorithmic complexity, but may benefit from greatly increased on-device bandwidth.

To begin a match, pass a default initialised filter_state_type. An error matching errc::no_such_file_or_directory will be returned if no more keys match. The default initialised mask and bits causes matching of all keys in the store.

◆ open()

virtual result<handle_type> kvstore_v1_xxx::basic_key_value_store::open ( key_type  key,
mode  _mode = mode::read 
)
pure virtualnoexcept

Returns a handle type which gives access to a key's value. The lifetime of the returned handle may pin the key's value at the time of retrieval if this store has features::stable_values.

This function avoids reading any of the value where possible. It may internally use memory maps, and thus return scatter buffers to elsewhere memory, same as llfio::mapped_file_handle.

The ability to open a value for write access depends on the lack of features::stable_values, or presence of features::update_deltas. Stable values without update deltas will not permit the value to be opened for write access.

This call is not racy with respect to its value if features::stable_values. Individual key opens are racy with respect to one another i.e. other threads or processes may modify values concurrently, thus causing a sequence of key opens to refer to disjoint moments in time. Use snapshot if you don't want this.

Note
The handle type returned implements llfio::file_handle, but may be a lightweight synthetic handle with no kernel resources backing it. In particular, not all operations may be implemented e.g. byte range locks.

◆ read()

virtual io_result<buffers_type> kvstore_v1_xxx::basic_key_value_store::read ( io_request< buffers_type reqs,
key_type  key,
llfio::deadline  d = llfio::deadline() 
)
pure virtualnoexcept

Scatter reads some or all of a key's value into the supplied buffers, possibly returning completely different buffers to memory elsewhere similar to llfio::mapped_file_handle.

This call may be more efficient than open(), or it may be implemented entirely in terms of open(). This call is unavoidably racy, and it may read different values for a key each time it is called.

◆ snapshot()

virtual result<basic_key_value_store> kvstore_v1_xxx::basic_key_value_store::snapshot ( )
pure virtualnoexcept

Returns a snapshot of the key store's values at a single moment in time i.e. all the values appear as-if in a single moment of time with no changes appearing to values after the snapshot. In this sense, the snapshot is atomic. Values snapshotted are pinned to the moment of the snapshot.

Some store implementations do not implement both features::stable_values and features::stable_keys, if so then creating a snapshot must read all the values for all the keys during snapshot creation (which can be more efficient than reading each key-value at a time). Otherwise values are not read, rather a note is taken of their current state, and values are only fetched on demand.

Some store implementations do not implement features::stable_keys, if so a snapshot's list of keys may be affected by subsequent changes to the main store. In other words, the keys in a snapshot may match those of the main store, only the values for what keys are not deleted in the main store remain pinned.

Note that if a store does not have features::history, one may find that retrieving a value from a snapshot may no longer be able to retrieve that value as it has since been replaced. In this situation you will receive an error matching errc::no_such_file_or_directory.

It is never possible to read a value from a snapshot and get an updated value instead of the snapshotted value. This is why not all stores implement features::snapshot, as a store must implement some mechanism of knowing when a value has been updated since it was pinned.

If a store implementation does not implement features::atomic_snapshot, this function returns an error code comparing equal to errc::operation_not_supported.

◆ uri()

virtual result<uri_type> kvstore_v1_xxx::basic_key_value_store::uri ( )
pure virtualnoexcept

Fetch the URI for this store. Note that if features::shared_memory, this will freeze the keys and value sizes in place from henceforth onwards. Only the values will be mutable.

◆ write()

virtual io_result<const_buffers_type> kvstore_v1_xxx::basic_key_value_store::write ( key_type  key,
io_request< const_buffers_type reqs,
llfio::deadline  d = llfio::deadline() 
)
pure virtualnoexcept

Gather writes some or all of a key's value from the supplied buffers, returning buffers written. For stores with features::stable_values but without features::update_deltas, the offset must be zero, and the gather list is assumed to reflect the whole of the value to be written.

This call may be more efficient than open(), or it may be implemented entirely in terms of open(). This call is unavoidably racy, and it may write into different values for a key each time it is called.


The documentation for this class was generated from the following file: