pub struct CachedDbAccess<TKey, TData, S = RandomState, TLegacy = TData>{ /* private fields */ }Expand description
A concurrent DB store access with typed caching.
§Versioned stores
CachedDbAccess supports an opt-in “versioned key” mode used by stores
whose on-disk value layout changed across a hardfork (currently only
DbUtxoDiffsStore across Toccata). A version-aware store is constructed
with CachedDbAccess::new_with_version_suffix.
When a version suffix is configured, every write appends that byte to the
DB key and every read uses a rocksdb::PrefixRange scan on
[store_prefix || logical_key] so pre-fork (unversioned) and post-fork
(versioned) rows can coexist on disk under the same logical key. Legacy
rows decode through a caller-provided shadow type TLegacy and are
converted into the live TData via TLegacy: Into<TData>. When
version_suffix is None (the default for every existing store) each
method falls through to the pre-fork point-get path unchanged — zero
functional impact on non-versioned stores.
The TLegacy generic defaults to TData, so existing callers that spell
only two or three type parameters (TKey, TData[, S]) continue to
compile unchanged: TData: Into<TData> is supplied by the blanket
impl<T> From<T> for T.
Implementations§
Source§impl<TKey, TData, S, TLegacy> CachedDbAccess<TKey, TData, S, TLegacy>
impl<TKey, TData, S, TLegacy> CachedDbAccess<TKey, TData, S, TLegacy>
pub fn new(db: Arc<DB>, cache_policy: CachePolicy, prefix: Vec<u8>) -> Self
Sourcepub fn new_with_version_suffix(
db: Arc<DB>,
cache_policy: CachePolicy,
prefix: Vec<u8>,
version_suffix: u8,
) -> Self
pub fn new_with_version_suffix( db: Arc<DB>, cache_policy: CachePolicy, prefix: Vec<u8>, version_suffix: u8, ) -> Self
Constructs a version-aware store. Writes append version_suffix to
every DB key. Reads use a rocksdb::PrefixRange scan on
[store_prefix || logical_key] and dispatch on the tail byte:
- no tail byte → legacy (pre-fork) row, decoded as
TLegacyand converted intoTDataviaTLegacy: Into<TData>; - tail byte ==
version_suffix→ current row, decoded directly asTData; - any other tail →
StoreError::DataInconsistency.
The caller is responsible for picking a TLegacy type whose derived
Deserialize matches the pre-fork byte layout, and for providing a
From<TLegacy> for TData conversion. See
consensus/core/src/utxo/pre_toccata.rs for the current example.
pub fn read_from_cache(&self, key: TKey) -> Option<TData>
pub fn has(&self, key: TKey) -> Result<bool, StoreError>
pub fn read(&self, key: TKey) -> Result<TData, StoreError>where
TKey: Clone + AsRef<[u8]> + ToString,
TData: DeserializeOwned,
TLegacy: DeserializeOwned + Into<TData>,
Sourcepub fn has_with_fallback(
&self,
fallback_prefix: &[u8],
key: TKey,
) -> Result<bool, StoreError>
pub fn has_with_fallback( &self, fallback_prefix: &[u8], key: TKey, ) -> Result<bool, StoreError>
Probes the live prefix first and falls back to fallback_prefix for legacy
rows. Used to access a store whose key prefix changed across releases —
readers transparently see both old and new locations during the migration
window.
Note: has_with_fallback and Self::read_with_fallback are the
prefix-migration helpers, orthogonal to the version-suffix mechanism.
They are not aware of version_suffix and are not intended to be
combined with a versioned store; use Self::has / Self::read
for versioned reads.
Sourcepub fn read_with_fallback<TFallbackDeser>(
&self,
fallback_prefix: &[u8],
key: TKey,
) -> Result<TData, StoreError>where
TKey: Clone + AsRef<[u8]> + ToString,
TData: DeserializeOwned,
TFallbackDeser: DeserializeOwned + Into<TData>,
pub fn read_with_fallback<TFallbackDeser>(
&self,
fallback_prefix: &[u8],
key: TKey,
) -> Result<TData, StoreError>where
TKey: Clone + AsRef<[u8]> + ToString,
TData: DeserializeOwned,
TFallbackDeser: DeserializeOwned + Into<TData>,
See Self::has_with_fallback for the note on interaction with
versioned stores.
Sourcepub fn iterator(
&self,
) -> impl Iterator<Item = Result<(Box<[u8]>, TData), Box<dyn Error>>> + '_
pub fn iterator( &self, ) -> impl Iterator<Item = Result<(Box<[u8]>, TData), Box<dyn Error>>> + '_
Iterates every row in this store under the bare [store_prefix || *]
range. Not yet aware of versioned stores: on a version-aware
store this will emit logical keys that still carry the trailing
version suffix byte, and it does not dispatch legacy rows through
TLegacy. DbUtxoDiffsStore does not call this method; if a future
versioned store needs streaming iteration, this helper will have to
learn about version_suffix first.
pub fn write( &self, writer: impl DbWriter, key: TKey, data: TData, ) -> Result<(), StoreError>
pub fn write_many( &self, writer: impl DbWriter, iter: &mut (impl Iterator<Item = (TKey, TData)> + Clone), ) -> Result<(), StoreError>
Sourcepub fn write_many_without_cache(
&self,
writer: impl DbWriter,
iter: &mut impl Iterator<Item = (TKey, TData)>,
) -> Result<(), StoreError>
pub fn write_many_without_cache( &self, writer: impl DbWriter, iter: &mut impl Iterator<Item = (TKey, TData)>, ) -> Result<(), StoreError>
Write directly from an iterator and do not cache any data. NOTE: this action also clears the cache
pub fn delete(&self, writer: impl DbWriter, key: TKey) -> Result<(), StoreError>
pub fn delete_many( &self, writer: impl DbWriter, key_iter: &mut (impl Iterator<Item = TKey> + Clone), ) -> Result<(), StoreError>
Sourcepub fn delete_all(&self, writer: impl DbWriter) -> Result<(), StoreError>
pub fn delete_all(&self, writer: impl DbWriter) -> Result<(), StoreError>
Deletes all entries in the store using the underlying rocksdb delete_range operation
Sourcepub fn seek_iterator(
&self,
bucket: Option<&[u8]>,
seek_from: Option<TKey>,
limit: usize,
skip_first: bool,
) -> impl Iterator<Item = Result<(Box<[u8]>, TData), Box<dyn Error>>> + '_
pub fn seek_iterator( &self, bucket: Option<&[u8]>, seek_from: Option<TKey>, limit: usize, skip_first: bool, ) -> impl Iterator<Item = Result<(Box<[u8]>, TData), Box<dyn Error>>> + '_
A dynamic iterator that can iterate through a specific prefix / bucket, or from a certain start point.
Not yet aware of versioned stores — same caveat as Self::iterator.
pub fn prefix(&self) -> &[u8] ⓘ
Trait Implementations§
Auto Trait Implementations§
impl<TKey, TData, S = RandomState, TLegacy = TData> !RefUnwindSafe for CachedDbAccess<TKey, TData, S, TLegacy>
impl<TKey, TData, S = RandomState, TLegacy = TData> !UnwindSafe for CachedDbAccess<TKey, TData, S, TLegacy>
impl<TKey, TData, S, TLegacy> Freeze for CachedDbAccess<TKey, TData, S, TLegacy>
impl<TKey, TData, S, TLegacy> Send for CachedDbAccess<TKey, TData, S, TLegacy>
impl<TKey, TData, S, TLegacy> Sync for CachedDbAccess<TKey, TData, S, TLegacy>
impl<TKey, TData, S, TLegacy> Unpin for CachedDbAccess<TKey, TData, S, TLegacy>
impl<TKey, TData, S, TLegacy> UnsafeUnpin for CachedDbAccess<TKey, TData, S, TLegacy>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more