mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 17:01:09 +00:00
* Add `swap` and `decode_len` to `DoubleMap` * Add tests to `swap` and `decode_len` for `DoubleMap` (WIP) * Address review comments * Remove function that is not in scope * fix test * better naming
This commit is contained in:
committed by
Bastian Köcher
parent
810ac845b5
commit
22c00ff424
@@ -292,6 +292,36 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_map_swap_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
DataDM::insert(0, 1, 1);
|
||||
DataDM::insert(1, 0, 2);
|
||||
DataDM::insert(1, 1, 3);
|
||||
|
||||
let get_all = || vec![
|
||||
DataDM::get(0, 1),
|
||||
DataDM::get(1, 0),
|
||||
DataDM::get(1, 1),
|
||||
DataDM::get(2, 0),
|
||||
DataDM::get(2, 1),
|
||||
];
|
||||
assert_eq!(get_all(), vec![1, 2, 3, 0, 0]);
|
||||
|
||||
// Two existing
|
||||
DataDM::swap(0, 1, 1, 0);
|
||||
assert_eq!(get_all(), vec![2, 1, 3, 0, 0]);
|
||||
|
||||
// Left existing
|
||||
DataDM::swap(1, 0, 2, 0);
|
||||
assert_eq!(get_all(), vec![2, 0, 3, 1, 0]);
|
||||
|
||||
// Right existing
|
||||
DataDM::swap(2, 1, 1, 1);
|
||||
assert_eq!(get_all(), vec![2, 0, 0, 1, 3]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn linked_map_basic_insert_remove_should_work() {
|
||||
new_test_ext().execute_with(|| {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use rstd::prelude::*;
|
||||
use rstd::borrow::Borrow;
|
||||
use codec::{Ref, FullCodec, FullEncode, Encode, EncodeLike, EncodeAppend};
|
||||
use crate::{storage::{self, unhashed}, hash::{StorageHasher, Twox128}};
|
||||
use crate::{storage::{self, unhashed}, hash::{StorageHasher, Twox128}, traits::Len};
|
||||
|
||||
/// Generator for `StorageDoubleMap` used by `decl_storage`.
|
||||
///
|
||||
@@ -137,6 +137,29 @@ where
|
||||
G::from_optional_value_to_query(value)
|
||||
}
|
||||
|
||||
fn swap<XKArg1, XKArg2, YKArg1, YKArg2>(x_k1: XKArg1, x_k2: XKArg2, y_k1: YKArg1, y_k2: YKArg2)
|
||||
where
|
||||
XKArg1: EncodeLike<K1>,
|
||||
XKArg2: EncodeLike<K2>,
|
||||
YKArg1: EncodeLike<K1>,
|
||||
YKArg2: EncodeLike<K2>
|
||||
{
|
||||
let final_x_key = Self::storage_double_map_final_key(x_k1, x_k2);
|
||||
let final_y_key = Self::storage_double_map_final_key(y_k1, y_k2);
|
||||
|
||||
let v1 = unhashed::get_raw(&final_x_key);
|
||||
if let Some(val) = unhashed::get_raw(&final_y_key) {
|
||||
unhashed::put_raw(&final_x_key, &val);
|
||||
} else {
|
||||
unhashed::kill(&final_x_key)
|
||||
}
|
||||
if let Some(val) = v1 {
|
||||
unhashed::put_raw(&final_y_key, &val);
|
||||
} else {
|
||||
unhashed::kill(&final_y_key)
|
||||
}
|
||||
}
|
||||
|
||||
fn insert<KArg1, KArg2, VArg>(k1: KArg1, k2: KArg2, val: VArg)
|
||||
where
|
||||
KArg1: EncodeLike<K1>,
|
||||
@@ -225,4 +248,21 @@ where
|
||||
Self::append(Ref::from(&k1), Ref::from(&k2), items.clone())
|
||||
.unwrap_or_else(|_| Self::insert(k1, k2, items));
|
||||
}
|
||||
|
||||
fn decode_len<KArg1, KArg2>(key1: KArg1, key2: KArg2) -> Result<usize, &'static str>
|
||||
where KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
V: codec::DecodeLength + Len,
|
||||
{
|
||||
let final_key = Self::storage_double_map_final_key(key1, key2);
|
||||
if let Some(v) = unhashed::get_raw(&final_key) {
|
||||
<V as codec::DecodeLength>::len(&v).map_err(|e| e.what())
|
||||
} else {
|
||||
let len = G::from_query_to_optional_value(G::from_optional_value_to_query(None))
|
||||
.map(|v| v.len())
|
||||
.unwrap_or(0);
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,6 +284,14 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>;
|
||||
|
||||
/// Swap the values of two key-pairs.
|
||||
fn swap<XKArg1, XKArg2, YKArg1, YKArg2>(x_k1: XKArg1, x_k2: XKArg2, y_k1: YKArg1, y_k2: YKArg2)
|
||||
where
|
||||
XKArg1: EncodeLike<K1>,
|
||||
XKArg2: EncodeLike<K2>,
|
||||
YKArg1: EncodeLike<K1>,
|
||||
YKArg2: EncodeLike<K2>;
|
||||
|
||||
fn insert<KArg1, KArg2, VArg>(k1: KArg1, k2: KArg2, val: VArg)
|
||||
where
|
||||
KArg1: EncodeLike<K1>,
|
||||
@@ -330,4 +338,17 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
|
||||
V: EncodeAppend<Item=Item>,
|
||||
Items: IntoIterator<Item=EncodeLikeItem> + Clone + EncodeLike<V>,
|
||||
Items::IntoIter: ExactSizeIterator;
|
||||
|
||||
/// Read the length of the value in a fast way, without decoding the entire value.
|
||||
///
|
||||
/// `V` is required to implement `Codec::DecodeLength`.
|
||||
///
|
||||
/// Note that `0` is returned as the default value if no encoded value exists at the given key.
|
||||
/// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()`
|
||||
/// function for this purpose.
|
||||
fn decode_len<KArg1, KArg2>(key1: KArg1, key2: KArg2) -> Result<usize, &'static str>
|
||||
where
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
V: codec::DecodeLength + Len;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user