LLFIO
v2.00
|
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< void > | dependencies (span< key_type > keys) noexcept=0 |
Indicate that there is a dependency on the snapshotted values of these keys without fetching any values. | |
virtual result< void > | commit () noexcept=0 |
Try to commit this transaction, failing if any dependencies have been updated. | |
virtual result< uri_type > | uri () 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_type > | max_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_type > | size () const noexcept=0 |
Returns the current number of key-values currently in the store. | |
virtual result< capacity_type > | max_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_type > | bytes_stored () const noexcept=0 |
Returns the current number of bytes stored. | |
virtual result< extent_type > | max_value_size () const noexcept=0 |
Returns the maximum value size in bytes supported by this store. | |
allocator_type & | allocator () noexcept |
Access the allocator used for this store. | |
const allocator_type & | allocator () 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_type > | open (key_type key, mode _mode=mode::read) noexcept=0 |
virtual io_result< buffers_type > | read (io_request< buffers_type > reqs, key_type key, llfio::deadline d=llfio::deadline()) noexcept=0 |
virtual io_result< const_buffers_type > | write (key_type key, io_request< const_buffers_type > reqs, llfio::deadline d=llfio::deadline()) noexcept=0 |
virtual result< basic_key_value_store > | snapshot () noexcept=0 |
virtual result< transaction > | begin_transaction () noexcept=0 |
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 {} |
|
pure virtualnoexceptinherited |
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
.
|
pure virtualnoexceptinherited |
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.
|
pure virtualnoexceptinherited |
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.
|
pure virtualnoexceptinherited |
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.
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.
|
pure virtualnoexceptinherited |
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.
|
pure virtualnoexceptinherited |
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
.
|
pure virtualnoexceptinherited |
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.
|
pure virtualnoexceptinherited |
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.