Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Add methods to PrefixIterator to support iterating from a specific key #9313

Merged
18 commits merged into from
Jul 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion frame/support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ macro_rules! generate_storage_alias {
>;
}
};
($pallet:ident, $name:ident => NMap<$(($key:ty, $hasher:ty),)+ $value:ty>) => {
($pallet:ident, $name:ident => NMap<Key<$(($key:ty, $hasher:ty)),+>, $value:ty>) => {
$crate::paste::paste! {
$crate::generate_storage_alias!(@GENERATE_INSTANCE_STRUCT $pallet, $name);
type $name = $crate::storage::types::StorageNMap<
Expand Down
66 changes: 66 additions & 0 deletions frame/support/src/storage/generator/double_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,15 @@ where
}
}

fn iter_prefix_from(
k1: impl EncodeLike<K1>,
starting_raw_key: Vec<u8>,
) -> Self::PrefixIterator {
let mut iter = Self::iter_prefix(k1);
iter.set_last_raw_key(starting_raw_key);
iter
}
KiChjang marked this conversation as resolved.
Show resolved Hide resolved

fn iter_key_prefix(k1: impl EncodeLike<K1>) -> Self::PartialKeyIterator {
let prefix = G::storage_double_map_final_key1(k1);
Self::PartialKeyIterator {
Expand All @@ -382,6 +391,15 @@ where
}
}

fn iter_key_prefix_from(
k1: impl EncodeLike<K1>,
starting_raw_key: Vec<u8>,
) -> Self::PartialKeyIterator {
let mut iter = Self::iter_key_prefix(k1);
iter.set_last_raw_key(starting_raw_key);
iter
}

fn drain_prefix(k1: impl EncodeLike<K1>) -> Self::PrefixIterator {
let mut iterator = Self::iter_prefix(k1);
iterator.drain = true;
Expand All @@ -404,6 +422,12 @@ where
}
}

fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator {
let mut iter = Self::iter();
iter.set_last_raw_key(starting_raw_key);
iter
}

fn iter_keys() -> Self::FullKeyIterator {
let prefix = G::prefix_hash();
Self::FullKeyIterator {
Expand All @@ -420,6 +444,12 @@ where
}
}

fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::FullKeyIterator {
let mut iter = Self::iter_keys();
iter.set_last_raw_key(starting_raw_key);
iter
}

fn drain() -> Self::Iterator {
let mut iterator = Self::iter();
iterator.drain = true;
Expand Down Expand Up @@ -509,6 +539,42 @@ mod test_iterators {
prefix
}

#[test]
fn double_map_iter_from() {
sp_io::TestExternalities::default().execute_with(|| {
use crate::hash::Identity;
crate::generate_storage_alias!(
MyModule,
MyDoubleMap => DoubleMap<(u64, Identity), (u64, Identity), u64>
);

MyDoubleMap::insert(1, 10, 100);
MyDoubleMap::insert(1, 21, 201);
MyDoubleMap::insert(1, 31, 301);
MyDoubleMap::insert(1, 41, 401);
MyDoubleMap::insert(2, 20, 200);
MyDoubleMap::insert(3, 30, 300);
MyDoubleMap::insert(4, 40, 400);
MyDoubleMap::insert(5, 50, 500);

let starting_raw_key = MyDoubleMap::storage_double_map_final_key(1, 21);
let iter = MyDoubleMap::iter_key_prefix_from(1, starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![31, 41]);

let starting_raw_key = MyDoubleMap::storage_double_map_final_key(1, 31);
let iter = MyDoubleMap::iter_prefix_from(1, starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![(41, 401)]);

let starting_raw_key = MyDoubleMap::storage_double_map_final_key(2, 20);
let iter = MyDoubleMap::iter_keys_from(starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![(3, 30), (4, 40), (5, 50)]);

let starting_raw_key = MyDoubleMap::storage_double_map_final_key(3, 30);
let iter = MyDoubleMap::iter_from(starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![(4, 40, 400), (5, 50, 500)]);
});
}

#[test]
fn double_map_reversible_reversible_iteration() {
sp_io::TestExternalities::default().execute_with(|| {
Expand Down
36 changes: 36 additions & 0 deletions frame/support/src/storage/generator/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ where
}
}

/// Enumerate all elements in the map after a given key.
fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator {
let mut iter = Self::iter();
iter.set_last_raw_key(starting_raw_key);
iter
}

/// Enumerate all keys in the map.
fn iter_keys() -> Self::KeyIterator {
let prefix = G::prefix_hash();
Expand All @@ -167,6 +174,13 @@ where
}
}

/// Enumerate all keys in the map after a given key.
fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::KeyIterator {
let mut iter = Self::iter_keys();
iter.set_last_raw_key(starting_raw_key);
iter
}

/// Enumerate all elements in the map.
fn drain() -> Self::Iterator {
let mut iterator = Self::iter();
Expand Down Expand Up @@ -382,6 +396,28 @@ mod test_iterators {
prefix
}

#[test]
fn map_iter_from() {
sp_io::TestExternalities::default().execute_with(|| {
use crate::hash::Identity;
crate::generate_storage_alias!(MyModule, MyMap => Map<(u64, Identity), u64>);

MyMap::insert(1, 10);
MyMap::insert(2, 20);
MyMap::insert(3, 30);
MyMap::insert(4, 40);
MyMap::insert(5, 50);

let starting_raw_key = MyMap::storage_map_final_key(3);
let iter = MyMap::iter_from(starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![(4, 40), (5, 50)]);

let starting_raw_key = MyMap::storage_map_final_key(2);
let iter = MyMap::iter_keys_from(starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![3, 4, 5]);
});
}

#[test]
fn map_reversible_reversible_iteration() {
sp_io::TestExternalities::default().execute_with(|| {
Expand Down
2 changes: 1 addition & 1 deletion frame/support/src/storage/generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
//! This is internal api and is subject to change.

mod double_map;
mod map;
pub(crate) mod map;
mod nmap;
mod value;

Expand Down
80 changes: 76 additions & 4 deletions frame/support/src/storage/generator/nmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,18 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
}
}

fn iter_prefix_from<KP>(
kp: KP,
starting_raw_key: Vec<u8>,
) -> PrefixIterator<(<K as HasKeyPrefix<KP>>::Suffix, V)>
where
K: HasReversibleKeyPrefix<KP>,
{
let mut iter = Self::iter_prefix(kp);
iter.set_last_raw_key(starting_raw_key);
iter
}

fn iter_key_prefix<KP>(kp: KP) -> KeyPrefixIterator<<K as HasKeyPrefix<KP>>::Suffix>
where
K: HasReversibleKeyPrefix<KP>,
Expand All @@ -342,6 +354,18 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
}
}

fn iter_key_prefix_from<KP>(
kp: KP,
starting_raw_key: Vec<u8>,
) -> KeyPrefixIterator<<K as HasKeyPrefix<KP>>::Suffix>
where
K: HasReversibleKeyPrefix<KP>,
{
let mut iter = Self::iter_key_prefix(kp);
iter.set_last_raw_key(starting_raw_key);
iter
}

fn drain_prefix<KP>(kp: KP) -> PrefixIterator<(<K as HasKeyPrefix<KP>>::Suffix, V)>
where
K: HasReversibleKeyPrefix<KP>,
Expand All @@ -352,10 +376,14 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
}

fn iter() -> Self::Iterator {
Self::iter_from(G::prefix_hash())
}

fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator {
let prefix = G::prefix_hash();
Self::Iterator {
prefix: prefix.clone(),
previous_key: prefix,
prefix,
previous_key: starting_raw_key,
drain: false,
closure: |raw_key_without_prefix, mut raw_value| {
let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?;
Expand All @@ -365,10 +393,14 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
}

fn iter_keys() -> Self::KeyIterator {
Self::iter_keys_from(G::prefix_hash())
}

fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::KeyIterator {
let prefix = G::prefix_hash();
Self::KeyIterator {
prefix: prefix.clone(),
previous_key: prefix,
prefix,
previous_key: starting_raw_key,
drain: false,
closure: |raw_key_without_prefix| {
let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?;
Expand Down Expand Up @@ -457,6 +489,46 @@ mod test_iterators {
prefix
}

#[test]
fn n_map_iter_from() {
sp_io::TestExternalities::default().execute_with(|| {
use crate::{hash::Identity, storage::Key as NMapKey};
crate::generate_storage_alias!(
MyModule,
MyNMap => NMap<Key<(u64, Identity), (u64, Identity), (u64, Identity)>, u64>
);

MyNMap::insert((1, 1, 1), 11);
MyNMap::insert((1, 1, 2), 21);
MyNMap::insert((1, 1, 3), 31);
MyNMap::insert((1, 2, 1), 12);
MyNMap::insert((1, 2, 2), 22);
MyNMap::insert((1, 2, 3), 32);
MyNMap::insert((1, 3, 1), 13);
MyNMap::insert((1, 3, 2), 23);
MyNMap::insert((1, 3, 3), 33);
MyNMap::insert((2, 0, 0), 200);

type Key = (NMapKey<Identity, u64>, NMapKey<Identity, u64>, NMapKey<Identity, u64>);

let starting_raw_key = MyNMap::storage_n_map_final_key::<Key, _>((1, 2, 2));
let iter = MyNMap::iter_key_prefix_from((1,), starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![(2, 3), (3, 1), (3, 2), (3, 3)]);

let starting_raw_key = MyNMap::storage_n_map_final_key::<Key, _>((1, 3, 1));
let iter = MyNMap::iter_prefix_from((1, 3), starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![(2, 23), (3, 33)]);

let starting_raw_key = MyNMap::storage_n_map_final_key::<Key, _>((1, 3, 2));
let iter = MyNMap::iter_keys_from(starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![(1, 3, 3), (2, 0, 0)]);

let starting_raw_key = MyNMap::storage_n_map_final_key::<Key, _>((1, 3, 3));
let iter = MyNMap::iter_from(starting_raw_key);
assert_eq!(iter.collect::<Vec<_>>(), vec![((2, 0, 0), 200)]);
});
}

#[test]
fn n_map_double_map_identical_key() {
sp_io::TestExternalities::default().execute_with(|| {
Expand Down
Loading