Child trie api changes BREAKING (#4857)

Co-Authored-By: thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
cheme
2020-04-20 15:21:22 +02:00
committed by GitHub
parent 7d9aa81bfc
commit 4ffcf98d8d
64 changed files with 1514 additions and 1655 deletions
@@ -29,7 +29,7 @@ use crate::{
use std::iter::FromIterator;
use std::collections::{HashMap, BTreeMap, BTreeSet};
use codec::{Decode, Encode};
use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, OwnedChildInfo, ChildInfo};
use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, ChildInfo};
use std::{mem, ops};
use hash_db::Hasher;
@@ -79,8 +79,8 @@ pub struct OverlayedValue {
pub struct OverlayedChangeSet {
/// Top level storage changes.
pub top: BTreeMap<StorageKey, OverlayedValue>,
/// Child storage changes.
pub children: HashMap<StorageKey, (BTreeMap<StorageKey, OverlayedValue>, OwnedChildInfo)>,
/// Child storage changes. The map key is the child storage key without the common prefix.
pub children_default: HashMap<StorageKey, (BTreeMap<StorageKey, OverlayedValue>, ChildInfo)>,
}
/// A storage changes structure that can be generated by the data collected in [`OverlayedChanges`].
@@ -174,7 +174,7 @@ impl FromIterator<(StorageKey, OverlayedValue)> for OverlayedChangeSet {
fn from_iter<T: IntoIterator<Item = (StorageKey, OverlayedValue)>>(iter: T) -> Self {
Self {
top: iter.into_iter().collect(),
children: Default::default(),
children_default: Default::default(),
}
}
}
@@ -182,13 +182,13 @@ impl FromIterator<(StorageKey, OverlayedValue)> for OverlayedChangeSet {
impl OverlayedChangeSet {
/// Whether the change set is empty.
pub fn is_empty(&self) -> bool {
self.top.is_empty() && self.children.is_empty()
self.top.is_empty() && self.children_default.is_empty()
}
/// Clear the change set.
pub fn clear(&mut self) {
self.top.clear();
self.children.clear();
self.children_default.clear();
}
}
@@ -219,8 +219,8 @@ impl OverlayedChanges {
/// Returns a double-Option: None if the key is unknown (i.e. and the query should be referred
/// to the backend); Some(None) if the key has been deleted. Some(Some(...)) for a key whose
/// value has been set.
pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option<Option<&[u8]>> {
if let Some(map) = self.prospective.children.get(storage_key) {
pub fn child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> Option<Option<&[u8]>> {
if let Some(map) = self.prospective.children_default.get(child_info.storage_key()) {
if let Some(val) = map.0.get(key) {
let size_read = val.value.as_ref().map(|x| x.len() as u64).unwrap_or(0);
self.stats.tally_read_modified(size_read);
@@ -228,7 +228,7 @@ impl OverlayedChanges {
}
}
if let Some(map) = self.committed.children.get(storage_key) {
if let Some(map) = self.committed.children_default.get(child_info.storage_key()) {
if let Some(val) = map.0.get(key) {
let size_read = val.value.as_ref().map(|x| x.len() as u64).unwrap_or(0);
self.stats.tally_read_modified(size_read);
@@ -260,15 +260,15 @@ impl OverlayedChanges {
/// `None` can be used to delete a value specified by the given key.
pub(crate) fn set_child_storage(
&mut self,
storage_key: StorageKey,
child_info: ChildInfo,
child_info: &ChildInfo,
key: StorageKey,
val: Option<StorageValue>,
) {
let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0);
self.stats.tally_write_overlay(size_write);
let extrinsic_index = self.extrinsic_index();
let map_entry = self.prospective.children.entry(storage_key)
let storage_key = child_info.storage_key().to_vec();
let map_entry = self.prospective.children_default.entry(storage_key)
.or_insert_with(|| (Default::default(), child_info.to_owned()));
let updatable = map_entry.1.try_update(child_info);
debug_assert!(updatable);
@@ -290,11 +290,11 @@ impl OverlayedChanges {
/// [`discard_prospective`]: #method.discard_prospective
pub(crate) fn clear_child_storage(
&mut self,
storage_key: &[u8],
child_info: ChildInfo,
child_info: &ChildInfo,
) {
let extrinsic_index = self.extrinsic_index();
let map_entry = self.prospective.children.entry(storage_key.to_vec())
let storage_key = child_info.storage_key();
let map_entry = self.prospective.children_default.entry(storage_key.to_vec())
.or_insert_with(|| (Default::default(), child_info.to_owned()));
let updatable = map_entry.1.try_update(child_info);
debug_assert!(updatable);
@@ -308,7 +308,7 @@ impl OverlayedChanges {
e.value = None;
});
if let Some((committed_map, _child_info)) = self.committed.children.get(storage_key) {
if let Some((committed_map, _child_info)) = self.committed.children_default.get(storage_key) {
for (key, value) in committed_map.iter() {
if !map_entry.0.contains_key(key) {
map_entry.0.insert(key.clone(), OverlayedValue {
@@ -364,12 +364,12 @@ impl OverlayedChanges {
pub(crate) fn clear_child_prefix(
&mut self,
storage_key: &[u8],
child_info: ChildInfo,
child_info: &ChildInfo,
prefix: &[u8],
) {
let extrinsic_index = self.extrinsic_index();
let map_entry = self.prospective.children.entry(storage_key.to_vec())
let storage_key = child_info.storage_key();
let map_entry = self.prospective.children_default.entry(storage_key.to_vec())
.or_insert_with(|| (Default::default(), child_info.to_owned()));
let updatable = map_entry.1.try_update(child_info);
debug_assert!(updatable);
@@ -385,7 +385,7 @@ impl OverlayedChanges {
}
}
if let Some((child_committed, _child_info)) = self.committed.children.get(storage_key) {
if let Some((child_committed, _child_info)) = self.committed.children_default.get(storage_key) {
// Then do the same with keys from committed changes.
// NOTE that we are making changes in the prospective change set.
for key in child_committed.keys() {
@@ -422,8 +422,8 @@ impl OverlayedChanges {
.extend(prospective_extrinsics);
}
}
for (storage_key, (map, child_info)) in self.prospective.children.drain() {
let child_content = self.committed.children.entry(storage_key)
for (storage_key, (map, child_info)) in self.prospective.children_default.drain() {
let child_content = self.committed.children_default.entry(storage_key)
.or_insert_with(|| (Default::default(), child_info));
// No update to child info at this point (will be needed for deletion).
for (key, val) in map.into_iter() {
@@ -445,14 +445,14 @@ impl OverlayedChanges {
/// Will panic if there are any uncommitted prospective changes.
fn drain_committed(&mut self) -> (
impl Iterator<Item=(StorageKey, Option<StorageValue>)>,
impl Iterator<Item=(StorageKey, (impl Iterator<Item=(StorageKey, Option<StorageValue>)>, OwnedChildInfo))>,
impl Iterator<Item=(StorageKey, (impl Iterator<Item=(StorageKey, Option<StorageValue>)>, ChildInfo))>,
) {
assert!(self.prospective.is_empty());
(
std::mem::replace(&mut self.committed.top, Default::default())
.into_iter()
.map(|(k, v)| (k, v.value)),
std::mem::replace(&mut self.committed.children, Default::default())
std::mem::replace(&mut self.committed.children_default, Default::default())
.into_iter()
.map(|(sk, (v, ci))| (sk, (v.into_iter().map(|(k, v)| (k, v.value)), ci))),
)
@@ -549,21 +549,20 @@ impl OverlayedChanges {
) -> H::Out
where H::Out: Ord + Encode,
{
let child_storage_keys = self.prospective.children.keys()
.chain(self.committed.children.keys());
let child_storage_keys = self.prospective.children_default.keys()
.chain(self.committed.children_default.keys());
let child_delta_iter = child_storage_keys.map(|storage_key|
(
storage_key.clone(),
self.committed.children.get(storage_key)
self.default_child_info(storage_key).cloned()
.expect("child info initialized in either committed or prospective"),
self.committed.children_default.get(storage_key)
.into_iter()
.flat_map(|(map, _)| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))
.chain(
self.prospective.children.get(storage_key)
self.prospective.children_default.get(storage_key)
.into_iter()
.flat_map(|(map, _)| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))
),
self.child_info(storage_key).cloned()
.expect("child info initialized in either committed or prospective"),
)
);
@@ -610,11 +609,11 @@ impl OverlayedChanges {
/// Get child info for a storage key.
/// Take the latest value so prospective first.
pub fn child_info(&self, storage_key: &[u8]) -> Option<&OwnedChildInfo> {
if let Some((_, ci)) = self.prospective.children.get(storage_key) {
pub fn default_child_info(&self, storage_key: &[u8]) -> Option<&ChildInfo> {
if let Some((_, ci)) = self.prospective.children_default.get(storage_key) {
return Some(&ci);
}
if let Some((_, ci)) = self.committed.children.get(storage_key) {
if let Some((_, ci)) = self.committed.children_default.get(storage_key) {
return Some(&ci);
}
None
@@ -654,10 +653,10 @@ impl OverlayedChanges {
) -> Option<(&[u8], &OverlayedValue)> {
let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded);
let next_prospective_key = self.prospective.children.get(storage_key)
let next_prospective_key = self.prospective.children_default.get(storage_key)
.and_then(|(map, _)| map.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v)));
let next_committed_key = self.committed.children.get(storage_key)
let next_committed_key = self.committed.children_default.get(storage_key)
.and_then(|(map, _)| map.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v)));
match (next_committed_key, next_prospective_key) {
@@ -866,39 +865,40 @@ mod tests {
#[test]
fn next_child_storage_key_change_works() {
let child = b"Child1".to_vec();
let child_info = ChildInfo::new_default(b"uniqueid");
let child_info = ChildInfo::new_default(b"Child1");
let child_info = &child_info;
let child = child_info.storage_key();
let mut overlay = OverlayedChanges::default();
overlay.set_child_storage(child.clone(), child_info, vec![20], Some(vec![20]));
overlay.set_child_storage(child.clone(), child_info, vec![30], Some(vec![30]));
overlay.set_child_storage(child.clone(), child_info, vec![40], Some(vec![40]));
overlay.set_child_storage(child_info, vec![20], Some(vec![20]));
overlay.set_child_storage(child_info, vec![30], Some(vec![30]));
overlay.set_child_storage(child_info, vec![40], Some(vec![40]));
overlay.commit_prospective();
overlay.set_child_storage(child.clone(), child_info, vec![10], Some(vec![10]));
overlay.set_child_storage(child.clone(), child_info, vec![30], None);
overlay.set_child_storage(child_info, vec![10], Some(vec![10]));
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.next_child_storage_key_change(child, &[5]).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.next_child_storage_key_change(child, &[10]).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.next_child_storage_key_change(child, &[20]).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.next_child_storage_key_change(child, &[30]).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.clone(), child_info, vec![50], Some(vec![50]));
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.next_child_storage_key_change(child, &[40]).unwrap();
assert_eq!(next_to_40.0.to_vec(), vec![50]);
assert_eq!(next_to_40.1.value, Some(vec![50]));
}