From cfbfad959cc4145adba1fbeb78b5e18b41b03f45 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Tue, 6 Jul 2021 23:10:28 -0700 Subject: [PATCH 01/17] Add methods to PrefixIterator to support iterating from a specific key --- frame/support/src/storage/mod.rs | 117 +++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 65bd9af6c498b..fad69cc3d28ba 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -716,6 +716,37 @@ pub struct PrefixIterator { } impl PrefixIterator { + /// Creates a new `PrefixIterator`, starting from `next_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, + next_key: Vec, + decode_fn: fn(&[u8], &[u8]) -> Result, + ) -> Self { + PrefixIterator { + prefix, + previous_key: next_key, + drain: false, + closure: decode_fn, + } + } + + /// Get the next key that is about to be iterated upon and return it. + pub fn next_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 + } + /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; @@ -781,6 +812,36 @@ pub struct KeyPrefixIterator { } impl KeyPrefixIterator { + /// Creates a new `KeyPrefixIterator`, starting from `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, + previous_key: Vec, + decode_fn: fn(&[u8]) -> Result, + ) -> Self { + KeyPrefixIterator { + prefix, + previous_key, + drain: false, + closure: decode_fn, + } + } + + /// Get the next key that is about to be iterated upon and return it. + pub fn next_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 + } + /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; @@ -1413,6 +1474,62 @@ mod test { }); } + #[test] + fn prefix_iterator_pagination() { + TestExternalities::default().execute_with(|| { + use crate::storage::generator::StorageMap; + use crate::hash::Twox64Concat; + struct MyStorageMap; + impl StorageMap for MyStorageMap { + type Query = u64; + type Hasher = Twox64Concat; + + fn module_prefix() -> &'static [u8] { + b"MyModule" + } + + fn storage_prefix() -> &'static [u8] { + b"MyStorageMap" + } + + fn from_optional_value_to_query(v: Option) -> Self::Query { + v.unwrap_or_default() + } + + fn from_query_to_optional_value(v: Self::Query) -> Option { + Some(v) + } + } + + 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 mut iter = MyStorageMap::iter(); + assert!(iter.next().is_some()); + assert!(iter.next().is_some()); + + let prefix = iter.prefix().to_owned(); + let stored_key = iter.next_key().to_owned(); + let iter = PrefixIterator::new( + prefix, + stored_key, + |raw_key_without_prefix, mut raw_value| { + let mut key_material = Twox64Concat::reverse(raw_key_without_prefix); + Ok((u64::decode(&mut key_material)?, u64::decode(&mut raw_value)?)) + }, + ); + assert_eq!(iter.collect::>().len(), 8); + }); + } + #[test] fn child_trie_prefixed_map_works() { TestExternalities::default().execute_with(|| { From 34f57d92db89646d0c98ea1880df58d58e523b09 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 8 Jul 2021 17:16:13 -0700 Subject: [PATCH 02/17] Expose the decode functions used in iterators for storage maps --- .../src/storage/generator/double_map.rs | 58 ++++++++++------- frame/support/src/storage/generator/map.rs | 25 +++++--- frame/support/src/storage/generator/nmap.rs | 50 +++++++++++---- frame/support/src/storage/mod.rs | 63 +++++++++++++++++++ 4 files changed, 153 insertions(+), 43 deletions(-) diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 71d8ca3c043a6..1f6b2d0a3df84 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -351,10 +351,7 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix, mut raw_value| { - let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); - Ok((K2::decode(&mut key_material)?, V::decode(&mut raw_value)?)) - }, + closure: >::partial_key_value_decode_fn, } } @@ -364,10 +361,7 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix| { - let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); - K2::decode(&mut key_material) - } + closure: >::partial_key_decode_fn, } } @@ -383,13 +377,7 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix, mut raw_value| { - let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); - let k1 = K1::decode(&mut k1_k2_material)?; - let mut k2_material = G::Hasher2::reverse(k1_k2_material); - let k2 = K2::decode(&mut k2_material)?; - Ok((k1, k2, V::decode(&mut raw_value)?)) - }, + closure: >::full_key_value_decode_fn, } } @@ -399,13 +387,7 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix| { - let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); - let k1 = K1::decode(&mut k1_k2_material)?; - let mut k2_material = G::Hasher2::reverse(k1_k2_material); - let k2 = K2::decode(&mut k2_material)?; - Ok((k1, k2)) - } + closure: >::full_key_decode_fn, } } @@ -415,6 +397,38 @@ impl< iterator } + fn partial_key_value_decode_fn( + raw_key_without_prefix: &[u8], + mut raw_value: &[u8], + ) -> Result<(K2, V), codec::Error> { + let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); + Ok((K2::decode(&mut key_material)?, V::decode(&mut raw_value)?)) + } + + fn partial_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result { + let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); + K2::decode(&mut key_material) + } + + fn full_key_value_decode_fn( + raw_key_without_prefix: &[u8], + mut raw_value: &[u8], + ) -> Result<(K1, K2, V), codec::Error> { + let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); + let k1 = K1::decode(&mut k1_k2_material)?; + let mut k2_material = G::Hasher2::reverse(k1_k2_material); + let k2 = K2::decode(&mut k2_material)?; + Ok((k1, k2, V::decode(&mut raw_value)?)) + } + + fn full_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result<(K1, K2), codec::Error> { + let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); + let k1 = K1::decode(&mut k1_k2_material)?; + let mut k2_material = G::Hasher2::reverse(k1_k2_material); + let k2 = K2::decode(&mut k2_material)?; + Ok((k1, k2)) + } + fn translate Option>(mut f: F) { let prefix = G::prefix_hash(); let mut previous_key = prefix.clone(); diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index e58a001c679fd..0b418735d3655 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -149,10 +149,7 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix, mut raw_value| { - let mut key_material = G::Hasher::reverse(raw_key_without_prefix); - Ok((K::decode(&mut key_material)?, V::decode(&mut raw_value)?)) - }, + closure: >::key_value_decode_fn, } } @@ -163,13 +160,25 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix| { - let mut key_material = G::Hasher::reverse(raw_key_without_prefix); - K::decode(&mut key_material) - } + closure: >::key_decode_fn, } } + /// Decode function used in iter. + fn key_value_decode_fn( + raw_key_without_prefix: &[u8], + mut raw_value: &[u8], + ) -> Result<(K, V), codec::Error> { + let mut key_material = G::Hasher::reverse(raw_key_without_prefix); + Ok((K::decode(&mut key_material)?, V::decode(&mut raw_value)?)) + } + + /// Decode function used in iter_keys. + fn key_decode_fn(raw_key_without_prefix: &[u8]) -> Result { + let mut key_material = G::Hasher::reverse(raw_key_without_prefix); + K::decode(&mut key_material) + } + /// Enumerate all elements in the map. fn drain() -> Self::Iterator { let mut iterator = Self::iter(); diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index 49c8c94ea7a94..1190a5ccb5891 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -322,10 +322,7 @@ impl> prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix, mut raw_value| { - let partial_key = K::decode_partial_key(raw_key_without_prefix)?; - Ok((partial_key, V::decode(&mut raw_value)?)) - }, + closure: >::partial_key_value_decode_fn::, } } @@ -338,7 +335,7 @@ impl> prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: K::decode_partial_key, + closure: >::partial_key_decode_fn::, } } @@ -357,10 +354,7 @@ impl> prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix, mut raw_value| { - let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; - Ok((final_key, V::decode(&mut raw_value)?)) - }, + closure: >::full_key_value_decode_fn, } } @@ -370,10 +364,7 @@ impl> prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: |raw_key_without_prefix| { - let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; - Ok(final_key) - } + closure: >::full_key_decode_fn, } } @@ -383,6 +374,39 @@ impl> iterator } + fn partial_key_value_decode_fn( + raw_key_without_prefix: &[u8], + mut raw_value: &[u8], + ) -> Result<(>::Suffix, V), codec::Error> + where + K: HasReversibleKeyPrefix, + { + let partial_key = K::decode_partial_key(raw_key_without_prefix)?; + Ok((partial_key, V::decode(&mut raw_value)?)) + } + + fn partial_key_decode_fn( + raw_key_without_prefix: &[u8], + ) -> Result<>::Suffix, codec::Error> + where + K: HasReversibleKeyPrefix, + { + K::decode_partial_key(raw_key_without_prefix) + } + + fn full_key_value_decode_fn( + raw_key_without_prefix: &[u8], + mut raw_value: &[u8], + ) -> Result<(K::Key, V), codec::Error> { + let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; + Ok((final_key, V::decode(&mut raw_value)?)) + } + + fn full_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result { + let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; + Ok(final_key) + } + fn translate Option>(mut f: F) { let prefix = G::prefix_hash(); let mut previous_key = prefix.clone(); diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index fad69cc3d28ba..cd5b0e9d4a838 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -325,6 +325,17 @@ pub trait IterableStorageMap: StorageMap { /// alter the map while doing this, you'll get undefined results. fn iter_keys() -> Self::KeyIterator; + /// The decode function used while iterating through the key-value pairs in + /// [`IterableStorageMap::iter`]. + fn key_value_decode_fn( + raw_key_without_prefix: &[u8], + raw_value: &[u8], + ) -> Result<(K, V), codec::Error>; + + /// The decode function used while iterating through the keys in + /// [`IterableStorageMap::iter_keys`]. + fn key_decode_fn(raw_key_without_prefix: &[u8]) -> Result; + /// 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. fn drain() -> Self::Iterator; @@ -381,6 +392,28 @@ pub trait IterableStorageDoubleMap< /// add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; + /// The decode function used while iterating through the partial key-value pairs in + /// [`IterableStorageDoubleMap::iter_prefix`]. + fn partial_key_value_decode_fn( + raw_key_without_prefix: &[u8], + raw_value: &[u8], + ) -> Result<(K2, V), codec::Error>; + + /// The decode function used while iterating through the partial keys in + /// [`IterableStorageDoubleMap::iter_key_prefix`]. + fn partial_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result; + + /// The decode function used while iterating through the full key-value pairs in + /// [`IterableStorageDoubleMap::iter`]. + fn full_key_value_decode_fn( + raw_key_without_prefix: &[u8], + raw_value: &[u8], + ) -> Result<(K1, K2, V), codec::Error>; + + /// The decode function used while iterating through the full key pairs in + /// [`IterableStorageDoubleMap::iter_keys`]. + fn full_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result<(K1, K2), codec::Error>; + /// Translate the values of all elements by a function `f`, in the map in no particular order. /// By returning `None` from `f` for an element, you'll remove it from the map. /// @@ -427,6 +460,36 @@ pub trait IterableStorageNMap: StorageN /// add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; + /// The decode function used while iterating through the prefix key-value pairs in + /// [`IterableStorageNMap::iter_prefix`]. + /// + /// A type parameter `KP` denoting the type of the key prefix must be provided. See + fn partial_key_value_decode_fn( + raw_key_without_prefix: &[u8], + raw_value: &[u8], + ) -> Result<(>::Suffix, V), codec::Error> + where K: HasReversibleKeyPrefix; + + /// The decode function used while iterating through the prefix keys in + /// [`IterableStorageNMap::iter_key_prefix`]. + /// + /// A type parameter denoting the type of the key prefix must be provided. See + fn partial_key_decode_fn( + raw_key_without_prefix: &[u8], + ) -> Result<>::Suffix, codec::Error> + where K: HasReversibleKeyPrefix; + + /// The decode function used while iterating through the key-value pairs in + /// [`IterableStorageNMap::iter`]. + fn full_key_value_decode_fn( + raw_key_without_prefix: &[u8], + raw_value: &[u8], + ) -> Result<(K::Key, V), codec::Error>; + + /// The decode function used while iterating through the keys in + /// [`IterableStorageNMap::iter_keys`]. + fn full_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result; + /// Translate the values of all elements by a function `f`, in the map in no particular order. /// By returning `None` from `f` for an element, you'll remove it from the map. /// From 5b3bbe2f624d05007d2c2683bed45fe869ee0cf0 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 8 Jul 2021 17:21:42 -0700 Subject: [PATCH 03/17] Use associated decode function in tests --- frame/support/src/storage/mod.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index cd5b0e9d4a838..d01cf8eddf508 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -1538,7 +1538,7 @@ mod test { } #[test] - fn prefix_iterator_pagination() { + fn prefix_iterator_pagination_works() { TestExternalities::default().execute_with(|| { use crate::storage::generator::StorageMap; use crate::hash::Twox64Concat; @@ -1584,10 +1584,7 @@ mod test { let iter = PrefixIterator::new( prefix, stored_key, - |raw_key_without_prefix, mut raw_value| { - let mut key_material = Twox64Concat::reverse(raw_key_without_prefix); - Ok((u64::decode(&mut key_material)?, u64::decode(&mut raw_value)?)) - }, + MyStorageMap::key_value_decode_fn, ); assert_eq!(iter.collect::>().len(), 8); }); From 981a1ceb9da32f495204f61d92bf80f4eecb71fe Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 12 Jul 2021 15:54:52 -0700 Subject: [PATCH 04/17] Revert "Expose the decode functions used in iterators for storage maps" This reverts commit 34f57d92db89646d0c98ea1880df58d58e523b09. --- .../src/storage/generator/double_map.rs | 58 ++++++--------- frame/support/src/storage/generator/map.rs | 25 +++---- frame/support/src/storage/generator/nmap.rs | 50 ++++--------- frame/support/src/storage/mod.rs | 70 ++----------------- 4 files changed, 48 insertions(+), 155 deletions(-) diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 1f6b2d0a3df84..71d8ca3c043a6 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -351,7 +351,10 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::partial_key_value_decode_fn, + closure: |raw_key_without_prefix, mut raw_value| { + let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); + Ok((K2::decode(&mut key_material)?, V::decode(&mut raw_value)?)) + }, } } @@ -361,7 +364,10 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::partial_key_decode_fn, + closure: |raw_key_without_prefix| { + let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); + K2::decode(&mut key_material) + } } } @@ -377,7 +383,13 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::full_key_value_decode_fn, + closure: |raw_key_without_prefix, mut raw_value| { + let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); + let k1 = K1::decode(&mut k1_k2_material)?; + let mut k2_material = G::Hasher2::reverse(k1_k2_material); + let k2 = K2::decode(&mut k2_material)?; + Ok((k1, k2, V::decode(&mut raw_value)?)) + }, } } @@ -387,7 +399,13 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::full_key_decode_fn, + closure: |raw_key_without_prefix| { + let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); + let k1 = K1::decode(&mut k1_k2_material)?; + let mut k2_material = G::Hasher2::reverse(k1_k2_material); + let k2 = K2::decode(&mut k2_material)?; + Ok((k1, k2)) + } } } @@ -397,38 +415,6 @@ impl< iterator } - fn partial_key_value_decode_fn( - raw_key_without_prefix: &[u8], - mut raw_value: &[u8], - ) -> Result<(K2, V), codec::Error> { - let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); - Ok((K2::decode(&mut key_material)?, V::decode(&mut raw_value)?)) - } - - fn partial_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result { - let mut key_material = G::Hasher2::reverse(raw_key_without_prefix); - K2::decode(&mut key_material) - } - - fn full_key_value_decode_fn( - raw_key_without_prefix: &[u8], - mut raw_value: &[u8], - ) -> Result<(K1, K2, V), codec::Error> { - let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); - let k1 = K1::decode(&mut k1_k2_material)?; - let mut k2_material = G::Hasher2::reverse(k1_k2_material); - let k2 = K2::decode(&mut k2_material)?; - Ok((k1, k2, V::decode(&mut raw_value)?)) - } - - fn full_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result<(K1, K2), codec::Error> { - let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); - let k1 = K1::decode(&mut k1_k2_material)?; - let mut k2_material = G::Hasher2::reverse(k1_k2_material); - let k2 = K2::decode(&mut k2_material)?; - Ok((k1, k2)) - } - fn translate Option>(mut f: F) { let prefix = G::prefix_hash(); let mut previous_key = prefix.clone(); diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 0b418735d3655..e58a001c679fd 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -149,7 +149,10 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::key_value_decode_fn, + closure: |raw_key_without_prefix, mut raw_value| { + let mut key_material = G::Hasher::reverse(raw_key_without_prefix); + Ok((K::decode(&mut key_material)?, V::decode(&mut raw_value)?)) + }, } } @@ -160,25 +163,13 @@ impl< prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::key_decode_fn, + closure: |raw_key_without_prefix| { + let mut key_material = G::Hasher::reverse(raw_key_without_prefix); + K::decode(&mut key_material) + } } } - /// Decode function used in iter. - fn key_value_decode_fn( - raw_key_without_prefix: &[u8], - mut raw_value: &[u8], - ) -> Result<(K, V), codec::Error> { - let mut key_material = G::Hasher::reverse(raw_key_without_prefix); - Ok((K::decode(&mut key_material)?, V::decode(&mut raw_value)?)) - } - - /// Decode function used in iter_keys. - fn key_decode_fn(raw_key_without_prefix: &[u8]) -> Result { - let mut key_material = G::Hasher::reverse(raw_key_without_prefix); - K::decode(&mut key_material) - } - /// Enumerate all elements in the map. fn drain() -> Self::Iterator { let mut iterator = Self::iter(); diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index 1190a5ccb5891..49c8c94ea7a94 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -322,7 +322,10 @@ impl> prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::partial_key_value_decode_fn::, + closure: |raw_key_without_prefix, mut raw_value| { + let partial_key = K::decode_partial_key(raw_key_without_prefix)?; + Ok((partial_key, V::decode(&mut raw_value)?)) + }, } } @@ -335,7 +338,7 @@ impl> prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::partial_key_decode_fn::, + closure: K::decode_partial_key, } } @@ -354,7 +357,10 @@ impl> prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::full_key_value_decode_fn, + closure: |raw_key_without_prefix, mut raw_value| { + let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; + Ok((final_key, V::decode(&mut raw_value)?)) + }, } } @@ -364,7 +370,10 @@ impl> prefix: prefix.clone(), previous_key: prefix, drain: false, - closure: >::full_key_decode_fn, + closure: |raw_key_without_prefix| { + let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; + Ok(final_key) + } } } @@ -374,39 +383,6 @@ impl> iterator } - fn partial_key_value_decode_fn( - raw_key_without_prefix: &[u8], - mut raw_value: &[u8], - ) -> Result<(>::Suffix, V), codec::Error> - where - K: HasReversibleKeyPrefix, - { - let partial_key = K::decode_partial_key(raw_key_without_prefix)?; - Ok((partial_key, V::decode(&mut raw_value)?)) - } - - fn partial_key_decode_fn( - raw_key_without_prefix: &[u8], - ) -> Result<>::Suffix, codec::Error> - where - K: HasReversibleKeyPrefix, - { - K::decode_partial_key(raw_key_without_prefix) - } - - fn full_key_value_decode_fn( - raw_key_without_prefix: &[u8], - mut raw_value: &[u8], - ) -> Result<(K::Key, V), codec::Error> { - let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; - Ok((final_key, V::decode(&mut raw_value)?)) - } - - fn full_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result { - let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; - Ok(final_key) - } - fn translate Option>(mut f: F) { let prefix = G::prefix_hash(); let mut previous_key = prefix.clone(); diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index d01cf8eddf508..fad69cc3d28ba 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -325,17 +325,6 @@ pub trait IterableStorageMap: StorageMap { /// alter the map while doing this, you'll get undefined results. fn iter_keys() -> Self::KeyIterator; - /// The decode function used while iterating through the key-value pairs in - /// [`IterableStorageMap::iter`]. - fn key_value_decode_fn( - raw_key_without_prefix: &[u8], - raw_value: &[u8], - ) -> Result<(K, V), codec::Error>; - - /// The decode function used while iterating through the keys in - /// [`IterableStorageMap::iter_keys`]. - fn key_decode_fn(raw_key_without_prefix: &[u8]) -> Result; - /// 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. fn drain() -> Self::Iterator; @@ -392,28 +381,6 @@ pub trait IterableStorageDoubleMap< /// add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; - /// The decode function used while iterating through the partial key-value pairs in - /// [`IterableStorageDoubleMap::iter_prefix`]. - fn partial_key_value_decode_fn( - raw_key_without_prefix: &[u8], - raw_value: &[u8], - ) -> Result<(K2, V), codec::Error>; - - /// The decode function used while iterating through the partial keys in - /// [`IterableStorageDoubleMap::iter_key_prefix`]. - fn partial_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result; - - /// The decode function used while iterating through the full key-value pairs in - /// [`IterableStorageDoubleMap::iter`]. - fn full_key_value_decode_fn( - raw_key_without_prefix: &[u8], - raw_value: &[u8], - ) -> Result<(K1, K2, V), codec::Error>; - - /// The decode function used while iterating through the full key pairs in - /// [`IterableStorageDoubleMap::iter_keys`]. - fn full_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result<(K1, K2), codec::Error>; - /// Translate the values of all elements by a function `f`, in the map in no particular order. /// By returning `None` from `f` for an element, you'll remove it from the map. /// @@ -460,36 +427,6 @@ pub trait IterableStorageNMap: StorageN /// add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; - /// The decode function used while iterating through the prefix key-value pairs in - /// [`IterableStorageNMap::iter_prefix`]. - /// - /// A type parameter `KP` denoting the type of the key prefix must be provided. See - fn partial_key_value_decode_fn( - raw_key_without_prefix: &[u8], - raw_value: &[u8], - ) -> Result<(>::Suffix, V), codec::Error> - where K: HasReversibleKeyPrefix; - - /// The decode function used while iterating through the prefix keys in - /// [`IterableStorageNMap::iter_key_prefix`]. - /// - /// A type parameter denoting the type of the key prefix must be provided. See - fn partial_key_decode_fn( - raw_key_without_prefix: &[u8], - ) -> Result<>::Suffix, codec::Error> - where K: HasReversibleKeyPrefix; - - /// The decode function used while iterating through the key-value pairs in - /// [`IterableStorageNMap::iter`]. - fn full_key_value_decode_fn( - raw_key_without_prefix: &[u8], - raw_value: &[u8], - ) -> Result<(K::Key, V), codec::Error>; - - /// The decode function used while iterating through the keys in - /// [`IterableStorageNMap::iter_keys`]. - fn full_key_decode_fn(raw_key_without_prefix: &[u8]) -> Result; - /// Translate the values of all elements by a function `f`, in the map in no particular order. /// By returning `None` from `f` for an element, you'll remove it from the map. /// @@ -1538,7 +1475,7 @@ mod test { } #[test] - fn prefix_iterator_pagination_works() { + fn prefix_iterator_pagination() { TestExternalities::default().execute_with(|| { use crate::storage::generator::StorageMap; use crate::hash::Twox64Concat; @@ -1584,7 +1521,10 @@ mod test { let iter = PrefixIterator::new( prefix, stored_key, - MyStorageMap::key_value_decode_fn, + |raw_key_without_prefix, mut raw_value| { + let mut key_material = Twox64Concat::reverse(raw_key_without_prefix); + Ok((u64::decode(&mut key_material)?, u64::decode(&mut raw_value)?)) + }, ); assert_eq!(iter.collect::>().len(), 8); }); From 6cb9c1bea6b801b7f56647ef2d69897cbfc47c84 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 12 Jul 2021 16:07:54 -0700 Subject: [PATCH 05/17] Fix documentation for next_key --- frame/support/src/storage/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index fad69cc3d28ba..bad5d2a49bcb1 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -737,7 +737,7 @@ impl PrefixIterator { } } - /// Get the next key that is about to be iterated upon and return it. + /// Get the last key that has been iterated upon and return it. pub fn next_key(&self) -> &[u8] { &self.previous_key } @@ -832,7 +832,7 @@ impl KeyPrefixIterator { } } - /// Get the next key that is about to be iterated upon and return it. + /// Get the last key that has been iterated upon and return it. pub fn next_key(&self) -> &[u8] { &self.previous_key } From f3b21a004474a50a3157caba5c838fe0f7ecf553 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 12 Jul 2021 17:56:46 -0700 Subject: [PATCH 06/17] Add API for iterating from a specified key for all storage map types --- .../src/storage/generator/double_map.rs | 31 +++++- frame/support/src/storage/generator/map.rs | 18 +++- frame/support/src/storage/generator/nmap.rs | 40 ++++++- frame/support/src/storage/mod.rs | 102 ++++++++++++------ 4 files changed, 149 insertions(+), 42 deletions(-) diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 71d8ca3c043a6..e31c3fdad1b2c 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -358,6 +358,12 @@ impl< } } + fn iter_prefix_from(k1: impl EncodeLike, starting_key: Vec) -> Self::PrefixIterator { + let mut iter = Self::iter_prefix(k1); + iter.set_next_key(starting_key); + iter + } + fn iter_key_prefix(k1: impl EncodeLike) -> Self::PartialKeyIterator { let prefix = G::storage_double_map_final_key1(k1); Self::PartialKeyIterator { @@ -371,6 +377,15 @@ impl< } } + fn iter_key_prefix_from( + k1: impl EncodeLike, + starting_key: Vec, + ) -> Self::PartialKeyIterator { + let mut iter = Self::iter_key_prefix(k1); + iter.set_next_key(starting_key); + iter + } + fn drain_prefix(k1: impl EncodeLike) -> Self::PrefixIterator { let mut iterator = Self::iter_prefix(k1); iterator.drain = true; @@ -378,10 +393,14 @@ impl< } fn iter() -> Self::Iterator { + Self::iter_from(G::prefix_hash()) + } + + fn iter_from(starting_key: Vec) -> Self::Iterator { let prefix = G::prefix_hash(); Self::Iterator { - prefix: prefix.clone(), - previous_key: prefix, + prefix, + previous_key: starting_key, drain: false, closure: |raw_key_without_prefix, mut raw_value| { let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); @@ -394,10 +413,14 @@ impl< } fn iter_keys() -> Self::FullKeyIterator { + Self::iter_keys_from(G::prefix_hash()) + } + + fn iter_keys_from(starting_key: Vec) -> Self::FullKeyIterator { let prefix = G::prefix_hash(); Self::FullKeyIterator { - prefix: prefix.clone(), - previous_key: prefix, + prefix, + previous_key: starting_key, drain: false, closure: |raw_key_without_prefix| { let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index e58a001c679fd..062f11645b112 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -144,10 +144,15 @@ impl< /// Enumerate all elements in the map. fn iter() -> Self::Iterator { + Self::iter_from(G::prefix_hash()) + } + + /// Enumerate all elements in the map starting from a given key. + fn iter_from(starting_key: Vec) -> Self::Iterator { let prefix = G::prefix_hash(); PrefixIterator { - prefix: prefix.clone(), - previous_key: prefix, + prefix, + previous_key: starting_key, drain: false, closure: |raw_key_without_prefix, mut raw_value| { let mut key_material = G::Hasher::reverse(raw_key_without_prefix); @@ -158,10 +163,15 @@ impl< /// Enumerate all keys in the map. fn iter_keys() -> Self::KeyIterator { + Self::iter_keys_from(G::prefix_hash()) + } + + /// Enumerate all keys in the map starting from a given key. + fn iter_keys_from(starting_key: Vec) -> Self::KeyIterator { let prefix = G::prefix_hash(); KeyPrefixIterator { - prefix: prefix.clone(), - previous_key: prefix, + prefix, + previous_key: starting_key, drain: false, closure: |raw_key_without_prefix| { let mut key_material = G::Hasher::reverse(raw_key_without_prefix); diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index 49c8c94ea7a94..b6b911a9bf976 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -329,6 +329,18 @@ impl> } } + fn iter_prefix_from( + kp: KP, + starting_key: Vec, + ) -> PrefixIterator<(>::Suffix, V)> + where + K: HasReversibleKeyPrefix, + { + let mut iter = Self::iter_prefix(kp); + iter.set_next_key(starting_key); + iter + } + fn iter_key_prefix(kp: KP) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix, @@ -342,6 +354,18 @@ impl> } } + fn iter_key_prefix_from( + kp: KP, + starting_key: Vec, + ) -> KeyPrefixIterator<>::Suffix> + where + K: HasReversibleKeyPrefix, + { + let mut iter = Self::iter_key_prefix(kp); + iter.set_next_key(starting_key); + iter + } + fn drain_prefix(kp: KP) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix, @@ -352,10 +376,14 @@ impl> } fn iter() -> Self::Iterator { + Self::iter_from(G::prefix_hash()) + } + + fn iter_from(starting_key: Vec) -> Self::Iterator { let prefix = G::prefix_hash(); Self::Iterator { - prefix: prefix.clone(), - previous_key: prefix, + prefix, + previous_key: starting_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> } fn iter_keys() -> Self::KeyIterator { + Self::iter_keys_from(G::prefix_hash()) + } + + fn iter_keys_from(starting_key: Vec) -> Self::KeyIterator { let prefix = G::prefix_hash(); Self::KeyIterator { - prefix: prefix.clone(), - previous_key: prefix, + prefix, + previous_key: starting_key, drain: false, closure: |raw_key_without_prefix| { let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index bad5d2a49bcb1..3767e395d422e 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -321,10 +321,18 @@ pub trait IterableStorageMap: StorageMap { /// this, you'll get undefined results. fn iter() -> Self::Iterator; + /// Enumerate all elements in the map starting from a specified `starting_key` in no particular + /// order. If you alter the map while doing this, you'll get undefined results. + fn iter_from(starting_key: Vec) -> 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. fn iter_keys() -> Self::KeyIterator; + /// Enumerate all keys in the map starting from a specified `starting_key` in no particular + /// order. If you alter the map while doing this, you'll get undefined results. + fn iter_keys_from(starting_key: Vec) -> 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. fn drain() -> Self::Iterator; @@ -359,11 +367,24 @@ pub trait IterableStorageDoubleMap< /// results. fn iter_prefix(k1: impl EncodeLike) -> Self::PrefixIterator; + /// Enumerate all elements in the map with first key `k1` starting from a specified + /// `starting_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. + fn iter_prefix_from(k1: impl EncodeLike, starting_key: Vec) -> 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. fn iter_key_prefix(k1: impl EncodeLike) -> Self::PartialKeyIterator; + /// Enumerate all second keys `k2` in the map with the same first key `k1` starting from a + /// specified `starting_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. + fn iter_key_prefix_from( + k1: impl EncodeLike, + starting_key: Vec, + ) -> 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. @@ -373,10 +394,20 @@ pub trait IterableStorageDoubleMap< /// the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; + /// Enumerate all elements in the map starting from 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. + fn iter_from(starting_key: Vec) -> 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. fn iter_keys() -> Self::FullKeyIterator; + /// Enumerate all keys `k1` and `k2` in the map starting from 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. + fn iter_keys_from(starting_key: Vec) -> 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. fn drain() -> Self::Iterator; @@ -403,12 +434,30 @@ pub trait IterableStorageNMap: StorageN fn iter_prefix(kp: KP) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; + /// Enumerate all elements in the map with prefix key `kp` starting from a specified + /// `starting_key` 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_prefix_from( + kp: KP, + starting_key: Vec, + ) -> PrefixIterator<(>::Suffix, V)> + where K: HasReversibleKeyPrefix; + /// 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) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix; + /// Enumerate all suffix keys in the map with prefix key `kp` starting from a specified + /// `starting_key` 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_from( + kp: KP, + starting_key: Vec, + ) -> KeyPrefixIterator<>::Suffix> + where K: HasReversibleKeyPrefix; + /// 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, /// you'll get undefined results. @@ -419,10 +468,19 @@ pub trait IterableStorageNMap: StorageN /// the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; + /// Enumerate all elements in the map starting from 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. + fn iter_from(starting_key: Vec) -> 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. fn iter_keys() -> Self::KeyIterator; + /// Enumerate all keys in the map starting from `starting_key` in no particular order. If you + /// add or remove values to the map while doing this, you'll get undefined results. + fn iter_keys_from(starting_key: Vec) -> 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. fn drain() -> Self::Iterator; @@ -747,6 +805,11 @@ impl PrefixIterator { &self.prefix } + /// Set the next key that the iterator should start iterating upon. + pub fn set_next_key(&mut self, next_key: Vec) { + self.previous_key = next_key; + } + /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; @@ -842,6 +905,11 @@ impl KeyPrefixIterator { &self.prefix } + /// Set the next key that the iterator should start iterating upon. + pub fn set_next_key(&mut self, next_key: Vec) { + self.previous_key = next_key; + } + /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; @@ -1477,28 +1545,10 @@ mod test { #[test] fn prefix_iterator_pagination() { TestExternalities::default().execute_with(|| { - use crate::storage::generator::StorageMap; use crate::hash::Twox64Concat; - struct MyStorageMap; - impl StorageMap for MyStorageMap { - type Query = u64; - type Hasher = Twox64Concat; - - fn module_prefix() -> &'static [u8] { - b"MyModule" - } - - fn storage_prefix() -> &'static [u8] { - b"MyStorageMap" - } - - fn from_optional_value_to_query(v: Option) -> Self::Query { - v.unwrap_or_default() - } - - fn from_query_to_optional_value(v: Self::Query) -> Option { - Some(v) - } + crate::generate_storage_alias! { + MyModule, + MyStorageMap => Map<(u64, Twox64Concat), u64> } MyStorageMap::insert(1, 10); @@ -1516,16 +1566,8 @@ mod test { assert!(iter.next().is_some()); assert!(iter.next().is_some()); - let prefix = iter.prefix().to_owned(); let stored_key = iter.next_key().to_owned(); - let iter = PrefixIterator::new( - prefix, - stored_key, - |raw_key_without_prefix, mut raw_value| { - let mut key_material = Twox64Concat::reverse(raw_key_without_prefix); - Ok((u64::decode(&mut key_material)?, u64::decode(&mut raw_value)?)) - }, - ); + let iter = MyStorageMap::iter_from(stored_key); assert_eq!(iter.collect::>().len(), 8); }); } From 2dd16b7f61c6852c9a6d713688a84c76ced5ff44 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 12 Jul 2021 18:55:45 -0700 Subject: [PATCH 07/17] Enhance pagination test --- frame/support/src/storage/mod.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 3767e395d422e..acdfeaa1bcd40 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -1562,13 +1562,27 @@ mod test { MyStorageMap::insert(9, 90); MyStorageMap::insert(10, 100); + let op = |(_, v)| v / 10; + let mut final_vec = vec![]; let mut iter = MyStorageMap::iter(); - assert!(iter.next().is_some()); - assert!(iter.next().is_some()); + + let elem = iter.next(); + assert!(elem.is_some()); + final_vec.push(op(elem.unwrap())); + + let elem = iter.next(); + assert!(elem.is_some()); + final_vec.push(op(elem.unwrap())); let stored_key = iter.next_key().to_owned(); - let iter = MyStorageMap::iter_from(stored_key); - assert_eq!(iter.collect::>().len(), 8); + let iter = MyStorageMap::iter_from(stored_key).map(op); + let remaining = iter.collect::>(); + assert_eq!(remaining.len(), 8); + + final_vec.extend_from_slice(&remaining); + final_vec.sort(); + + assert_eq!(final_vec, vec![1,2, 3, 4, 5, 6, 7, 8, 9, 10]); }); } From 0d7a2ebcd6ef08c7ed5f353578db70a2c9cb595b Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 12 Jul 2021 21:17:33 -0700 Subject: [PATCH 08/17] Add API methods to storage map types --- frame/support/src/storage/types/double_map.rs | 40 ++++++++++++++++ frame/support/src/storage/types/map.rs | 16 +++++++ frame/support/src/storage/types/nmap.rs | 46 +++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/frame/support/src/storage/types/double_map.rs b/frame/support/src/storage/types/double_map.rs index a8ab4329ceb30..aa5a218ea2cdd 100644 --- a/frame/support/src/storage/types/double_map.rs +++ b/frame/support/src/storage/types/double_map.rs @@ -387,6 +387,18 @@ where >::iter_prefix(k1) } + /// Enumerate all elements in the map with first key `k1` starting from a specified + /// `starting_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, + starting_key: Vec, + ) -> crate::storage::PrefixIterator<(Key2, Value)> { + >::iter_prefix_from(k1, starting_key) + } + /// Enumerate all second keys `k2` in the map with the same first key `k1` in no particular /// order. /// @@ -396,6 +408,18 @@ where >::iter_key_prefix(k1) } + /// Enumerate all second keys `k2` in the map with the same first key `k1` starting from a + /// specified `starting_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, + starting_key: Vec, + ) -> crate::storage::KeyPrefixIterator { + >::iter_key_prefix_from(k1, starting_key) + } + /// Remove all elements from the map with first key `k1` and iterate through them in no /// particular order. /// @@ -412,6 +436,14 @@ where >::iter() } + /// Enumerate all elements in the map starting from 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_key: Vec) -> crate::storage::PrefixIterator<(Key1, Key2, Value)> { + >::iter_from(starting_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. @@ -419,6 +451,14 @@ where >::iter_keys() } + /// Enumerate all keys `k1` and `k2` in the map starting from 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_keys_from(starting_key: Vec) -> crate::storage::KeyPrefixIterator<(Key1, Key2)> { + >::iter_keys_from(starting_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/frame/support/src/storage/types/map.rs b/frame/support/src/storage/types/map.rs index 800cd1153a72d..0a1d9584946a2 100644 --- a/frame/support/src/storage/types/map.rs +++ b/frame/support/src/storage/types/map.rs @@ -297,6 +297,14 @@ where >::iter() } + /// Enumerate all elements in the map starting from a specified `starting_key` in no + /// particular order. + /// + /// If you alter the map while doing this, you'll get undefined results. + pub fn iter_from(starting_key: Vec) -> crate::storage::PrefixIterator<(Key, Value)> { + >::iter_from(starting_key) + } + /// Enumerate all keys in the map in no particular order. /// /// If you alter the map while doing this, you'll get undefined results. @@ -304,6 +312,14 @@ where >::iter_keys() } + /// Enumerate all keys in the map starting from a specified `starting_key` in no particular + /// order. + /// + /// If you alter the map while doing this, you'll get undefined results. + pub fn iter_keys_from(starting_key: Vec) -> crate::storage::KeyPrefixIterator { + >::iter_keys_from(starting_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/frame/support/src/storage/types/nmap.rs b/frame/support/src/storage/types/nmap.rs index b75542cbf9a25..23920c183c74a 100755 --- a/frame/support/src/storage/types/nmap.rs +++ b/frame/support/src/storage/types/nmap.rs @@ -318,6 +318,21 @@ where >::iter_prefix(kp) } + /// Enumerate all elements in the map with prefix key `kp` starting from a specified + /// `starting_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, + starting_key: Vec, + ) -> crate::storage::PrefixIterator<(>::Suffix, Value)> + where + Key: HasReversibleKeyPrefix, + { + >::iter_prefix_from(kp, starting_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 @@ -331,6 +346,21 @@ where >::iter_key_prefix(kp) } + /// Enumerate all suffix keys in the map with prefix key `kp` starting from a specified + /// `starting_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, + starting_key: Vec, + ) -> crate::storage::KeyPrefixIterator<>::Suffix> + where + Key: HasReversibleKeyPrefix, + { + >::iter_key_prefix_from(kp, starting_key) + } + /// Remove all elements from the map with prefix key `kp` and iterate through them in no /// particular order. /// @@ -352,6 +382,14 @@ where >::iter() } + /// Enumerate all elements in the map starting from 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_key: Vec) -> crate::storage::PrefixIterator<(Key::Key, Value)> { + >::iter_from(starting_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. @@ -359,6 +397,14 @@ where >::iter_keys() } + /// Enumerate all keys in the map starting from 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_keys_from(starting_key: Vec) -> crate::storage::KeyPrefixIterator { + >::iter_keys_from(starting_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. From 13527ffb90149517a80d20bb56354b7cb295035c Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Tue, 13 Jul 2021 15:05:16 -0700 Subject: [PATCH 09/17] Rename next_key to last_key --- frame/support/src/storage/generator/double_map.rs | 4 ++-- frame/support/src/storage/generator/nmap.rs | 4 ++-- frame/support/src/storage/mod.rs | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index e31c3fdad1b2c..85ff645724b31 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -360,7 +360,7 @@ impl< fn iter_prefix_from(k1: impl EncodeLike, starting_key: Vec) -> Self::PrefixIterator { let mut iter = Self::iter_prefix(k1); - iter.set_next_key(starting_key); + iter.set_last_key(starting_key); iter } @@ -382,7 +382,7 @@ impl< starting_key: Vec, ) -> Self::PartialKeyIterator { let mut iter = Self::iter_key_prefix(k1); - iter.set_next_key(starting_key); + iter.set_last_key(starting_key); iter } diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index b6b911a9bf976..19ab30e74453f 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -337,7 +337,7 @@ impl> K: HasReversibleKeyPrefix, { let mut iter = Self::iter_prefix(kp); - iter.set_next_key(starting_key); + iter.set_last_key(starting_key); iter } @@ -362,7 +362,7 @@ impl> K: HasReversibleKeyPrefix, { let mut iter = Self::iter_key_prefix(kp); - iter.set_next_key(starting_key); + iter.set_last_key(starting_key); iter } diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index acdfeaa1bcd40..0774e8984e576 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -796,7 +796,7 @@ impl PrefixIterator { } /// Get the last key that has been iterated upon and return it. - pub fn next_key(&self) -> &[u8] { + pub fn last_key(&self) -> &[u8] { &self.previous_key } @@ -806,7 +806,7 @@ impl PrefixIterator { } /// Set the next key that the iterator should start iterating upon. - pub fn set_next_key(&mut self, next_key: Vec) { + pub fn set_last_key(&mut self, next_key: Vec) { self.previous_key = next_key; } @@ -896,7 +896,7 @@ impl KeyPrefixIterator { } /// Get the last key that has been iterated upon and return it. - pub fn next_key(&self) -> &[u8] { + pub fn last_key(&self) -> &[u8] { &self.previous_key } @@ -906,7 +906,7 @@ impl KeyPrefixIterator { } /// Set the next key that the iterator should start iterating upon. - pub fn set_next_key(&mut self, next_key: Vec) { + pub fn set_last_key(&mut self, next_key: Vec) { self.previous_key = next_key; } @@ -1574,7 +1574,7 @@ mod test { assert!(elem.is_some()); final_vec.push(op(elem.unwrap())); - let stored_key = iter.next_key().to_owned(); + let stored_key = iter.last_key().to_owned(); let iter = MyStorageMap::iter_from(stored_key).map(op); let remaining = iter.collect::>(); assert_eq!(remaining.len(), 8); From e5593c6874cd451f0034361fb8c31d77bf3c3298 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Tue, 13 Jul 2021 15:07:04 -0700 Subject: [PATCH 10/17] Rename last_key to last_raw_key --- frame/support/src/storage/generator/double_map.rs | 4 ++-- frame/support/src/storage/generator/nmap.rs | 4 ++-- frame/support/src/storage/mod.rs | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 85ff645724b31..30b9a7b55dd83 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -360,7 +360,7 @@ impl< fn iter_prefix_from(k1: impl EncodeLike, starting_key: Vec) -> Self::PrefixIterator { let mut iter = Self::iter_prefix(k1); - iter.set_last_key(starting_key); + iter.set_last_raw_key(starting_key); iter } @@ -382,7 +382,7 @@ impl< starting_key: Vec, ) -> Self::PartialKeyIterator { let mut iter = Self::iter_key_prefix(k1); - iter.set_last_key(starting_key); + iter.set_last_raw_key(starting_key); iter } diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index 19ab30e74453f..92437c41f8f60 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -337,7 +337,7 @@ impl> K: HasReversibleKeyPrefix, { let mut iter = Self::iter_prefix(kp); - iter.set_last_key(starting_key); + iter.set_last_raw_key(starting_key); iter } @@ -362,7 +362,7 @@ impl> K: HasReversibleKeyPrefix, { let mut iter = Self::iter_key_prefix(kp); - iter.set_last_key(starting_key); + iter.set_last_raw_key(starting_key); iter } diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 0774e8984e576..53fe7533b764f 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -796,7 +796,7 @@ impl PrefixIterator { } /// Get the last key that has been iterated upon and return it. - pub fn last_key(&self) -> &[u8] { + pub fn last_raw_key(&self) -> &[u8] { &self.previous_key } @@ -806,7 +806,7 @@ impl PrefixIterator { } /// Set the next key that the iterator should start iterating upon. - pub fn set_last_key(&mut self, next_key: Vec) { + pub fn set_last_raw_key(&mut self, next_key: Vec) { self.previous_key = next_key; } @@ -896,7 +896,7 @@ impl KeyPrefixIterator { } /// Get the last key that has been iterated upon and return it. - pub fn last_key(&self) -> &[u8] { + pub fn last_raw_key(&self) -> &[u8] { &self.previous_key } @@ -906,7 +906,7 @@ impl KeyPrefixIterator { } /// Set the next key that the iterator should start iterating upon. - pub fn set_last_key(&mut self, next_key: Vec) { + pub fn set_last_raw_key(&mut self, next_key: Vec) { self.previous_key = next_key; } @@ -1574,7 +1574,7 @@ mod test { assert!(elem.is_some()); final_vec.push(op(elem.unwrap())); - let stored_key = iter.last_key().to_owned(); + let stored_key = iter.last_raw_key().to_owned(); let iter = MyStorageMap::iter_from(stored_key).map(op); let remaining = iter.collect::>(); assert_eq!(remaining.len(), 8); From b14264bfe951c79549ee2b666350ca0dc4030519 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 14 Jul 2021 17:28:29 -0700 Subject: [PATCH 11/17] Specify that iteration starts after starting_raw_key --- .../src/storage/generator/double_map.rs | 19 ++-- frame/support/src/storage/generator/map.rs | 12 +-- frame/support/src/storage/generator/nmap.rs | 16 ++-- frame/support/src/storage/mod.rs | 88 ++++++++++--------- frame/support/src/storage/types/double_map.rs | 40 +++++---- frame/support/src/storage/types/map.rs | 12 +-- frame/support/src/storage/types/nmap.rs | 38 ++++---- 7 files changed, 123 insertions(+), 102 deletions(-) diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 30b9a7b55dd83..2517972336718 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -358,9 +358,12 @@ impl< } } - fn iter_prefix_from(k1: impl EncodeLike, starting_key: Vec) -> Self::PrefixIterator { + fn iter_prefix_from( + k1: impl EncodeLike, + starting_raw_key: Vec, + ) -> Self::PrefixIterator { let mut iter = Self::iter_prefix(k1); - iter.set_last_raw_key(starting_key); + iter.set_last_raw_key(starting_raw_key); iter } @@ -379,10 +382,10 @@ impl< fn iter_key_prefix_from( k1: impl EncodeLike, - starting_key: Vec, + starting_raw_key: Vec, ) -> Self::PartialKeyIterator { let mut iter = Self::iter_key_prefix(k1); - iter.set_last_raw_key(starting_key); + iter.set_last_raw_key(starting_raw_key); iter } @@ -396,11 +399,11 @@ impl< Self::iter_from(G::prefix_hash()) } - fn iter_from(starting_key: Vec) -> Self::Iterator { + fn iter_from(starting_raw_key: Vec) -> Self::Iterator { let prefix = G::prefix_hash(); Self::Iterator { prefix, - previous_key: starting_key, + previous_key: starting_raw_key, drain: false, closure: |raw_key_without_prefix, mut raw_value| { let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); @@ -416,11 +419,11 @@ impl< Self::iter_keys_from(G::prefix_hash()) } - fn iter_keys_from(starting_key: Vec) -> Self::FullKeyIterator { + fn iter_keys_from(starting_raw_key: Vec) -> Self::FullKeyIterator { let prefix = G::prefix_hash(); Self::FullKeyIterator { prefix, - previous_key: starting_key, + previous_key: starting_raw_key, drain: false, closure: |raw_key_without_prefix| { let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 062f11645b112..536cd4b80045a 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -147,12 +147,12 @@ impl< Self::iter_from(G::prefix_hash()) } - /// Enumerate all elements in the map starting from a given key. - fn iter_from(starting_key: Vec) -> Self::Iterator { + /// Enumerate all elements in the map after a given key. + fn iter_from(starting_raw_key: Vec) -> Self::Iterator { let prefix = G::prefix_hash(); PrefixIterator { prefix, - previous_key: starting_key, + previous_key: starting_raw_key, drain: false, closure: |raw_key_without_prefix, mut raw_value| { let mut key_material = G::Hasher::reverse(raw_key_without_prefix); @@ -166,12 +166,12 @@ impl< Self::iter_keys_from(G::prefix_hash()) } - /// Enumerate all keys in the map starting from a given key. - fn iter_keys_from(starting_key: Vec) -> Self::KeyIterator { + /// Enumerate all keys in the map after a given key. + fn iter_keys_from(starting_raw_key: Vec) -> Self::KeyIterator { let prefix = G::prefix_hash(); KeyPrefixIterator { prefix, - previous_key: starting_key, + previous_key: starting_raw_key, drain: false, closure: |raw_key_without_prefix| { let mut key_material = G::Hasher::reverse(raw_key_without_prefix); diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index 92437c41f8f60..29534ae9d3dba 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -331,13 +331,13 @@ impl> fn iter_prefix_from( kp: KP, - starting_key: Vec, + starting_raw_key: Vec, ) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix, { let mut iter = Self::iter_prefix(kp); - iter.set_last_raw_key(starting_key); + iter.set_last_raw_key(starting_raw_key); iter } @@ -356,13 +356,13 @@ impl> fn iter_key_prefix_from( kp: KP, - starting_key: Vec, + starting_raw_key: Vec, ) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix, { let mut iter = Self::iter_key_prefix(kp); - iter.set_last_raw_key(starting_key); + iter.set_last_raw_key(starting_raw_key); iter } @@ -379,11 +379,11 @@ impl> Self::iter_from(G::prefix_hash()) } - fn iter_from(starting_key: Vec) -> Self::Iterator { + fn iter_from(starting_raw_key: Vec) -> Self::Iterator { let prefix = G::prefix_hash(); Self::Iterator { prefix, - previous_key: starting_key, + 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)?; @@ -396,11 +396,11 @@ impl> Self::iter_keys_from(G::prefix_hash()) } - fn iter_keys_from(starting_key: Vec) -> Self::KeyIterator { + fn iter_keys_from(starting_raw_key: Vec) -> Self::KeyIterator { let prefix = G::prefix_hash(); Self::KeyIterator { prefix, - previous_key: starting_key, + previous_key: starting_raw_key, drain: false, closure: |raw_key_without_prefix| { let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?; diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 53fe7533b764f..07833d4b7df6d 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -321,17 +321,17 @@ pub trait IterableStorageMap: StorageMap { /// this, you'll get undefined results. fn iter() -> Self::Iterator; - /// Enumerate all elements in the map starting from a specified `starting_key` in no particular + /// 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. - fn iter_from(starting_key: Vec) -> Self::Iterator; + fn iter_from(starting_raw_key: Vec) -> 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. fn iter_keys() -> Self::KeyIterator; - /// Enumerate all keys in the map starting from a specified `starting_key` in no particular - /// order. If you alter the map while doing this, you'll get undefined results. - fn iter_keys_from(starting_key: Vec) -> Self::KeyIterator; + /// 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. + fn iter_keys_from(starting_raw_key: Vec) -> 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. @@ -367,22 +367,22 @@ pub trait IterableStorageDoubleMap< /// results. fn iter_prefix(k1: impl EncodeLike) -> Self::PrefixIterator; - /// Enumerate all elements in the map with first key `k1` starting from a specified - /// `starting_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. - fn iter_prefix_from(k1: impl EncodeLike, starting_key: Vec) -> Self::PrefixIterator; + /// 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. + fn iter_prefix_from(k1: impl EncodeLike, starting_raw_key: Vec) -> 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. fn iter_key_prefix(k1: impl EncodeLike) -> Self::PartialKeyIterator; - /// Enumerate all second keys `k2` in the map with the same first key `k1` starting from a - /// specified `starting_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. + /// 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. fn iter_key_prefix_from( k1: impl EncodeLike, - starting_key: Vec, + starting_raw_key: Vec, ) -> Self::PartialKeyIterator; /// Remove all elements from the map with first key `k1` and iterate through them in no @@ -394,19 +394,19 @@ pub trait IterableStorageDoubleMap< /// the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; - /// Enumerate all elements in the map starting from a specified `starting_key` in no particular + /// 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. - fn iter_from(starting_key: Vec) -> Self::Iterator; + fn iter_from(starting_raw_key: Vec) -> 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. fn iter_keys() -> Self::FullKeyIterator; - /// Enumerate all keys `k1` and `k2` in the map starting from a specified `starting_key` in no + /// 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. - fn iter_keys_from(starting_key: Vec) -> Self::FullKeyIterator; + fn iter_keys_from(starting_raw_key: Vec) -> 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. @@ -434,12 +434,12 @@ pub trait IterableStorageNMap: StorageN fn iter_prefix(kp: KP) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; - /// Enumerate all elements in the map with prefix key `kp` starting from a specified - /// `starting_key` 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` after a specified `starting_raw_key` + /// 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_prefix_from( kp: KP, - starting_key: Vec, + starting_raw_key: Vec, ) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; @@ -449,12 +449,12 @@ pub trait IterableStorageNMap: StorageN fn iter_key_prefix(kp: KP) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix; - /// Enumerate all suffix keys in the map with prefix key `kp` starting from a specified - /// `starting_key` 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 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 is `kp` + /// to the map while doing this, you'll get undefined results. fn iter_key_prefix_from( kp: KP, - starting_key: Vec, + starting_raw_key: Vec, ) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix; @@ -468,18 +468,18 @@ pub trait IterableStorageNMap: StorageN /// the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; - /// Enumerate all elements in the map starting from a specified `starting_key` in no particular + /// 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. - fn iter_from(starting_key: Vec) -> Self::Iterator; + fn iter_from(starting_raw_key: Vec) -> 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. fn iter_keys() -> Self::KeyIterator; - /// Enumerate all keys in the map starting from `starting_key` in no particular order. If you - /// add or remove values to the map while doing this, you'll get undefined results. - fn iter_keys_from(starting_key: Vec) -> Self::KeyIterator; + /// Enumerate all keys in the map after `starting_raw_key` in no particular order. 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) -> 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. @@ -774,7 +774,7 @@ pub struct PrefixIterator { } impl PrefixIterator { - /// Creates a new `PrefixIterator`, starting from `next_key` and filtering out keys that are + /// Creates a new `PrefixIterator`, iterating after `next_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, @@ -875,8 +875,8 @@ pub struct KeyPrefixIterator { } impl KeyPrefixIterator { - /// Creates a new `KeyPrefixIterator`, starting from `previous_key` and filtering out keys that - /// are not prefixed with `prefix`. + /// 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 @@ -1545,10 +1545,10 @@ mod test { #[test] fn prefix_iterator_pagination() { TestExternalities::default().execute_with(|| { - use crate::hash::Twox64Concat; + use crate::hash::Identity; crate::generate_storage_alias! { MyModule, - MyStorageMap => Map<(u64, Twox64Concat), u64> + MyStorageMap => Map<(u64, Identity), u64> } MyStorageMap::insert(1, 10); @@ -1566,23 +1566,25 @@ mod test { let mut final_vec = vec![]; let mut iter = MyStorageMap::iter(); - let elem = iter.next(); - assert!(elem.is_some()); - final_vec.push(op(elem.unwrap())); + let elem = iter.next().unwrap(); + assert_eq!(elem, (1, 10)); + final_vec.push(op(elem)); - let elem = iter.next(); - assert!(elem.is_some()); - final_vec.push(op(elem.unwrap())); + let elem = iter.next().unwrap(); + assert_eq!(elem, (2, 20)); + final_vec.push(op(elem)); let stored_key = iter.last_raw_key().to_owned(); let iter = MyStorageMap::iter_from(stored_key).map(op); - let remaining = iter.collect::>(); + let mut remaining = iter.collect::>(); + remaining.sort(); assert_eq!(remaining.len(), 8); + assert_eq!(remaining, vec![3, 4, 5, 6, 7, 8, 9, 10]); final_vec.extend_from_slice(&remaining); final_vec.sort(); - assert_eq!(final_vec, vec![1,2, 3, 4, 5, 6, 7, 8, 9, 10]); + assert_eq!(final_vec, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); }); } diff --git a/frame/support/src/storage/types/double_map.rs b/frame/support/src/storage/types/double_map.rs index aa5a218ea2cdd..12543fe9d5be2 100644 --- a/frame/support/src/storage/types/double_map.rs +++ b/frame/support/src/storage/types/double_map.rs @@ -387,16 +387,18 @@ where >::iter_prefix(k1) } - /// Enumerate all elements in the map with first key `k1` starting from a specified - /// `starting_key` in no particular order. + /// 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, - starting_key: Vec, + starting_raw_key: Vec, ) -> crate::storage::PrefixIterator<(Key2, Value)> { - >::iter_prefix_from(k1, starting_key) + < + Self as crate::storage::IterableStorageDoubleMap + >::iter_prefix_from(k1, starting_raw_key) } /// Enumerate all second keys `k2` in the map with the same first key `k1` in no particular @@ -408,16 +410,18 @@ where >::iter_key_prefix(k1) } - /// Enumerate all second keys `k2` in the map with the same first key `k1` starting from a - /// specified `starting_key` in no particular order. + /// 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, - starting_key: Vec, + starting_raw_key: Vec, ) -> crate::storage::KeyPrefixIterator { - >::iter_key_prefix_from(k1, starting_key) + < + Self as crate::storage::IterableStorageDoubleMap + >::iter_key_prefix_from(k1, starting_raw_key) } /// Remove all elements from the map with first key `k1` and iterate through them in no @@ -436,12 +440,16 @@ where >::iter() } - /// Enumerate all elements in the map starting from a specified `starting_key` in no - /// particular order. + /// 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_key: Vec) -> crate::storage::PrefixIterator<(Key1, Key2, Value)> { - >::iter_from(starting_key) + pub fn iter_from( + starting_raw_key: Vec, + ) -> crate::storage::PrefixIterator<(Key1, Key2, Value)> { + < + Self as crate::storage::IterableStorageDoubleMap + >::iter_from(starting_raw_key) } /// Enumerate all keys `k1` and `k2` in the map in no particular order. @@ -451,12 +459,14 @@ where >::iter_keys() } - /// Enumerate all keys `k1` and `k2` in the map starting from a specified `starting_key` in no + /// 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_key: Vec) -> crate::storage::KeyPrefixIterator<(Key1, Key2)> { - >::iter_keys_from(starting_key) + pub fn iter_keys_from(starting_raw_key: Vec) -> crate::storage::KeyPrefixIterator<(Key1, Key2)> { + < + Self as crate::storage::IterableStorageDoubleMap + >::iter_keys_from(starting_raw_key) } /// Remove all elements from the map and iterate through them in no particular order. diff --git a/frame/support/src/storage/types/map.rs b/frame/support/src/storage/types/map.rs index 0a1d9584946a2..34a006afc380c 100644 --- a/frame/support/src/storage/types/map.rs +++ b/frame/support/src/storage/types/map.rs @@ -297,12 +297,12 @@ where >::iter() } - /// Enumerate all elements in the map starting from a specified `starting_key` in no + /// 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_key: Vec) -> crate::storage::PrefixIterator<(Key, Value)> { - >::iter_from(starting_key) + pub fn iter_from(starting_raw_key: Vec) -> crate::storage::PrefixIterator<(Key, Value)> { + >::iter_from(starting_raw_key) } /// Enumerate all keys in the map in no particular order. @@ -312,12 +312,12 @@ where >::iter_keys() } - /// Enumerate all keys in the map starting from a specified `starting_key` in no particular + /// 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_key: Vec) -> crate::storage::KeyPrefixIterator { - >::iter_keys_from(starting_key) + pub fn iter_keys_from(starting_raw_key: Vec) -> crate::storage::KeyPrefixIterator { + >::iter_keys_from(starting_raw_key) } /// Remove all elements from the map and iterate through them in no particular order. diff --git a/frame/support/src/storage/types/nmap.rs b/frame/support/src/storage/types/nmap.rs index 23920c183c74a..913730930c71f 100755 --- a/frame/support/src/storage/types/nmap.rs +++ b/frame/support/src/storage/types/nmap.rs @@ -318,19 +318,21 @@ where >::iter_prefix(kp) } - /// Enumerate all elements in the map with prefix key `kp` starting from a specified - /// `starting_key` in no particular order. + /// 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, - starting_key: Vec, + starting_raw_key: Vec, ) -> crate::storage::PrefixIterator<(>::Suffix, Value)> where Key: HasReversibleKeyPrefix, { - >::iter_prefix_from(kp, starting_key) + < + Self as crate::storage::IterableStorageNMap + >::iter_prefix_from(kp, starting_raw_key) } /// Enumerate all suffix keys in the map with prefix key `kp` in no particular order. @@ -346,19 +348,21 @@ where >::iter_key_prefix(kp) } - /// Enumerate all suffix keys in the map with prefix key `kp` starting from a specified - /// `starting_key` in no particular order. + /// 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, - starting_key: Vec, + starting_raw_key: Vec, ) -> crate::storage::KeyPrefixIterator<>::Suffix> where Key: HasReversibleKeyPrefix, { - >::iter_key_prefix_from(kp, starting_key) + < + Self as crate::storage::IterableStorageNMap + >::iter_key_prefix_from(kp, starting_raw_key) } /// Remove all elements from the map with prefix key `kp` and iterate through them in no @@ -382,12 +386,13 @@ where >::iter() } - /// Enumerate all elements in the map starting from a specified `starting_key` in no particular - /// order. + /// 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_key: Vec) -> crate::storage::PrefixIterator<(Key::Key, Value)> { - >::iter_from(starting_key) + pub fn iter_from( + starting_raw_key: Vec, + ) -> crate::storage::PrefixIterator<(Key::Key, Value)> { + >::iter_from(starting_raw_key) } /// Enumerate all keys in the map in no particular order. @@ -397,12 +402,13 @@ where >::iter_keys() } - /// Enumerate all keys in the map starting from a specified `starting_key` in no particular - /// order. + /// 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_key: Vec) -> crate::storage::KeyPrefixIterator { - >::iter_keys_from(starting_key) + pub fn iter_keys_from( + starting_raw_key: Vec, + ) -> crate::storage::KeyPrefixIterator { + >::iter_keys_from(starting_raw_key) } /// Remove all elements from the map and iterate through them in no particular order. From e9a877569b7037baf4fce1f054738ffae2725efe Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 15 Jul 2021 15:18:42 -0700 Subject: [PATCH 12/17] Update documentation on iteration ordering --- frame/support/src/storage/mod.rs | 129 ++++++++++++++++--------------- 1 file changed, 67 insertions(+), 62 deletions(-) diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 07833d4b7df6d..8aa46d38b0f3e 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -317,27 +317,29 @@ pub trait IterableStorageMap: StorageMap { /// The type that itereates over all `key`s. type KeyIterator: Iterator; - /// 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 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. + /// 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) -> 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 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; - /// 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. + /// 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) -> 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. + /// 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. @@ -362,57 +364,58 @@ pub trait IterableStorageDoubleMap< /// The type that iterates over all `(key1, key2, value)`. type Iterator: Iterator; - /// 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) -> Self::PrefixIterator; /// 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. + /// 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, starting_raw_key: Vec) -> 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 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) -> Self::PartialKeyIterator; /// 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. + /// `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, starting_raw_key: Vec, ) -> 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. + /// 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) -> 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 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. + /// 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) -> 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 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; - /// 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. + /// 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) -> 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. + /// 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. @@ -428,64 +431,66 @@ pub trait IterableStorageNMap: StorageN /// The type that iterates over all `(key1, key2, key3, ... keyN), value)` tuples. type Iterator: Iterator; - /// 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) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; /// 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 is `kp` to the map while - /// doing this, you'll get undefined results. + /// 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, starting_raw_key: Vec, ) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; - /// 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. + /// 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) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix; /// 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 is `kp` - /// to the map while doing this, you'll get undefined results. + /// `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, starting_raw_key: Vec, ) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix; - /// 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, - /// you'll get undefined results. + /// 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) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; - /// 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 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. + /// 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) -> 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 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; - /// Enumerate all keys in the map after `starting_raw_key` in no particular order. If you add - /// or remove values 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) -> 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. + /// 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. From 58e8fcd28d02ca93293804b257f1e33ece240493 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 15 Jul 2021 15:57:20 -0700 Subject: [PATCH 13/17] Rename next_key to previous_key --- frame/support/src/storage/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 8aa46d38b0f3e..eceaf01e221c2 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -779,8 +779,8 @@ pub struct PrefixIterator { } impl PrefixIterator { - /// Creates a new `PrefixIterator`, iterating after `next_key` and filtering out keys that are - /// not prefixed with `prefix`. + /// 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 @@ -789,12 +789,12 @@ impl PrefixIterator { /// undecoded value. pub fn new( prefix: Vec, - next_key: Vec, + previous_key: Vec, decode_fn: fn(&[u8], &[u8]) -> Result, ) -> Self { PrefixIterator { prefix, - previous_key: next_key, + previous_key, drain: false, closure: decode_fn, } From d41953a5b938db5c3685e34751e088f6d794c454 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 15 Jul 2021 16:45:46 -0700 Subject: [PATCH 14/17] Enhance pagination unit test --- frame/support/src/storage/mod.rs | 35 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index eceaf01e221c2..b8a3e77095eb0 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -1548,7 +1548,7 @@ mod test { } #[test] - fn prefix_iterator_pagination() { + fn prefix_iterator_pagination_works() { TestExternalities::default().execute_with(|| { use crate::hash::Identity; crate::generate_storage_alias! { @@ -1580,14 +1580,35 @@ mod test { final_vec.push(op(elem)); let stored_key = iter.last_raw_key().to_owned(); - let iter = MyStorageMap::iter_from(stored_key).map(op); - let mut remaining = iter.collect::>(); - remaining.sort(); - assert_eq!(remaining.len(), 8); - assert_eq!(remaining, vec![3, 4, 5, 6, 7, 8, 9, 10]); + let mut expected_key = MyStorageMap::final_prefix().to_vec(); + expected_key.extend_from_slice(&[2, 0, 0, 0, 0, 0, 0, 0]); + assert_eq!(stored_key, expected_key); + + 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 mut previous_key = MyStorageMap::final_prefix().to_vec(); + previous_key.extend_from_slice(&[5, 0, 0, 0, 0, 0, 0, 0]); + iter.set_last_raw_key(previous_key); + + let remaining = iter.map(op).collect::>(); + assert_eq!(remaining.len(), 5); + assert_eq!(remaining, vec![6, 7, 8, 9, 10]); final_vec.extend_from_slice(&remaining); - final_vec.sort(); assert_eq!(final_vec, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); }); From a65a6ed563b39fbda048b472741f2bdea76f470b Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 16 Jul 2021 00:49:01 -0700 Subject: [PATCH 15/17] Create unit tests for all kinds of iter_from methods --- frame/support/src/lib.rs | 2 +- .../src/storage/generator/double_map.rs | 36 ++++++++++++++++ frame/support/src/storage/generator/map.rs | 22 ++++++++++ frame/support/src/storage/generator/mod.rs | 2 +- frame/support/src/storage/generator/nmap.rs | 41 +++++++++++++++++++ frame/support/src/storage/mod.rs | 20 ++++----- frame/support/src/storage/types/nmap.rs | 2 +- 7 files changed, 111 insertions(+), 14 deletions(-) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 4134c7302a4c8..79a39abeb0533 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -155,7 +155,7 @@ macro_rules! generate_storage_alias { >; } }; - ($pallet:ident, $name:ident => NMap<$(($key:ty, $hasher:ty),)+ $value:ty>) => { + ($pallet:ident, $name:ident => NMap, $value:ty>) => { $crate::paste::paste! { $crate::generate_storage_alias!(@GENERATE_INSTANCE_STRUCT $pallet, $name); type $name = $crate::storage::types::StorageNMap< diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 2517972336718..3a619e8d641d5 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -524,6 +524,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![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![(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![(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![(4, 40, 400), (5, 50, 500)]); + }); + } + #[test] fn double_map_reversible_reversible_iteration() { sp_io::TestExternalities::default().execute_with(|| { diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 536cd4b80045a..c958da6014704 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -388,6 +388,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![(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![3, 4, 5]); + }); + } + #[test] fn map_reversible_reversible_iteration() { sp_io::TestExternalities::default().execute_with(|| { diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index 578831314c1f6..45042ca1a65ff 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -24,7 +24,7 @@ //! //! This is internal api and is subject to change. -mod map; +pub(crate) mod map; mod nmap; mod double_map; mod value; diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index 29534ae9d3dba..f02ce26c4953c 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -492,6 +492,47 @@ mod test_iterators { prefix } + #[test] + fn n_map_iter_from() { + sp_io::TestExternalities::default().execute_with(|| { + use crate::hash::Identity; + use crate::storage::Key as NMapKey; + crate::generate_storage_alias!( + MyModule, + MyNMap => NMap, 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, NMapKey, NMapKey); + + let starting_raw_key = MyNMap::storage_n_map_final_key::((1, 2, 2)); + let iter = MyNMap::iter_key_prefix_from((1,), starting_raw_key); + assert_eq!(iter.collect::>(), vec![(2, 3), (3, 1), (3, 2), (3, 3)]); + + let starting_raw_key = MyNMap::storage_n_map_final_key::((1, 3, 1)); + let iter = MyNMap::iter_prefix_from((1, 3), starting_raw_key); + assert_eq!(iter.collect::>(), vec![(2, 23), (3, 33)]); + + let starting_raw_key = MyNMap::storage_n_map_final_key::((1, 3, 2)); + let iter = MyNMap::iter_keys_from(starting_raw_key); + assert_eq!(iter.collect::>(), vec![(1, 3, 3), (2, 0, 0)]); + + let starting_raw_key = MyNMap::storage_n_map_final_key::((1, 3, 3)); + let iter = MyNMap::iter_from(starting_raw_key); + assert_eq!(iter.collect::>(), vec![((2, 0, 0), 200)]); + }); + } + #[test] fn n_map_double_map_identical_key() { sp_io::TestExternalities::default().execute_with(|| { diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index b8a3e77095eb0..dba2df97a1015 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -810,9 +810,9 @@ impl PrefixIterator { &self.prefix } - /// Set the next key that the iterator should start iterating upon. - pub fn set_last_raw_key(&mut self, next_key: Vec) { - self.previous_key = next_key; + /// Set the key that the iterator should start iterating after. + pub fn set_last_raw_key(&mut self, previous_key: Vec) { + self.previous_key = previous_key; } /// Mutate this iterator into a draining iterator; items iterated are removed from storage. @@ -910,9 +910,9 @@ impl KeyPrefixIterator { &self.prefix } - /// Set the next key that the iterator should start iterating upon. - pub fn set_last_raw_key(&mut self, next_key: Vec) { - self.previous_key = next_key; + /// Set the key that the iterator should start iterating after. + pub fn set_last_raw_key(&mut self, previous_key: Vec) { + self.previous_key = previous_key; } /// Mutate this iterator into a draining iterator; items iterated are removed from storage. @@ -1551,6 +1551,7 @@ mod test { fn prefix_iterator_pagination_works() { TestExternalities::default().execute_with(|| { use crate::hash::Identity; + use crate::storage::generator::map::StorageMap; crate::generate_storage_alias! { MyModule, MyStorageMap => Map<(u64, Identity), u64> @@ -1580,9 +1581,7 @@ mod test { final_vec.push(op(elem)); let stored_key = iter.last_raw_key().to_owned(); - let mut expected_key = MyStorageMap::final_prefix().to_vec(); - expected_key.extend_from_slice(&[2, 0, 0, 0, 0, 0, 0, 0]); - assert_eq!(stored_key, expected_key); + assert_eq!(stored_key, MyStorageMap::storage_map_final_key(2)); let mut iter = MyStorageMap::iter_from(stored_key.clone()); @@ -1600,8 +1599,7 @@ mod test { Ok((key, u64::decode(&mut raw_value)?)) }, ); - let mut previous_key = MyStorageMap::final_prefix().to_vec(); - previous_key.extend_from_slice(&[5, 0, 0, 0, 0, 0, 0, 0]); + let previous_key = MyStorageMap::storage_map_final_key(5); iter.set_last_raw_key(previous_key); let remaining = iter.map(op).collect::>(); diff --git a/frame/support/src/storage/types/nmap.rs b/frame/support/src/storage/types/nmap.rs index 913730930c71f..5afc924bffcc5 100755 --- a/frame/support/src/storage/types/nmap.rs +++ b/frame/support/src/storage/types/nmap.rs @@ -554,7 +554,7 @@ mod test { { crate::generate_storage_alias!(test, Foo => NMap< - (u16, Blake2_128Concat), + Key<(u16, Blake2_128Concat)>, u32 >); From 3aefbbb4e634bbd1512ec4cd47adf2d8b08f4fbb Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 26 Jul 2021 15:32:12 -0700 Subject: [PATCH 16/17] Define iter_from in terms of iter rather than vice versa --- .../src/storage/generator/double_map.rs | 26 ++++++++------- frame/support/src/storage/generator/map.rs | 32 +++++++++++-------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 806e34957475e..cec5bf57e50ce 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -407,14 +407,10 @@ where } fn iter() -> Self::Iterator { - Self::iter_from(G::prefix_hash()) - } - - fn iter_from(starting_raw_key: Vec) -> Self::Iterator { let prefix = G::prefix_hash(); Self::Iterator { - prefix, - previous_key: starting_raw_key, + prefix: prefix.clone(), + previous_key: prefix, drain: false, closure: |raw_key_without_prefix, mut raw_value| { let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); @@ -426,15 +422,17 @@ where } } - fn iter_keys() -> Self::FullKeyIterator { - Self::iter_keys_from(G::prefix_hash()) + fn iter_from(starting_raw_key: Vec) -> Self::Iterator { + let mut iter = Self::iter(); + iter.set_last_raw_key(starting_raw_key); + iter } - fn iter_keys_from(starting_raw_key: Vec) -> Self::FullKeyIterator { + fn iter_keys() -> Self::FullKeyIterator { let prefix = G::prefix_hash(); Self::FullKeyIterator { - prefix, - previous_key: starting_raw_key, + prefix: prefix.clone(), + previous_key: prefix, drain: false, closure: |raw_key_without_prefix| { let mut k1_k2_material = G::Hasher1::reverse(raw_key_without_prefix); @@ -446,6 +444,12 @@ where } } + fn iter_keys_from(starting_raw_key: Vec) -> 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; diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 95c5f240d0636..b78e9f96496fa 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -141,15 +141,10 @@ where /// Enumerate all elements in the map. fn iter() -> Self::Iterator { - Self::iter_from(G::prefix_hash()) - } - - /// Enumerate all elements in the map after a given key. - fn iter_from(starting_raw_key: Vec) -> Self::Iterator { let prefix = G::prefix_hash(); PrefixIterator { - prefix, - previous_key: starting_raw_key, + prefix: prefix.clone(), + previous_key: prefix, drain: false, closure: |raw_key_without_prefix, mut raw_value| { let mut key_material = G::Hasher::reverse(raw_key_without_prefix); @@ -158,17 +153,19 @@ where } } - /// Enumerate all keys in the map. - fn iter_keys() -> Self::KeyIterator { - Self::iter_keys_from(G::prefix_hash()) + /// Enumerate all elements in the map after a given key. + fn iter_from(starting_raw_key: Vec) -> Self::Iterator { + let mut iter = Self::iter(); + iter.set_last_raw_key(starting_raw_key); + iter } - /// Enumerate all keys in the map after a given key. - fn iter_keys_from(starting_raw_key: Vec) -> Self::KeyIterator { + /// Enumerate all keys in the map. + fn iter_keys() -> Self::KeyIterator { let prefix = G::prefix_hash(); KeyPrefixIterator { - prefix, - previous_key: starting_raw_key, + prefix: prefix.clone(), + previous_key: prefix, drain: false, closure: |raw_key_without_prefix| { let mut key_material = G::Hasher::reverse(raw_key_without_prefix); @@ -177,6 +174,13 @@ where } } + /// Enumerate all keys in the map after a given key. + fn iter_keys_from(starting_raw_key: Vec) -> 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(); From 447ef775657054fe13263e66526cbbdadab05159 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 26 Jul 2021 17:10:09 -0700 Subject: [PATCH 17/17] Cargo fmt --- frame/support/src/storage/generator/nmap.rs | 3 +- frame/support/src/storage/mod.rs | 22 ++++---------- frame/support/src/storage/types/double_map.rs | 30 +++++++++++-------- frame/support/src/storage/types/nmap.rs | 14 +++++---- 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/frame/support/src/storage/generator/nmap.rs b/frame/support/src/storage/generator/nmap.rs index 5ed5e4169d50d..2ea401f44e96f 100755 --- a/frame/support/src/storage/generator/nmap.rs +++ b/frame/support/src/storage/generator/nmap.rs @@ -492,8 +492,7 @@ mod test_iterators { #[test] fn n_map_iter_from() { sp_io::TestExternalities::default().execute_with(|| { - use crate::hash::Identity; - use crate::storage::Key as NMapKey; + use crate::{hash::Identity, storage::Key as NMapKey}; crate::generate_storage_alias!( MyModule, MyNMap => NMap, u64> diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 08b3f529782a5..57cbc6e31da12 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -381,7 +381,8 @@ pub trait IterableStorageDoubleMap: /// 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, starting_raw_key: Vec) -> Self::PrefixIterator; + fn iter_prefix_from(k1: impl EncodeLike, starting_raw_key: Vec) + -> 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 @@ -811,12 +812,7 @@ impl PrefixIterator { previous_key: Vec, decode_fn: fn(&[u8], &[u8]) -> Result, ) -> Self { - PrefixIterator { - prefix, - previous_key, - drain: false, - closure: decode_fn, - } + PrefixIterator { prefix, previous_key, drain: false, closure: decode_fn } } /// Get the last key that has been iterated upon and return it. @@ -911,12 +907,7 @@ impl KeyPrefixIterator { previous_key: Vec, decode_fn: fn(&[u8]) -> Result, ) -> Self { - KeyPrefixIterator { - prefix, - previous_key, - drain: false, - closure: decode_fn, - } + KeyPrefixIterator { prefix, previous_key, drain: false, closure: decode_fn } } /// Get the last key that has been iterated upon and return it. @@ -1568,8 +1559,7 @@ mod test { #[test] fn prefix_iterator_pagination_works() { TestExternalities::default().execute_with(|| { - use crate::hash::Identity; - use crate::storage::generator::map::StorageMap; + use crate::{hash::Identity, storage::generator::map::StorageMap}; crate::generate_storage_alias! { MyModule, MyStorageMap => Map<(u64, Identity), u64> @@ -1589,7 +1579,7 @@ mod test { 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)); diff --git a/frame/support/src/storage/types/double_map.rs b/frame/support/src/storage/types/double_map.rs index 324e70e129e31..2db8a845c568c 100644 --- a/frame/support/src/storage/types/double_map.rs +++ b/frame/support/src/storage/types/double_map.rs @@ -415,9 +415,10 @@ where k1: impl EncodeLike, starting_raw_key: Vec, ) -> crate::storage::PrefixIterator<(Key2, Value)> { - < - Self as crate::storage::IterableStorageDoubleMap - >::iter_prefix_from(k1, starting_raw_key) + >::iter_prefix_from( + k1, + starting_raw_key, + ) } /// Enumerate all second keys `k2` in the map with the same first key `k1` in no particular @@ -438,9 +439,10 @@ where k1: impl EncodeLike, starting_raw_key: Vec, ) -> crate::storage::KeyPrefixIterator { - < - Self as crate::storage::IterableStorageDoubleMap - >::iter_key_prefix_from(k1, starting_raw_key) + >::iter_key_prefix_from( + k1, + starting_raw_key, + ) } /// Remove all elements from the map with first key `k1` and iterate through them in no @@ -468,9 +470,9 @@ where pub fn iter_from( starting_raw_key: Vec, ) -> crate::storage::PrefixIterator<(Key1, Key2, Value)> { - < - Self as crate::storage::IterableStorageDoubleMap - >::iter_from(starting_raw_key) + >::iter_from( + starting_raw_key, + ) } /// Enumerate all keys `k1` and `k2` in the map in no particular order. @@ -484,10 +486,12 @@ where /// 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) -> crate::storage::KeyPrefixIterator<(Key1, Key2)> { - < - Self as crate::storage::IterableStorageDoubleMap - >::iter_keys_from(starting_raw_key) + pub fn iter_keys_from( + starting_raw_key: Vec, + ) -> crate::storage::KeyPrefixIterator<(Key1, Key2)> { + >::iter_keys_from( + starting_raw_key, + ) } /// Remove all elements from the map and iterate through them in no particular order. diff --git a/frame/support/src/storage/types/nmap.rs b/frame/support/src/storage/types/nmap.rs index 50f67942ba2b0..149872ccba9ab 100755 --- a/frame/support/src/storage/types/nmap.rs +++ b/frame/support/src/storage/types/nmap.rs @@ -340,9 +340,10 @@ where where Key: HasReversibleKeyPrefix, { - < - Self as crate::storage::IterableStorageNMap - >::iter_prefix_from(kp, starting_raw_key) + >::iter_prefix_from( + kp, + starting_raw_key, + ) } /// Enumerate all suffix keys in the map with prefix key `kp` in no particular order. @@ -370,9 +371,10 @@ where where Key: HasReversibleKeyPrefix, { - < - Self as crate::storage::IterableStorageNMap - >::iter_key_prefix_from(kp, starting_raw_key) + >::iter_key_prefix_from( + kp, + starting_raw_key, + ) } /// Remove all elements from the map with prefix key `kp` and iterate through them in no