mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 09:17:58 +00:00
Optimize next_storage_key (#8956)
* Optimize `next_storage_key` - Do not rely on recursion - Use an iterator over the overlay to not always call the same method * Fix bug
This commit is contained in:
@@ -426,11 +426,11 @@ impl OverlayedChangeSet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the change that is next to the supplied key.
|
||||
pub fn next_change(&self, key: &[u8]) -> Option<(&[u8], &OverlayedValue)> {
|
||||
/// Get the iterator over all changes that follow the supplied `key`.
|
||||
pub fn changes_after(&self, key: &[u8]) -> impl Iterator<Item = (&[u8], &OverlayedValue)> {
|
||||
use sp_std::ops::Bound;
|
||||
let range = (Bound::Excluded(key), Bound::Unbounded);
|
||||
self.changes.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v))
|
||||
self.changes.range::<[u8], _>(range).map(|(k, v)| (k.as_slice(), v))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,29 +707,29 @@ mod test {
|
||||
changeset.set(b"key4".to_vec(), Some(b"val4".to_vec()), Some(4));
|
||||
changeset.set(b"key11".to_vec(), Some(b"val11".to_vec()), Some(11));
|
||||
|
||||
assert_eq!(changeset.next_change(b"key0").unwrap().0, b"key1");
|
||||
assert_eq!(changeset.next_change(b"key0").unwrap().1.value(), Some(&b"val1".to_vec()));
|
||||
assert_eq!(changeset.next_change(b"key1").unwrap().0, b"key11");
|
||||
assert_eq!(changeset.next_change(b"key1").unwrap().1.value(), Some(&b"val11".to_vec()));
|
||||
assert_eq!(changeset.next_change(b"key11").unwrap().0, b"key2");
|
||||
assert_eq!(changeset.next_change(b"key11").unwrap().1.value(), Some(&b"val2".to_vec()));
|
||||
assert_eq!(changeset.next_change(b"key2").unwrap().0, b"key3");
|
||||
assert_eq!(changeset.next_change(b"key2").unwrap().1.value(), Some(&b"val3".to_vec()));
|
||||
assert_eq!(changeset.next_change(b"key3").unwrap().0, b"key4");
|
||||
assert_eq!(changeset.next_change(b"key3").unwrap().1.value(), Some(&b"val4".to_vec()));
|
||||
assert_eq!(changeset.next_change(b"key4"), None);
|
||||
assert_eq!(changeset.changes_after(b"key0").next().unwrap().0, b"key1");
|
||||
assert_eq!(changeset.changes_after(b"key0").next().unwrap().1.value(), Some(&b"val1".to_vec()));
|
||||
assert_eq!(changeset.changes_after(b"key1").next().unwrap().0, b"key11");
|
||||
assert_eq!(changeset.changes_after(b"key1").next().unwrap().1.value(), Some(&b"val11".to_vec()));
|
||||
assert_eq!(changeset.changes_after(b"key11").next().unwrap().0, b"key2");
|
||||
assert_eq!(changeset.changes_after(b"key11").next().unwrap().1.value(), Some(&b"val2".to_vec()));
|
||||
assert_eq!(changeset.changes_after(b"key2").next().unwrap().0, b"key3");
|
||||
assert_eq!(changeset.changes_after(b"key2").next().unwrap().1.value(), Some(&b"val3".to_vec()));
|
||||
assert_eq!(changeset.changes_after(b"key3").next().unwrap().0, b"key4");
|
||||
assert_eq!(changeset.changes_after(b"key3").next().unwrap().1.value(), Some(&b"val4".to_vec()));
|
||||
assert_eq!(changeset.changes_after(b"key4").next(), None);
|
||||
|
||||
changeset.rollback_transaction().unwrap();
|
||||
|
||||
assert_eq!(changeset.next_change(b"key0").unwrap().0, b"key1");
|
||||
assert_eq!(changeset.next_change(b"key0").unwrap().1.value(), Some(&b"val1".to_vec()));
|
||||
assert_eq!(changeset.next_change(b"key1").unwrap().0, b"key2");
|
||||
assert_eq!(changeset.next_change(b"key1").unwrap().1.value(), Some(&b"val2".to_vec()));
|
||||
assert_eq!(changeset.next_change(b"key11").unwrap().0, b"key2");
|
||||
assert_eq!(changeset.next_change(b"key11").unwrap().1.value(), Some(&b"val2".to_vec()));
|
||||
assert_eq!(changeset.next_change(b"key2"), None);
|
||||
assert_eq!(changeset.next_change(b"key3"), None);
|
||||
assert_eq!(changeset.next_change(b"key4"), None);
|
||||
assert_eq!(changeset.changes_after(b"key0").next().unwrap().0, b"key1");
|
||||
assert_eq!(changeset.changes_after(b"key0").next().unwrap().1.value(), Some(&b"val1".to_vec()));
|
||||
assert_eq!(changeset.changes_after(b"key1").next().unwrap().0, b"key2");
|
||||
assert_eq!(changeset.changes_after(b"key1").next().unwrap().1.value(), Some(&b"val2".to_vec()));
|
||||
assert_eq!(changeset.changes_after(b"key11").next().unwrap().0, b"key2");
|
||||
assert_eq!(changeset.changes_after(b"key11").next().unwrap().1.value(), Some(&b"val2".to_vec()));
|
||||
assert_eq!(changeset.changes_after(b"key2").next(), None);
|
||||
assert_eq!(changeset.changes_after(b"key3").next(), None);
|
||||
assert_eq!(changeset.changes_after(b"key4").next(), None);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -669,24 +669,24 @@ impl OverlayedChanges {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the next (in lexicographic order) storage key in the overlayed alongside its value.
|
||||
/// If no value is next then `None` is returned.
|
||||
pub fn next_storage_key_change(&self, key: &[u8]) -> Option<(&[u8], &OverlayedValue)> {
|
||||
self.top.next_change(key)
|
||||
/// Returns an iterator over the keys (in lexicographic order) following `key` (excluding `key`)
|
||||
/// alongside its value.
|
||||
pub fn iter_after(&self, key: &[u8]) -> impl Iterator<Item = (&[u8], &OverlayedValue)> {
|
||||
self.top.changes_after(key)
|
||||
}
|
||||
|
||||
/// Returns the next (in lexicographic order) child storage key in the overlayed alongside its
|
||||
/// value. If no value is next then `None` is returned.
|
||||
pub fn next_child_storage_key_change(
|
||||
/// Returns an iterator over the keys (in lexicographic order) following `key` (excluding `key`)
|
||||
/// alongside its value for the given `storage_key` child.
|
||||
pub fn child_iter_after(
|
||||
&self,
|
||||
storage_key: &[u8],
|
||||
key: &[u8]
|
||||
) -> Option<(&[u8], &OverlayedValue)> {
|
||||
) -> impl Iterator<Item = (&[u8], &OverlayedValue)> {
|
||||
self.children
|
||||
.get(storage_key)
|
||||
.and_then(|(overlay, _)|
|
||||
overlay.next_change(key)
|
||||
)
|
||||
.map(|(overlay, _)| overlay.changes_after(key))
|
||||
.into_iter()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
/// Read only access ot offchain overlay.
|
||||
@@ -988,28 +988,28 @@ mod tests {
|
||||
overlay.set_storage(vec![30], None);
|
||||
|
||||
// next_prospective < next_committed
|
||||
let next_to_5 = overlay.next_storage_key_change(&[5]).unwrap();
|
||||
let next_to_5 = overlay.iter_after(&[5]).next().unwrap();
|
||||
assert_eq!(next_to_5.0.to_vec(), vec![10]);
|
||||
assert_eq!(next_to_5.1.value(), Some(&vec![10]));
|
||||
|
||||
// next_committed < next_prospective
|
||||
let next_to_10 = overlay.next_storage_key_change(&[10]).unwrap();
|
||||
let next_to_10 = overlay.iter_after(&[10]).next().unwrap();
|
||||
assert_eq!(next_to_10.0.to_vec(), vec![20]);
|
||||
assert_eq!(next_to_10.1.value(), Some(&vec![20]));
|
||||
|
||||
// next_committed == next_prospective
|
||||
let next_to_20 = overlay.next_storage_key_change(&[20]).unwrap();
|
||||
let next_to_20 = overlay.iter_after(&[20]).next().unwrap();
|
||||
assert_eq!(next_to_20.0.to_vec(), vec![30]);
|
||||
assert_eq!(next_to_20.1.value(), None);
|
||||
|
||||
// next_committed, no next_prospective
|
||||
let next_to_30 = overlay.next_storage_key_change(&[30]).unwrap();
|
||||
let next_to_30 = overlay.iter_after(&[30]).next().unwrap();
|
||||
assert_eq!(next_to_30.0.to_vec(), vec![40]);
|
||||
assert_eq!(next_to_30.1.value(), Some(&vec![40]));
|
||||
|
||||
overlay.set_storage(vec![50], Some(vec![50]));
|
||||
// next_prospective, no next_committed
|
||||
let next_to_40 = overlay.next_storage_key_change(&[40]).unwrap();
|
||||
let next_to_40 = overlay.iter_after(&[40]).next().unwrap();
|
||||
assert_eq!(next_to_40.0.to_vec(), vec![50]);
|
||||
assert_eq!(next_to_40.1.value(), Some(&vec![50]));
|
||||
}
|
||||
@@ -1029,28 +1029,28 @@ mod tests {
|
||||
overlay.set_child_storage(child_info, vec![30], None);
|
||||
|
||||
// next_prospective < next_committed
|
||||
let next_to_5 = overlay.next_child_storage_key_change(child, &[5]).unwrap();
|
||||
let next_to_5 = overlay.child_iter_after(child, &[5]).next().unwrap();
|
||||
assert_eq!(next_to_5.0.to_vec(), vec![10]);
|
||||
assert_eq!(next_to_5.1.value(), Some(&vec![10]));
|
||||
|
||||
// next_committed < next_prospective
|
||||
let next_to_10 = overlay.next_child_storage_key_change(child, &[10]).unwrap();
|
||||
let next_to_10 = overlay.child_iter_after(child, &[10]).next().unwrap();
|
||||
assert_eq!(next_to_10.0.to_vec(), vec![20]);
|
||||
assert_eq!(next_to_10.1.value(), Some(&vec![20]));
|
||||
|
||||
// next_committed == next_prospective
|
||||
let next_to_20 = overlay.next_child_storage_key_change(child, &[20]).unwrap();
|
||||
let next_to_20 = overlay.child_iter_after(child, &[20]).next().unwrap();
|
||||
assert_eq!(next_to_20.0.to_vec(), vec![30]);
|
||||
assert_eq!(next_to_20.1.value(), None);
|
||||
|
||||
// next_committed, no next_prospective
|
||||
let next_to_30 = overlay.next_child_storage_key_change(child, &[30]).unwrap();
|
||||
let next_to_30 = overlay.child_iter_after(child, &[30]).next().unwrap();
|
||||
assert_eq!(next_to_30.0.to_vec(), vec![40]);
|
||||
assert_eq!(next_to_30.1.value(), Some(&vec![40]));
|
||||
|
||||
overlay.set_child_storage(child_info, vec![50], Some(vec![50]));
|
||||
// next_prospective, no next_committed
|
||||
let next_to_40 = overlay.next_child_storage_key_change(child, &[40]).unwrap();
|
||||
let next_to_40 = overlay.child_iter_after(child, &[40]).next().unwrap();
|
||||
assert_eq!(next_to_40.0.to_vec(), vec![50]);
|
||||
assert_eq!(next_to_40.1.value(), Some(&vec![50]));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user