mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: move helper methods from DatabaseProvider to DBProvider as defaults (#12367)
This commit is contained in:
@ -1,6 +1,14 @@
|
||||
use reth_db_api::{database::Database, transaction::DbTx};
|
||||
use reth_db_api::{
|
||||
common::KeyValue,
|
||||
cursor::DbCursorRO,
|
||||
database::Database,
|
||||
table::Table,
|
||||
transaction::{DbTx, DbTxMut},
|
||||
DatabaseError,
|
||||
};
|
||||
use reth_prune_types::PruneModes;
|
||||
use reth_storage_errors::provider::ProviderResult;
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
/// Database provider.
|
||||
pub trait DBProvider: Send + Sync + Sized + 'static {
|
||||
@ -34,6 +42,101 @@ pub trait DBProvider: Send + Sync + Sized + 'static {
|
||||
|
||||
/// Returns a reference to prune modes.
|
||||
fn prune_modes_ref(&self) -> &PruneModes;
|
||||
|
||||
/// Return full table as Vec
|
||||
fn table<T: Table>(&self) -> Result<Vec<KeyValue<T>>, DatabaseError>
|
||||
where
|
||||
T::Key: Default + Ord,
|
||||
{
|
||||
self.tx_ref()
|
||||
.cursor_read::<T>()?
|
||||
.walk(Some(T::Key::default()))?
|
||||
.collect::<Result<Vec<_>, DatabaseError>>()
|
||||
}
|
||||
|
||||
/// Return a list of entries from the table, based on the given range.
|
||||
#[inline]
|
||||
fn get<T: Table>(
|
||||
&self,
|
||||
range: impl RangeBounds<T::Key>,
|
||||
) -> Result<Vec<KeyValue<T>>, DatabaseError> {
|
||||
self.tx_ref().cursor_read::<T>()?.walk_range(range)?.collect::<Result<Vec<_>, _>>()
|
||||
}
|
||||
|
||||
/// Iterates over read only values in the given table and collects them into a vector.
|
||||
///
|
||||
/// Early-returns if the range is empty, without opening a cursor transaction.
|
||||
fn cursor_read_collect<T: Table<Key = u64>>(
|
||||
&self,
|
||||
range: impl RangeBounds<T::Key>,
|
||||
) -> ProviderResult<Vec<T::Value>> {
|
||||
let capacity = match range_size_hint(&range) {
|
||||
Some(0) | None => return Ok(Vec::new()),
|
||||
Some(capacity) => capacity,
|
||||
};
|
||||
let mut cursor = self.tx_ref().cursor_read::<T>()?;
|
||||
self.cursor_collect_with_capacity(&mut cursor, range, capacity)
|
||||
}
|
||||
|
||||
/// Iterates over read only values in the given table and collects them into a vector.
|
||||
fn cursor_collect<T: Table<Key = u64>>(
|
||||
&self,
|
||||
cursor: &mut impl DbCursorRO<T>,
|
||||
range: impl RangeBounds<T::Key>,
|
||||
) -> ProviderResult<Vec<T::Value>> {
|
||||
let capacity = range_size_hint(&range).unwrap_or(0);
|
||||
self.cursor_collect_with_capacity(cursor, range, capacity)
|
||||
}
|
||||
|
||||
/// Iterates over read only values in the given table and collects them into a vector with
|
||||
/// capacity.
|
||||
fn cursor_collect_with_capacity<T: Table<Key = u64>>(
|
||||
&self,
|
||||
cursor: &mut impl DbCursorRO<T>,
|
||||
range: impl RangeBounds<T::Key>,
|
||||
capacity: usize,
|
||||
) -> ProviderResult<Vec<T::Value>> {
|
||||
let mut items = Vec::with_capacity(capacity);
|
||||
for entry in cursor.walk_range(range)? {
|
||||
items.push(entry?.1);
|
||||
}
|
||||
Ok(items)
|
||||
}
|
||||
|
||||
/// Remove list of entries from the table. Returns the number of entries removed.
|
||||
#[inline]
|
||||
fn remove<T: Table>(&self, range: impl RangeBounds<T::Key>) -> Result<usize, DatabaseError>
|
||||
where
|
||||
Self::Tx: DbTxMut,
|
||||
{
|
||||
let mut entries = 0;
|
||||
let mut cursor_write = self.tx_ref().cursor_write::<T>()?;
|
||||
let mut walker = cursor_write.walk_range(range)?;
|
||||
while walker.next().transpose()?.is_some() {
|
||||
walker.delete_current()?;
|
||||
entries += 1;
|
||||
}
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
/// Return a list of entries from the table, and remove them, based on the given range.
|
||||
#[inline]
|
||||
fn take<T: Table>(
|
||||
&self,
|
||||
range: impl RangeBounds<T::Key>,
|
||||
) -> Result<Vec<KeyValue<T>>, DatabaseError>
|
||||
where
|
||||
Self::Tx: DbTxMut,
|
||||
{
|
||||
let mut cursor_write = self.tx_ref().cursor_write::<T>()?;
|
||||
let mut walker = cursor_write.walk_range(range)?;
|
||||
let mut items = Vec::new();
|
||||
while let Some(i) = walker.next().transpose()? {
|
||||
walker.delete_current()?;
|
||||
items.push(i)
|
||||
}
|
||||
Ok(items)
|
||||
}
|
||||
}
|
||||
|
||||
/// Database provider factory.
|
||||
@ -54,3 +157,17 @@ pub trait DatabaseProviderFactory: Send + Sync {
|
||||
/// Create new read-write database provider.
|
||||
fn database_provider_rw(&self) -> ProviderResult<Self::ProviderRW>;
|
||||
}
|
||||
|
||||
fn range_size_hint(range: &impl RangeBounds<u64>) -> Option<usize> {
|
||||
let start = match range.start_bound().cloned() {
|
||||
Bound::Included(start) => start,
|
||||
Bound::Excluded(start) => start.checked_add(1)?,
|
||||
Bound::Unbounded => 0,
|
||||
};
|
||||
let end = match range.end_bound().cloned() {
|
||||
Bound::Included(end) => end.saturating_add(1),
|
||||
Bound::Excluded(end) => end,
|
||||
Bound::Unbounded => return None,
|
||||
};
|
||||
end.checked_sub(start).map(|x| x as _)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user