Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Have KeyIterator clone the prefix it receives
  • Loading branch information
koute committed Jan 16, 2023
commit c84d0263a0ba0294e571685de46e61960e3db9a1
42 changes: 27 additions & 15 deletions client/api/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,32 +303,44 @@ pub trait AuxStore {
}

/// An `Iterator` that iterates keys in a given block under a prefix.
pub struct KeyIterator<'a, State, Block> {
pub struct KeyIterator<State, Block> {
state: State,
child_storage: Option<ChildInfo>,
prefix: Option<&'a StorageKey>,
prefix: Option<StorageKey>,
current_key: Vec<u8>,
_phantom: PhantomData<Block>,
}

impl<'a, State, Block> KeyIterator<'a, State, Block> {
impl<State, Block> KeyIterator<State, Block> {
/// create a KeyIterator instance
pub fn new(state: State, prefix: Option<&'a StorageKey>, current_key: Vec<u8>) -> Self {
Self { state, child_storage: None, prefix, current_key, _phantom: PhantomData }
pub fn new(state: State, prefix: Option<&StorageKey>, current_key: Vec<u8>) -> Self {
Self {
state,
child_storage: None,
prefix: prefix.map(|prefix| prefix.clone()),
current_key,
_phantom: PhantomData,
}
}

/// Create a `KeyIterator` instance for a child storage.
pub fn new_child(
state: State,
child_info: ChildInfo,
prefix: Option<&'a StorageKey>,
prefix: Option<&StorageKey>,
current_key: Vec<u8>,
) -> Self {
Self { state, child_storage: Some(child_info), prefix, current_key, _phantom: PhantomData }
Self {
state,
child_storage: Some(child_info),
prefix: prefix.map(|prefix| prefix.clone()),
current_key,
_phantom: PhantomData,
}
}
}

impl<'a, State, Block> Iterator for KeyIterator<'a, State, Block>
impl<State, Block> Iterator for KeyIterator<State, Block>
where
Block: BlockT,
State: StateBackend<HashFor<Block>>,
Expand All @@ -344,7 +356,7 @@ where
.ok()
.flatten()?;
// this terminates the iterator the first time it fails.
if let Some(prefix) = self.prefix {
if let Some(ref prefix) = self.prefix {
if !next_key.starts_with(&prefix.0[..]) {
return None
}
Expand Down Expand Up @@ -387,12 +399,12 @@ pub trait StorageProvider<Block: BlockT, B: Backend<Block>> {

/// Given a block's `Hash` and a key prefix, return a `KeyIterator` iterates matching storage
/// keys in that block.
fn storage_keys_iter<'a>(
fn storage_keys_iter(
&self,
hash: Block::Hash,
prefix: Option<&'a StorageKey>,
prefix: Option<&StorageKey>,
start_key: Option<&StorageKey>,
) -> sp_blockchain::Result<KeyIterator<'a, B::State, Block>>;
) -> sp_blockchain::Result<KeyIterator<B::State, Block>>;

/// Given a block's `Hash`, a key and a child storage key, return the value under the key in
/// that block.
Expand All @@ -414,13 +426,13 @@ pub trait StorageProvider<Block: BlockT, B: Backend<Block>> {

/// Given a block's `Hash` and a key `prefix` and a child storage key,
/// return a `KeyIterator` that iterates matching storage keys in that block.
fn child_storage_keys_iter<'a>(
fn child_storage_keys_iter(
&self,
hash: Block::Hash,
child_info: ChildInfo,
prefix: Option<&'a StorageKey>,
prefix: Option<&StorageKey>,
start_key: Option<&StorageKey>,
) -> sp_blockchain::Result<KeyIterator<'a, B::State, Block>>;
) -> sp_blockchain::Result<KeyIterator<B::State, Block>>;

/// Given a block's `Hash`, a key and a child storage key, return the hash under the key in that
/// block.
Expand Down
12 changes: 6 additions & 6 deletions client/service/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1432,24 +1432,24 @@ where
Ok(keys)
}

fn storage_keys_iter<'a>(
fn storage_keys_iter(
&self,
hash: <Block as BlockT>::Hash,
prefix: Option<&'a StorageKey>,
prefix: Option<&StorageKey>,
start_key: Option<&StorageKey>,
) -> sp_blockchain::Result<KeyIterator<'a, B::State, Block>> {
) -> sp_blockchain::Result<KeyIterator<B::State, Block>> {
let state = self.state_at(hash)?;
let start_key = start_key.or(prefix).map(|key| key.0.clone()).unwrap_or_else(Vec::new);
Ok(KeyIterator::new(state, prefix, start_key))
}

fn child_storage_keys_iter<'a>(
fn child_storage_keys_iter(
&self,
hash: <Block as BlockT>::Hash,
child_info: ChildInfo,
prefix: Option<&'a StorageKey>,
prefix: Option<&StorageKey>,
start_key: Option<&StorageKey>,
) -> sp_blockchain::Result<KeyIterator<'a, B::State, Block>> {
) -> sp_blockchain::Result<KeyIterator<B::State, Block>> {
let state = self.state_at(hash)?;
let start_key = start_key.or(prefix).map(|key| key.0.clone()).unwrap_or_else(Vec::new);
Ok(KeyIterator::new_child(state, child_info, prefix, start_key))
Expand Down