Skip to content

Commit

Permalink
feat: Use boxed iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
netrome committed Oct 25, 2024
1 parent c05459e commit f9e0289
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl DatabaseMessages for OnChainIterableKeyValueView {
&'a self,
ids: BoxedIter<'a, &'a Nonce>,
) -> BoxedIter<'a, StorageResult<Message>> {
self.get_batch(ids)
<Self as StorageBatchInspect<Messages>>::get_batch(self, ids)
.map(|result| result.and_then(|opt| opt.ok_or(not_found!(Messages))))
.into_boxed()
}
Expand Down
2 changes: 2 additions & 0 deletions crates/fuel-core/src/state/data_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ where
impl<Description, Stage> KeyValueInspect for DataSource<Description, Stage>
where
Description: DatabaseDescription,
Stage: Send + Sync,
{
type Column = Description::Column;

Expand Down Expand Up @@ -76,6 +77,7 @@ where
impl<Description, Stage> IterableStore for DataSource<Description, Stage>
where
Description: DatabaseDescription,
Stage: Send + Sync,
{
fn iter_store(
&self,
Expand Down
5 changes: 2 additions & 3 deletions crates/fuel-core/src/state/generic_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,8 @@ where
{
fn get_batch<'a>(
&'a self,
keys: Box<dyn Iterator<Item = &'a <M as Mappable>::Key> + 'a>,
) -> Box<dyn Iterator<Item = StorageResult<Option<<M as Mappable>::OwnedValue>>> + 'a>
{
keys: BoxedIter<'a, &'a M::Key>,
) -> BoxedIter<'a, StorageResult<Option<<M as Mappable>::OwnedValue>>> {
self.storage.get_batch(keys)
}
}
Expand Down
12 changes: 5 additions & 7 deletions crates/fuel-core/src/state/rocks_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -724,16 +724,15 @@ where

fn get_multi<'a>(
&'a self,
keys: Box<dyn Iterator<Item = Vec<u8>> + 'a>,
keys: BoxedIter<'a, Vec<u8>>,
column: Self::Column,
) -> Box<dyn Iterator<Item = StorageResult<Option<Value>>> + 'a> {
) -> BoxedIter<'a, StorageResult<Option<Value>>> {
// TODO: Metrics

let column = self.cf(column);
let keys = keys.map(|key| (&column, key));

let values = self
.db
self.db
.multi_get_cf_opt(keys, &self.read_options)
.into_iter()
.map(|value_opt| {
Expand All @@ -742,9 +741,8 @@ where
StorageError::Other(DatabaseError::Other(e.into()).into())
})
.map(|value| value.map(Arc::new))
});

Box::new(values)
})
.into_boxed()
}

fn read(
Expand Down
36 changes: 20 additions & 16 deletions crates/storage/src/blueprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ use crate::{
Encode,
Encoder,
},
iter::{
BoxedIter,
IntoBoxedIter,
},
kv_store::{
BatchOperations,
KeyValueInspect,
Expand All @@ -19,9 +23,6 @@ use crate::{
};
use fuel_vm_private::prelude::MerkleRoot;

#[cfg(feature = "alloc")]
use alloc::boxed::Box;

pub mod merklized;
pub mod plain;
pub mod sparse;
Expand Down Expand Up @@ -82,22 +83,25 @@ where
/// Returns multiple values from the storage.
fn get_multi<'a>(
storage: &'a S,
keys: Box<dyn Iterator<Item = &'a M::Key> + 'a>,
keys: BoxedIter<'a, &'a M::Key>,
column: S::Column,
) -> Box<dyn Iterator<Item = StorageResult<Option<M::OwnedValue>>> + 'a> {
let keys = Box::new(
keys.map(|key| Self::KeyCodec::encode(&key).as_bytes().into_owned()),
);

Box::new(storage.get_multi(keys, column).map(|result| {
result.and_then(|opt| {
opt.map(|value| {
Self::ValueCodec::decode_from_value(value)
.map_err(crate::Error::Codec)
) -> BoxedIter<'a, StorageResult<Option<M::OwnedValue>>> {
let keys = keys
.map(|key| Self::KeyCodec::encode(&key).as_bytes().into_owned())
.into_boxed();

storage
.get_multi(keys, column)
.map(|result| {
result.and_then(|opt| {
opt.map(|value| {
Self::ValueCodec::decode_from_value(value)
.map_err(crate::Error::Codec)
})
.transpose()
})
.transpose()
})
}))
.into_boxed()
}
}

Expand Down
14 changes: 9 additions & 5 deletions crates/storage/src/kv_store.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//! The module provides plain abstract definition of the key-value store.

use crate::{
iter::{
BoxedIter,
IntoBoxedIter,
},
Error as StorageError,
Result as StorageResult,
};
Expand All @@ -26,7 +30,7 @@ pub type KVItem = StorageResult<(Key, Value)>;
pub type KeyItem = StorageResult<Key>;

/// A column of the storage.
pub trait StorageColumn: Copy + core::fmt::Debug {
pub trait StorageColumn: Copy + core::fmt::Debug + Send + Sync {
/// Returns the name of the column.
fn name(&self) -> String;

Expand All @@ -41,7 +45,7 @@ pub trait StorageColumn: Copy + core::fmt::Debug {

/// The definition of the key-value inspection store.
#[impl_tools::autoimpl(for<T: trait> &T, &mut T, Box<T>)]
pub trait KeyValueInspect {
pub trait KeyValueInspect: Send + Sync {
/// The type of the column.
type Column: StorageColumn;

Expand All @@ -65,10 +69,10 @@ pub trait KeyValueInspect {
/// Returns multiple values from the storage.
fn get_multi<'a>(
&'a self,
keys: Box<dyn Iterator<Item = Vec<u8>> + 'a>,
keys: BoxedIter<'a, Vec<u8>>,
column: Self::Column,
) -> Box<dyn Iterator<Item = StorageResult<Option<Value>>> + 'a> {
Box::new(keys.map(move |key| self.get(&key, column)))
) -> BoxedIter<'a, StorageResult<Option<Value>>> {
keys.map(move |key| self.get(&key, column)).into_boxed()
}

/// Reads the value from the storage into the `buf` and returns the number of read bytes.
Expand Down
5 changes: 3 additions & 2 deletions crates/storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ extern crate alloc;
use anyhow::anyhow;
use core::array::TryFromSliceError;
use fuel_core_types::services::executor::Error as ExecutorError;
use iter::BoxedIter;

#[cfg(feature = "alloc")]
use alloc::{
Expand Down Expand Up @@ -182,8 +183,8 @@ pub trait StorageBatchInspect<Type: Mappable> {
/// TODO
fn get_batch<'a>(
&'a self,
keys: Box<dyn Iterator<Item = &'a Type::Key> + 'a>,
) -> Box<dyn Iterator<Item = Result<Option<Type::OwnedValue>>> + 'a>;
keys: BoxedIter<'a, &'a Type::Key>,
) -> BoxedIter<'a, Result<Option<Type::OwnedValue>>>;
}

/// Creates `StorageError::NotFound` error with file and line information inside.
Expand Down
7 changes: 2 additions & 5 deletions crates/storage/src/structured_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ use alloc::{
fmt::Debug,
};

// TODO: Format
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;

Expand Down Expand Up @@ -281,8 +278,8 @@ where
{
fn get_batch<'a>(
&'a self,
keys: Box<dyn Iterator<Item = &'a M::Key> + 'a>,
) -> Box<dyn Iterator<Item = StorageResult<Option<M::OwnedValue>>> + 'a> {
keys: BoxedIter<'a, &'a M::Key>,
) -> BoxedIter<'a, StorageResult<Option<M::OwnedValue>>> {
M::Blueprint::get_multi(self, keys, M::column())
}
}
Expand Down

0 comments on commit f9e0289

Please sign in to comment.