diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 0cdaadbdae3a2441fa4fea73cfe34325e5089970..52b3907f64ced7c29c03ec3dbce563d3eb36153b 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -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< diff --git a/substrate/frame/support/src/storage/generator/double_map.rs b/substrate/frame/support/src/storage/generator/double_map.rs index 5a775b50b6f5411aa7df686e123d8a5f108d934a..cec5bf57e50ceecd24760972048bbb0042e3eae7 100644 --- a/substrate/frame/support/src/storage/generator/double_map.rs +++ b/substrate/frame/support/src/storage/generator/double_map.rs @@ -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 + } + fn iter_key_prefix(k1: impl EncodeLike<K1>) -> Self::PartialKeyIterator { let prefix = G::storage_double_map_final_key1(k1); Self::PartialKeyIterator { @@ -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; @@ -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 { @@ -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; @@ -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(|| { diff --git a/substrate/frame/support/src/storage/generator/map.rs b/substrate/frame/support/src/storage/generator/map.rs index 48593dba17bd2b4648239a210cb6373ee3e31630..b78e9f96496faaa91ce3bc39741737415d9a3c09 100644 --- a/substrate/frame/support/src/storage/generator/map.rs +++ b/substrate/frame/support/src/storage/generator/map.rs @@ -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(); @@ -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(); @@ -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(|| { diff --git a/substrate/frame/support/src/storage/generator/mod.rs b/substrate/frame/support/src/storage/generator/mod.rs index 86129091b7ef203d9efd1f73943352cf21a875e1..576bada2e262c89f4afb85341db4684337d616fd 100644 --- a/substrate/frame/support/src/storage/generator/mod.rs +++ b/substrate/frame/support/src/storage/generator/mod.rs @@ -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; diff --git a/substrate/frame/support/src/storage/generator/nmap.rs b/substrate/frame/support/src/storage/generator/nmap.rs index 595c21caf22e5a4c86808a3fc63651052f8b1e10..2ea401f44e96f95822ca728f92042fb22142aec7 100755 --- a/substrate/frame/support/src/storage/generator/nmap.rs +++ b/substrate/frame/support/src/storage/generator/nmap.rs @@ -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>, @@ -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>, @@ -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)?; @@ -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)?; @@ -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(|| { diff --git a/substrate/frame/support/src/storage/mod.rs b/substrate/frame/support/src/storage/mod.rs index 88c8b5a22e78e2e3fe52dcf4abbb5ac7d187529b..57cbc6e31da129a3e68d5b7a1bd1bd2f59c0abc3 100644 --- a/substrate/frame/support/src/storage/mod.rs +++ b/substrate/frame/support/src/storage/mod.rs @@ -328,19 +328,29 @@ pub trait IterableStorageMap<K: FullEncode, V: FullCodec>: StorageMap<K, V> { /// The type that itereates over all `key`s. type KeyIterator: Iterator<Item = K>; - /// Enumerate all elements in the map in no particular order. If you alter the map while doing - /// this, you'll get undefined results. + /// Enumerate all elements in the map in lexicographical order of the encoded key. If you + /// alter the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; - /// Enumerate all keys in the map in no particular order, skipping over the elements. If you - /// alter the map while doing this, you'll get undefined results. + /// Enumerate all elements in the map after a specified `starting_raw_key` in lexicographical + /// order of the encoded key. If you alter the map while doing this, you'll get undefined + /// results. + fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator; + + /// Enumerate all keys in the map in lexicographical order of the encoded key, skipping over + /// the elements. If you alter the map while doing this, you'll get undefined results. fn iter_keys() -> Self::KeyIterator; - /// Remove all elements from the map and iterate through them in no particular order. If you - /// add elements to the map while doing this, you'll get undefined results. + /// Enumerate all keys in the map after a specified `starting_raw_key` in lexicographical order + /// of the encoded key. If you alter the map while doing this, you'll get undefined results. + fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::KeyIterator; + + /// Remove all elements from the map and iterate through them in lexicographical order of the + /// encoded key. If you add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; - /// Translate the values of all elements by a function `f`, in the map in no particular order. + /// Translate the values of all elements by a function `f`, in the map in lexicographical order + /// of the encoded key. /// By returning `None` from `f` for an element, you'll remove it from the map. /// /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. @@ -363,34 +373,59 @@ pub trait IterableStorageDoubleMap<K1: FullCodec, K2: FullCodec, V: FullCodec>: /// The type that iterates over all `(key1, key2, value)`. type Iterator: Iterator<Item = (K1, K2, V)>; - /// Enumerate all elements in the map with first key `k1` in no particular order. If you add or - /// remove values whose first key is `k1` to the map while doing this, you'll get undefined - /// results. + /// Enumerate all elements in the map with first key `k1` in lexicographical order of the + /// encoded key. If you add or remove values whose first key is `k1` to the map while doing + /// this, you'll get undefined results. fn iter_prefix(k1: impl EncodeLike<K1>) -> Self::PrefixIterator; - /// Enumerate all second keys `k2` in the map with the same first key `k1` in no particular - /// order. If you add or remove values whose first key is `k1` to the map while doing this, - /// you'll get undefined results. + /// Enumerate all elements in the map with first key `k1` after a specified `starting_raw_key` + /// in lexicographical order of the encoded key. If you add or remove values whose first key is + /// `k1` to the map while doing this, you'll get undefined results. + fn iter_prefix_from(k1: impl EncodeLike<K1>, starting_raw_key: Vec<u8>) + -> Self::PrefixIterator; + + /// Enumerate all second keys `k2` in the map with the same first key `k1` in lexicographical + /// order of the encoded key. If you add or remove values whose first key is `k1` to the map + /// while doing this, you'll get undefined results. fn iter_key_prefix(k1: impl EncodeLike<K1>) -> Self::PartialKeyIterator; - /// Remove all elements from the map with first key `k1` and iterate through them in no - /// particular order. If you add elements with first key `k1` to the map while doing this, - /// you'll get undefined results. + /// Enumerate all second keys `k2` in the map with the same first key `k1` after a specified + /// `starting_raw_key` in lexicographical order of the encoded key. If you add or remove values + /// whose first key is `k1` to the map while doing this, you'll get undefined results. + fn iter_key_prefix_from( + k1: impl EncodeLike<K1>, + starting_raw_key: Vec<u8>, + ) -> Self::PartialKeyIterator; + + /// Remove all elements from the map with first key `k1` and iterate through them in + /// lexicographical order of the encoded key. If you add elements with first key `k1` to the + /// map while doing this, you'll get undefined results. fn drain_prefix(k1: impl EncodeLike<K1>) -> Self::PrefixIterator; - /// Enumerate all elements in the map in no particular order. If you add or remove values to - /// the map while doing this, you'll get undefined results. + /// Enumerate all elements in the map in lexicographical order of the encoded key. If you add + /// or remove values to the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; - /// Enumerate all keys `k1` and `k2` in the map in no particular order. If you add or remove - /// values to the map while doing this, you'll get undefined results. + /// Enumerate all elements in the map after a specified `starting_raw_key` in lexicographical + /// order of the encoded key. If you add or remove values to the map while doing this, you'll + /// get undefined results. + fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator; + + /// Enumerate all keys `k1` and `k2` in the map in lexicographical order of the encoded key. If + /// you add or remove values to the map while doing this, you'll get undefined results. fn iter_keys() -> Self::FullKeyIterator; - /// Remove all elements from the map and iterate through them in no particular order. If you - /// add elements to the map while doing this, you'll get undefined results. + /// Enumerate all keys `k1` and `k2` in the map after a specified `starting_raw_key` in + /// lexicographical order of the encoded key. If you add or remove values to the map while + /// doing this, you'll get undefined results. + fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::FullKeyIterator; + + /// Remove all elements from the map and iterate through them in lexicographical order of the + /// encoded key. If you add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; - /// Translate the values of all elements by a function `f`, in the map in no particular order. + /// Translate the values of all elements by a function `f`, in the map in lexicographical order + /// of the encoded key. /// By returning `None` from `f` for an element, you'll remove it from the map. /// /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. @@ -406,40 +441,71 @@ pub trait IterableStorageNMap<K: ReversibleKeyGenerator, V: FullCodec>: StorageN /// The type that iterates over all `(key1, key2, key3, ... keyN), value)` tuples. type Iterator: Iterator<Item = (K::Key, V)>; - /// Enumerate all elements in the map with prefix key `kp` in no particular order. If you add or - /// remove values whose prefix is `kp` to the map while doing this, you'll get undefined - /// results. + /// Enumerate all elements in the map with prefix key `kp` in lexicographical order of the + /// encoded key. If you add or remove values whose prefix is `kp` to the map while doing this, + /// you'll get undefined results. fn iter_prefix<KP>(kp: KP) -> PrefixIterator<(<K as HasKeyPrefix<KP>>::Suffix, V)> where K: HasReversibleKeyPrefix<KP>; - /// Enumerate all suffix keys in the map with prefix key `kp` in no particular order. If you - /// add or remove values whose prefix is `kp` to the map while doing this, you'll get undefined - /// results. - fn iter_key_prefix<KP>(kp: KP) -> KeyPrefixIterator<<K as HasKeyPrefix<KP>>::Suffix> + /// Enumerate all elements in the map with prefix key `kp` after a specified `starting_raw_key` + /// in lexicographical order of the encoded key. If you add or remove values whose prefix is + /// `kp` to the map while doing this, you'll get undefined results. + fn iter_prefix_from<KP>( + kp: KP, + starting_raw_key: Vec<u8>, + ) -> PrefixIterator<(<K as HasKeyPrefix<KP>>::Suffix, V)> where K: HasReversibleKeyPrefix<KP>; - /// Remove all elements from the map with prefix key `kp` and iterate through them in no - /// particular order. If you add elements with prefix key `kp` to the map while doing this, + /// Enumerate all suffix keys in the map with prefix key `kp` in lexicographical order of the + /// encoded key. If you add or remove values whose prefix is `kp` to the map while doing this, /// you'll get undefined results. + fn iter_key_prefix<KP>(kp: KP) -> KeyPrefixIterator<<K as HasKeyPrefix<KP>>::Suffix> + where + K: HasReversibleKeyPrefix<KP>; + + /// Enumerate all suffix keys in the map with prefix key `kp` after a specified + /// `starting_raw_key` in lexicographical order of the encoded key. If you add or remove values + /// whose prefix is `kp` to the map while doing this, you'll get undefined results. + fn iter_key_prefix_from<KP>( + kp: KP, + starting_raw_key: Vec<u8>, + ) -> KeyPrefixIterator<<K as HasKeyPrefix<KP>>::Suffix> + where + K: HasReversibleKeyPrefix<KP>; + + /// Remove all elements from the map with prefix key `kp` and iterate through them in + /// lexicographical order of the encoded key. If you add elements with prefix key `kp` to the + /// map while doing this, you'll get undefined results. fn drain_prefix<KP>(kp: KP) -> PrefixIterator<(<K as HasKeyPrefix<KP>>::Suffix, V)> where K: HasReversibleKeyPrefix<KP>; - /// Enumerate all elements in the map in no particular order. If you add or remove values to - /// the map while doing this, you'll get undefined results. + /// Enumerate all elements in the map in lexicographical order of the encoded key. If you add + /// or remove values to the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; - /// Enumerate all keys in the map in no particular order. If you add or remove values to the - /// map while doing this, you'll get undefined results. + /// Enumerate all elements in the map after a specified `starting_raw_key` in lexicographical + /// order of the encoded key. If you add or remove values to the map while doing this, you'll + /// get undefined results. + fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator; + + /// Enumerate all keys in the map in lexicographical order of the encoded key. If you add or + /// remove values to the map while doing this, you'll get undefined results. fn iter_keys() -> Self::KeyIterator; - /// Remove all elements from the map and iterate through them in no particular order. If you - /// add elements to the map while doing this, you'll get undefined results. + /// Enumerate all keys in the map after `starting_raw_key` in lexicographical order of the + /// encoded key. If you add or remove values to the map while doing this, you'll get undefined + /// results. + fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::KeyIterator; + + /// Remove all elements from the map and iterate through them in lexicographical order of the + /// encoded key. If you add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; - /// Translate the values of all elements by a function `f`, in the map in no particular order. + /// Translate the values of all elements by a function `f`, in the map in lexicographical order + /// of the encoded key. /// By returning `None` from `f` for an element, you'll remove it from the map. /// /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. @@ -733,6 +799,37 @@ pub struct PrefixIterator<T> { } impl<T> PrefixIterator<T> { + /// Creates a new `PrefixIterator`, iterating after `previous_key` and filtering out keys that + /// are not prefixed with `prefix`. + /// + /// A `decode_fn` function must also be supplied, and it takes in two `&[u8]` parameters, + /// returning a `Result` containing the decoded type `T` if successful, and a `codec::Error` on + /// failure. The first `&[u8]` argument represents the raw, undecoded key without the prefix of + /// the current item, while the second `&[u8]` argument denotes the corresponding raw, + /// undecoded value. + pub fn new( + prefix: Vec<u8>, + previous_key: Vec<u8>, + decode_fn: fn(&[u8], &[u8]) -> Result<T, codec::Error>, + ) -> Self { + PrefixIterator { prefix, previous_key, drain: false, closure: decode_fn } + } + + /// Get the last key that has been iterated upon and return it. + pub fn last_raw_key(&self) -> &[u8] { + &self.previous_key + } + + /// Get the prefix that is being iterated upon for this iterator and return it. + pub fn prefix(&self) -> &[u8] { + &self.prefix + } + + /// Set the key that the iterator should start iterating after. + pub fn set_last_raw_key(&mut self, previous_key: Vec<u8>) { + self.previous_key = previous_key; + } + /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; @@ -798,6 +895,36 @@ pub struct KeyPrefixIterator<T> { } impl<T> KeyPrefixIterator<T> { + /// Creates a new `KeyPrefixIterator`, iterating after `previous_key` and filtering out keys + /// that are not prefixed with `prefix`. + /// + /// A `decode_fn` function must also be supplied, and it takes in a `&[u8]` parameter, returning + /// a `Result` containing the decoded key type `T` if successful, and a `codec::Error` on + /// failure. The `&[u8]` argument represents the raw, undecoded key without the prefix of the + /// current item. + pub fn new( + prefix: Vec<u8>, + previous_key: Vec<u8>, + decode_fn: fn(&[u8]) -> Result<T, codec::Error>, + ) -> Self { + KeyPrefixIterator { prefix, previous_key, drain: false, closure: decode_fn } + } + + /// Get the last key that has been iterated upon and return it. + pub fn last_raw_key(&self) -> &[u8] { + &self.previous_key + } + + /// Get the prefix that is being iterated upon for this iterator and return it. + pub fn prefix(&self) -> &[u8] { + &self.prefix + } + + /// Set the key that the iterator should start iterating after. + pub fn set_last_raw_key(&mut self, previous_key: Vec<u8>) { + self.previous_key = previous_key; + } + /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; @@ -1429,6 +1556,70 @@ mod test { }); } + #[test] + fn prefix_iterator_pagination_works() { + TestExternalities::default().execute_with(|| { + use crate::{hash::Identity, storage::generator::map::StorageMap}; + crate::generate_storage_alias! { + MyModule, + MyStorageMap => Map<(u64, Identity), u64> + } + + MyStorageMap::insert(1, 10); + MyStorageMap::insert(2, 20); + MyStorageMap::insert(3, 30); + MyStorageMap::insert(4, 40); + MyStorageMap::insert(5, 50); + MyStorageMap::insert(6, 60); + MyStorageMap::insert(7, 70); + MyStorageMap::insert(8, 80); + MyStorageMap::insert(9, 90); + MyStorageMap::insert(10, 100); + + let op = |(_, v)| v / 10; + let mut final_vec = vec![]; + let mut iter = MyStorageMap::iter(); + + let elem = iter.next().unwrap(); + assert_eq!(elem, (1, 10)); + final_vec.push(op(elem)); + + let elem = iter.next().unwrap(); + assert_eq!(elem, (2, 20)); + final_vec.push(op(elem)); + + let stored_key = iter.last_raw_key().to_owned(); + assert_eq!(stored_key, MyStorageMap::storage_map_final_key(2)); + + let mut iter = MyStorageMap::iter_from(stored_key.clone()); + + final_vec.push(op(iter.next().unwrap())); + final_vec.push(op(iter.next().unwrap())); + final_vec.push(op(iter.next().unwrap())); + + assert_eq!(final_vec, vec![1, 2, 3, 4, 5]); + + let mut iter = PrefixIterator::new( + iter.prefix().to_vec(), + stored_key, + |mut raw_key_without_prefix, mut raw_value| { + let key = u64::decode(&mut raw_key_without_prefix)?; + Ok((key, u64::decode(&mut raw_value)?)) + }, + ); + let previous_key = MyStorageMap::storage_map_final_key(5); + iter.set_last_raw_key(previous_key); + + let remaining = iter.map(op).collect::<Vec<_>>(); + assert_eq!(remaining.len(), 5); + assert_eq!(remaining, vec![6, 7, 8, 9, 10]); + + final_vec.extend_from_slice(&remaining); + + assert_eq!(final_vec, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + }); + } + #[test] fn child_trie_prefixed_map_works() { TestExternalities::default().execute_with(|| { diff --git a/substrate/frame/support/src/storage/types/double_map.rs b/substrate/frame/support/src/storage/types/double_map.rs index 1704f8a647cb6e4e8934bc39bc18ad586161075c..2db8a845c568cbfbfd496db7436e6efd3185bb1b 100644 --- a/substrate/frame/support/src/storage/types/double_map.rs +++ b/substrate/frame/support/src/storage/types/double_map.rs @@ -406,6 +406,21 @@ where <Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::iter_prefix(k1) } + /// Enumerate all elements in the map with first key `k1` after a specified `starting_raw_key` + /// in no particular order. + /// + /// If you add or remove values whose first key is `k1` to the map while doing this, you'll get + /// undefined results. + pub fn iter_prefix_from( + k1: impl EncodeLike<Key1>, + starting_raw_key: Vec<u8>, + ) -> crate::storage::PrefixIterator<(Key2, Value)> { + <Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::iter_prefix_from( + k1, + starting_raw_key, + ) + } + /// Enumerate all second keys `k2` in the map with the same first key `k1` in no particular /// order. /// @@ -415,6 +430,21 @@ where <Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::iter_key_prefix(k1) } + /// Enumerate all second keys `k2` in the map with the same first key `k1` after a specified + /// `starting_raw_key` in no particular order. + /// + /// If you add or remove values whose first key is `k1` to the map while doing this, you'll get + /// undefined results. + pub fn iter_key_prefix_from( + k1: impl EncodeLike<Key1>, + starting_raw_key: Vec<u8>, + ) -> crate::storage::KeyPrefixIterator<Key2> { + <Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::iter_key_prefix_from( + k1, + starting_raw_key, + ) + } + /// Remove all elements from the map with first key `k1` and iterate through them in no /// particular order. /// @@ -433,6 +463,18 @@ where <Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::iter() } + /// Enumerate all elements in the map after a specified `starting_raw_key` in no particular + /// order. + /// + /// If you add or remove values to the map while doing this, you'll get undefined results. + pub fn iter_from( + starting_raw_key: Vec<u8>, + ) -> crate::storage::PrefixIterator<(Key1, Key2, Value)> { + <Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::iter_from( + starting_raw_key, + ) + } + /// Enumerate all keys `k1` and `k2` in the map in no particular order. /// /// If you add or remove values to the map while doing this, you'll get undefined results. @@ -440,6 +482,18 @@ where <Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::iter_keys() } + /// Enumerate all keys `k1` and `k2` in the map after a specified `starting_raw_key` in no + /// particular order. + /// + /// If you add or remove values to the map while doing this, you'll get undefined results. + pub fn iter_keys_from( + starting_raw_key: Vec<u8>, + ) -> crate::storage::KeyPrefixIterator<(Key1, Key2)> { + <Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::iter_keys_from( + starting_raw_key, + ) + } + /// Remove all elements from the map and iterate through them in no particular order. /// /// If you add elements to the map while doing this, you'll get undefined results. diff --git a/substrate/frame/support/src/storage/types/map.rs b/substrate/frame/support/src/storage/types/map.rs index 00fa3a3b8b40ed3c2d260226dfa5528f97bba76a..6b3cfe64eaec050db52cb92f1ad27d6f0d91a09f 100644 --- a/substrate/frame/support/src/storage/types/map.rs +++ b/substrate/frame/support/src/storage/types/map.rs @@ -296,6 +296,14 @@ where <Self as crate::storage::IterableStorageMap<Key, Value>>::iter() } + /// Enumerate all elements in the map after a specified `starting_raw_key` in no + /// particular order. + /// + /// If you alter the map while doing this, you'll get undefined results. + pub fn iter_from(starting_raw_key: Vec<u8>) -> crate::storage::PrefixIterator<(Key, Value)> { + <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_from(starting_raw_key) + } + /// Enumerate all keys in the map in no particular order. /// /// If you alter the map while doing this, you'll get undefined results. @@ -303,6 +311,14 @@ where <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_keys() } + /// Enumerate all keys in the map after a specified `starting_raw_key` in no particular + /// order. + /// + /// If you alter the map while doing this, you'll get undefined results. + pub fn iter_keys_from(starting_raw_key: Vec<u8>) -> crate::storage::KeyPrefixIterator<Key> { + <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_keys_from(starting_raw_key) + } + /// Remove all elements from the map and iterate through them in no particular order. /// /// If you add elements to the map while doing this, you'll get undefined results. diff --git a/substrate/frame/support/src/storage/types/nmap.rs b/substrate/frame/support/src/storage/types/nmap.rs index f62cd1435a2dff6aa71775ab27375c07414534ed..149872ccba9ab5f3ab2ca233338e89074850138a 100755 --- a/substrate/frame/support/src/storage/types/nmap.rs +++ b/substrate/frame/support/src/storage/types/nmap.rs @@ -328,6 +328,24 @@ where <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_prefix(kp) } + /// Enumerate all elements in the map with prefix key `kp` after a specified `starting_raw_key` + /// in no particular order. + /// + /// If you add or remove values whose prefix key is `kp` to the map while doing this, you'll get + /// undefined results. + pub fn iter_prefix_from<KP>( + kp: KP, + starting_raw_key: Vec<u8>, + ) -> crate::storage::PrefixIterator<(<Key as HasKeyPrefix<KP>>::Suffix, Value)> + where + Key: HasReversibleKeyPrefix<KP>, + { + <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_prefix_from( + kp, + starting_raw_key, + ) + } + /// Enumerate all suffix keys in the map with prefix key `kp` in no particular order. /// /// If you add or remove values whose prefix key is `kp` to the map while doing this, you'll get @@ -341,6 +359,24 @@ where <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_key_prefix(kp) } + /// Enumerate all suffix keys in the map with prefix key `kp` after a specified + /// `starting_raw_key` in no particular order. + /// + /// If you add or remove values whose prefix key is `kp` to the map while doing this, you'll get + /// undefined results. + pub fn iter_key_prefix_from<KP>( + kp: KP, + starting_raw_key: Vec<u8>, + ) -> crate::storage::KeyPrefixIterator<<Key as HasKeyPrefix<KP>>::Suffix> + where + Key: HasReversibleKeyPrefix<KP>, + { + <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_key_prefix_from( + kp, + starting_raw_key, + ) + } + /// Remove all elements from the map with prefix key `kp` and iterate through them in no /// particular order. /// @@ -362,6 +398,15 @@ where <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter() } + /// Enumerate all elements in the map after a specified `starting_key` in no particular order. + /// + /// If you add or remove values to the map while doing this, you'll get undefined results. + pub fn iter_from( + starting_raw_key: Vec<u8>, + ) -> crate::storage::PrefixIterator<(Key::Key, Value)> { + <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_from(starting_raw_key) + } + /// Enumerate all keys in the map in no particular order. /// /// If you add or remove values to the map while doing this, you'll get undefined results. @@ -369,6 +414,15 @@ where <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_keys() } + /// Enumerate all keys in the map after a specified `starting_raw_key` in no particular order. + /// + /// If you add or remove values to the map while doing this, you'll get undefined results. + pub fn iter_keys_from( + starting_raw_key: Vec<u8>, + ) -> crate::storage::KeyPrefixIterator<Key::Key> { + <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_keys_from(starting_raw_key) + } + /// Remove all elements from the map and iterate through them in no particular order. /// /// If you add elements to the map while doing this, you'll get undefined results. @@ -511,7 +565,7 @@ mod test { { crate::generate_storage_alias!(test, Foo => NMap< - (u16, Blake2_128Concat), + Key<(u16, Blake2_128Concat)>, u32 >);