mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 07:41:08 +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
@@ -79,7 +79,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
// implementation changes and behavior does not, then leave spec_version as
|
||||
// is and increment impl_version.
|
||||
spec_version: 197,
|
||||
impl_version: 197,
|
||||
impl_version: 198,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -521,6 +521,10 @@ mod test_append_and_len {
|
||||
MapVecWithDefault: map u32 => Vec<u32> = vec![6, 9];
|
||||
OptionMapVec: map u32 => Option<Vec<u32>>;
|
||||
|
||||
DoubleMapVec: double_map u32, blake2_256(u32) => Vec<u32>;
|
||||
DoubleMapVecWithDefault: double_map u32, blake2_256(u32) => Vec<u32> = vec![6, 9];
|
||||
OptionDoubleMapVec: double_map u32, blake2_256(u32) => Option<Vec<u32>>;
|
||||
|
||||
LinkedMapVec: linked_map u32 => Vec<u32>;
|
||||
LinkedMapVecWithDefault: linked_map u32 => Vec<u32> = vec![6, 9];
|
||||
OptionLinkedMapVec: linked_map u32 => Option<Vec<u32>>;
|
||||
@@ -596,11 +600,13 @@ mod test_append_and_len {
|
||||
OptionVec::put(&vec![1, 2, 3, 4, 5]);
|
||||
MapVec::insert(1, &vec![1, 2, 3, 4, 5, 6]);
|
||||
LinkedMapVec::insert(2, &vec![1, 2, 3]);
|
||||
DoubleMapVec::insert(0, 1, &vec![1, 2]);
|
||||
|
||||
assert_eq!(JustVec::decode_len().unwrap(), 4);
|
||||
assert_eq!(OptionVec::decode_len().unwrap(), 5);
|
||||
assert_eq!(MapVec::decode_len(1).unwrap(), 6);
|
||||
assert_eq!(LinkedMapVec::decode_len(2).unwrap(), 3);
|
||||
assert_eq!(DoubleMapVec::decode_len(0, 1).unwrap(), 2);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -636,6 +642,16 @@ mod test_append_and_len {
|
||||
|
||||
assert_eq!(OptionLinkedMapVec::get(0), None);
|
||||
assert_eq!(OptionLinkedMapVec::decode_len(0), Ok(0));
|
||||
|
||||
// Double map
|
||||
assert_eq!(DoubleMapVec::get(0, 0), vec![]);
|
||||
assert_eq!(DoubleMapVec::decode_len(0, 1), Ok(0));
|
||||
|
||||
assert_eq!(DoubleMapVecWithDefault::get(0, 0), vec![6, 9]);
|
||||
assert_eq!(DoubleMapVecWithDefault::decode_len(0, 1), Ok(2));
|
||||
|
||||
assert_eq!(OptionDoubleMapVec::get(0, 0), None);
|
||||
assert_eq!(OptionDoubleMapVec::decode_len(0, 1), Ok(0));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user