Trait frame_support::storage::StoragePrefixedMap
source · pub trait StoragePrefixedMap<Value: FullCodec> {
fn module_prefix() -> &'static [u8] ⓘ;
fn storage_prefix() -> &'static [u8] ⓘ;
fn final_prefix() -> [u8; 32] { ... }
fn remove_all(limit: Option<u32>) -> KillStorageResult { ... }
fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> MultiRemovalResults { ... }
fn iter_values() -> PrefixIterator<Value> ⓘ { ... }
fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(
f: F
) { ... }
}
Expand description
Trait for maps that store all its value after a unique prefix.
By default the final prefix is:
Twox128(module_prefix) ++ Twox128(storage_prefix)
Required Methods§
sourcefn module_prefix() -> &'static [u8] ⓘ
fn module_prefix() -> &'static [u8] ⓘ
Module prefix. Used for generating final key.
sourcefn storage_prefix() -> &'static [u8] ⓘ
fn storage_prefix() -> &'static [u8] ⓘ
Storage prefix. Used for generating final key.
Provided Methods§
sourcefn final_prefix() -> [u8; 32]
fn final_prefix() -> [u8; 32]
Final full prefix that prefixes all keys.
Examples found in repository?
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264
fn remove_all(limit: Option<u32>) -> sp_io::KillStorageResult {
unhashed::clear_prefix(&Self::final_prefix(), limit, None).into()
}
/// Attempt to remove all items from the map.
///
/// Returns [`MultiRemovalResults`](sp_io::MultiRemovalResults) to inform about the result. Once
/// the resultant `maybe_cursor` field is `None`, then no further items remain to be deleted.
///
/// NOTE: After the initial call for any given map, it is important that no further items
/// are inserted into the map. If so, then the map may not be empty when the resultant
/// `maybe_cursor` is `None`.
///
/// # Limit
///
/// A `limit` must always be provided through in order to cap the maximum
/// amount of deletions done in a single call. This is one fewer than the
/// maximum number of backend iterations which may be done by this operation and as such
/// represents the maximum number of backend deletions which may happen. A `limit` of zero
/// implies that no keys will be deleted, though there may be a single iteration done.
///
/// # Cursor
///
/// A *cursor* may be passed in to this operation with `maybe_cursor`. `None` should only be
/// passed once (in the initial call) for any given storage map. Subsequent calls
/// operating on the same map should always pass `Some`, and this should be equal to the
/// previous call result's `maybe_cursor` field.
fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> sp_io::MultiRemovalResults {
unhashed::clear_prefix(&Self::final_prefix(), Some(limit), maybe_cursor)
}
/// Iter over all value of the storage.
///
/// NOTE: If a value failed to decode because storage is corrupted then it is skipped.
fn iter_values() -> PrefixIterator<Value> {
let prefix = Self::final_prefix();
PrefixIterator {
prefix: prefix.to_vec(),
previous_key: prefix.to_vec(),
drain: false,
closure: |_raw_key, mut raw_value| Value::decode(&mut raw_value),
phantom: Default::default(),
}
}
/// 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.
///
/// NOTE: If a value fail to decode because storage is corrupted then it is skipped.
///
/// # Warning
///
/// This function must be used with care, before being updated the storage still contains the
/// old type, thus other calls (such as `get`) will fail at decoding it.
///
/// # Usage
///
/// This would typically be called inside the module implementation of on_runtime_upgrade.
fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(mut f: F) {
let prefix = Self::final_prefix();
let mut previous_key = prefix.clone().to_vec();
while let Some(next) =
sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))
{
previous_key = next;
let maybe_value = unhashed::get::<OldValue>(&previous_key);
match maybe_value {
Some(value) => match f(value) {
Some(new) => unhashed::put::<Value>(&previous_key, &new),
None => unhashed::kill(&previous_key),
},
None => {
log::error!("old key failed to decode at {:?}", previous_key);
continue
},
}
}
}
More examples
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
fn storage_info() -> Vec<StorageInfo> {
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Hasher::max_len::<Key>()
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}]
}
}
/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::PartialStorageInfoTrait
for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher: crate::hash::StorageHasher,
Key: FullCodec,
Value: FullCodec,
QueryKind: QueryKindTrait<Value, OnEmpty>,
OnEmpty: Get<QueryKind::Query> + 'static,
MaxValues: Get<Option<u32>>,
{
fn partial_storage_info() -> Vec<StorageInfo> {
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None,
}]
}
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
fn storage_info() -> Vec<StorageInfo> {
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Key::key_max_encoded_len()
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}]
}
}
/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::PartialStorageInfoTrait
for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Key: super::key::KeyGenerator,
Value: FullCodec,
QueryKind: QueryKindTrait<Value, OnEmpty>,
OnEmpty: Get<QueryKind::Query> + 'static,
MaxValues: Get<Option<u32>>,
{
fn partial_storage_info() -> Vec<StorageInfo> {
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None,
}]
}
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731
fn storage_info() -> Vec<StorageInfo> {
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Hasher1::max_len::<Key1>()
.saturating_add(Hasher2::max_len::<Key2>())
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}]
}
}
/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
impl<Prefix, Hasher1, Hasher2, Key1, Key2, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::PartialStorageInfoTrait
for StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher1: crate::hash::StorageHasher,
Hasher2: crate::hash::StorageHasher,
Key1: FullCodec,
Key2: FullCodec,
Value: FullCodec,
QueryKind: QueryKindTrait<Value, OnEmpty>,
OnEmpty: Get<QueryKind::Query> + 'static,
MaxValues: Get<Option<u32>>,
{
fn partial_storage_info() -> Vec<StorageInfo> {
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None,
}]
}
sourcefn remove_all(limit: Option<u32>) -> KillStorageResult
fn remove_all(limit: Option<u32>) -> KillStorageResult
clear
insteadRemove all values in the overlay and up to limit
in the backend.
All values in the client overlay will be deleted, if there is some limit
then up to
limit
values are deleted from the client backend, if limit
is none then all values in
the client backend are deleted.
Note
Calling this multiple times per block with a limit
set leads always to the same keys being
removed and the same result being returned. This happens because the keys to delete in the
overlay are not taken into account when deleting keys in the backend.
Examples found in repository?
More examples
sourcefn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> MultiRemovalResults
fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> MultiRemovalResults
Attempt to remove all items from the map.
Returns MultiRemovalResults
to inform about the result. Once
the resultant maybe_cursor
field is None
, then no further items remain to be deleted.
NOTE: After the initial call for any given map, it is important that no further items
are inserted into the map. If so, then the map may not be empty when the resultant
maybe_cursor
is None
.
Limit
A limit
must always be provided through in order to cap the maximum
amount of deletions done in a single call. This is one fewer than the
maximum number of backend iterations which may be done by this operation and as such
represents the maximum number of backend deletions which may happen. A limit
of zero
implies that no keys will be deleted, though there may be a single iteration done.
Cursor
A cursor may be passed in to this operation with maybe_cursor
. None
should only be
passed once (in the initial call) for any given storage map. Subsequent calls
operating on the same map should always pass Some
, and this should be equal to the
previous call result’s maybe_cursor
field.
Examples found in repository?
More examples
sourcefn iter_values() -> PrefixIterator<Value> ⓘ
fn iter_values() -> PrefixIterator<Value> ⓘ
Iter over all value of the storage.
NOTE: If a value failed to decode because storage is corrupted then it is skipped.
Examples found in repository?
More examples
sourcefn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(f: F)
fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(f: F)
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.
NOTE: If a value fail to decode because storage is corrupted then it is skipped.
Warning
This function must be used with care, before being updated the storage still contains the
old type, thus other calls (such as get
) will fail at decoding it.
Usage
This would typically be called inside the module implementation of on_runtime_upgrade.