Skip to content

Commit d53ba32

Browse files
atheicheme
andauthored
Allow capping the amount of work performed when deleting a child trie (#7671)
* Allow Backend::for_keys_in_child_storage to be aborted by the closure * Ext::kill_child_storage now takes an upper limit for backend deletion * Add Storage::storage_kill_limited() runtime interface * review: Use a new version of kill_storage instead of a new interface * review: Simplify boolean expression Co-authored-by: cheme <[email protected]> * review: Rename for_keys_in_child_storage Co-authored-by: cheme <[email protected]>
1 parent 62c85f7 commit d53ba32

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

src/storage/child.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ use crate::sp_std::prelude::*;
2525
use codec::{Codec, Encode, Decode};
2626
pub use sp_core::storage::{ChildInfo, ChildType};
2727

28+
/// The outcome of calling [`kill_storage`].
29+
pub enum KillOutcome {
30+
/// No key remains in the child trie.
31+
AllRemoved,
32+
/// At least one key still resides in the child trie due to the supplied limit.
33+
SomeRemaining,
34+
}
35+
2836
/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
2937
pub fn get<T: Decode + Sized>(
3038
child_info: &ChildInfo,
@@ -148,13 +156,37 @@ pub fn exists(
148156
}
149157

150158
/// Remove all `storage_key` key/values
159+
///
160+
/// Deletes all keys from the overlay and up to `limit` keys from the backend if
161+
/// it is set to `Some`. No limit is applied when `limit` is set to `None`.
162+
///
163+
/// The limit can be used to partially delete a child trie in case it is too large
164+
/// to delete in one go (block).
165+
///
166+
/// # Note
167+
///
168+
/// Please note that keys that are residing in the overlay for that child trie when
169+
/// issuing this call are all deleted without counting towards the `limit`. Only keys
170+
/// written during the current block are part of the overlay. Deleting with a `limit`
171+
/// mostly makes sense with an empty overlay for that child trie.
172+
///
173+
/// Calling this function multiple times per block for the same `storage_key` does
174+
/// not make much sense because it is not cumulative when called inside the same block.
175+
/// Use this function to distribute the deletion of a single child trie across multiple
176+
/// blocks.
151177
pub fn kill_storage(
152178
child_info: &ChildInfo,
153-
) {
154-
match child_info.child_type() {
179+
limit: Option<u32>,
180+
) -> KillOutcome {
181+
let all_removed = match child_info.child_type() {
155182
ChildType::ParentKeyId => sp_io::default_child_storage::storage_kill(
156183
child_info.storage_key(),
184+
limit
157185
),
186+
};
187+
match all_removed {
188+
true => KillOutcome::AllRemoved,
189+
false => KillOutcome::SomeRemaining,
158190
}
159191
}
160192

0 commit comments

Comments
 (0)