1use crate::{runtime};
2use crate::spread::SpreadLayout;
3use core::hash::Hash;
4use core::borrow::Borrow;
5use crate::prelude::{Vec};
6use crate::collections::entry_state::{ValueWrapper, EntryState};
7use scale::{Decode, Encode};
8use alloc::collections::BTreeMap;
9use alloc::borrow::ToOwned;
10use alloc::collections::btree_map::Entry;
11
12pub struct HyperMap<K, V> {
14 origin_size: u64,
16 size: u64,
17 storage_prefix: Vec<u8>,
20 cache_values: BTreeMap<K, ValueWrapper<V>>,
22}
23
24impl<K, V> HyperMap<K, V> {
25 pub fn new() -> Self {
51 Self {
52 origin_size: 0,
53 size: 0,
54 storage_prefix: "_".as_bytes().to_vec(),
55 cache_values: BTreeMap::<K, ValueWrapper<V>>::new(),
56 }
57 }
58}
59
60impl<K, V> HyperMap<K, V>
61 where
62 K: Ord + Hash + Encode + Decode,
63 V: Encode + Decode
64{
65 pub fn get<Q: ?Sized>(&mut self, k: &Q) -> Option<&V>
70 where
71 K: Borrow<Q> + Ord,
72 Q: Hash + Ord + Encode + ToOwned<Owned=K>,
73 {
74 match self.cache_values.entry(k.to_owned()) {
75 Entry::Vacant(entry) => {
76 let storage_key = k.encode();
78 let value = runtime::storage_read(storage_key.as_slice(), self.storage_prefix.as_slice());
79 match value {
80 Some(v) => {
81 let input = &mut &v[..];
82 let res: V = V::decode(input).unwrap();
83 let wrapper = ValueWrapper::new(res, EntryState::NoChanged);
84 let va = entry.insert(wrapper);
86 va.value.as_ref()
87 }
88 None => {
89 None
90 }
91 }
92 }
93 Entry::Occupied(entry) => {
94 let ent = entry.into_mut();
95 if ent.state == EntryState::Deleted {
96 return None;
97 }
98 ent.value.as_ref()
100 }
101 }
102 }
103
104 pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
111 where
112 K: Borrow<Q> + Ord,
113 Q: Hash + Ord + Encode + ToOwned<Owned=K>,
114 {
115 match self.cache_values.entry(k.to_owned()) {
116 Entry::Vacant(entry) => {
117 let storage_key = k.encode();
119 let value = runtime::storage_read(storage_key.as_slice(), self.storage_prefix.as_slice());
120 match value {
121 Some(v) => {
122 let input = &mut &v[..];
123 let res: V = V::decode(input).unwrap();
124 let wrapper = ValueWrapper::new(res, EntryState::Changed);
125 let va = entry.insert(wrapper);
127 va.value.as_mut()
128 }
129 None => {
130 None
131 }
132 }
133 }
134 Entry::Occupied(entry) => {
135 let ent = entry.into_mut();
137 if ent.state == EntryState::Deleted {
138 return None;
139 }
140 ent.state = EntryState::Changed;
141 return ent.value.as_mut();
142 }
143 }
144 }
145
146
147 pub fn insert(&mut self, key: K, value: V) -> Option<V> where K: Clone {
156 match self.get_mut(&key) {
158 Some(v) => {
159 let old_value = core::mem::replace(v, value);
161 Some(old_value)
162 }
163 None => {
164 let wrapper = ValueWrapper::new(value, EntryState::Changed);
166 self.cache_values.insert(key, wrapper);
167 self.size += 1;
168 None
169 }
170 }
171 }
172
173 pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
179 where
180 K: Borrow<Q>,
181 Q: Hash + Eq + Ord + Encode + ToOwned<Owned=K>,
182 {
183 match self.cache_values.entry(k.to_owned()) {
185 Entry::Vacant(entry) => {
186 let storage_key = k.encode();
188 let value = runtime::storage_read(storage_key.as_slice(), self.storage_prefix.as_slice());
189 match value {
190 Some(v) => {
191 let input = &mut &v[..];
192 let res: V = V::decode(input).unwrap();
193 let wrapper = ValueWrapper::new_empty_value(EntryState::Deleted);
194 entry.insert(wrapper);
196 self.size -= 1; Some(res)
198 }
199 None => {
200 None
201 }
202 }
203 }
204 Entry::Occupied(mut entry) => {
205 let old = entry.insert(ValueWrapper::new_empty_value(EntryState::Deleted));
207 if old.state == EntryState::Deleted {
208 return None;
209 }
210 self.size -= 1; return old.value;
212 }
213 }
214 }
215
216 pub fn len(&self) -> u64 {
219 self.size
220 }
221
222 pub fn is_empty(&self) -> bool {
225 self.size == 0
226 }
227
228 pub fn get_key_value<Q: ?Sized>(&mut self, k: &Q) -> Option<(&K, &V)>
233 where
234 K: Borrow<Q> + Ord,
235 Q: Hash + Ord + Encode + ToOwned<Owned=K>,
236 {
237 match self.get(k) {
239 None => { None }
240 Some(_) => {
241 let (key, value) = self.cache_values.get_key_value(k).unwrap();
242 Some((key, &value.value.as_ref().unwrap()))
243 }
244 }
245 }
246
247 pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
252 where
253 K: Borrow<Q> + Ord,
254 Q: Hash + Ord + Encode + ToOwned<Owned=K>,
255 {
256 if let Some(v) = self.cache_values.get(k) {
258 return v.state != EntryState::Deleted;
259 }
260
261 let storage_key = k.encode();
263 let value = runtime::storage_read(storage_key.as_slice(), self.storage_prefix.as_slice());
264
265 value.is_some()
266 }
267}
268
269impl<K, V> Default for HyperMap<K, V> {
270 fn default() -> Self {
271 HyperMap::new()
272 }
273}
274
275impl<K, V> SpreadLayout for HyperMap<K, V>
276 where
277 K: Ord + Hash + Encode + Decode,
278 V: Encode + Decode
279{
280 fn read_ledger(key_prefix: &[u8], _: &[u8]) -> Self {
281 let mut map = HyperMap::<K, V>::new();
283 map.storage_prefix = Vec::from(key_prefix);
284 let size = runtime::storage_read(key_prefix, "@HyperMap".as_bytes()).unwrap();
285 map.size = <u64 as scale::Decode>::decode(&mut &size[..]).unwrap();
286 map.origin_size = map.size;
287 map
288 }
289
290 fn write_ledger(&self, key_prefix: &[u8], deploy_flag: &[u8]) {
291 if deploy_flag == "deploy".as_bytes() {
292 runtime::storage_write(key_prefix, "@HyperMap".as_bytes(), &[0, 0, 0, 0, 0, 0, 0, 0])
294 }
295 self.cache_values.iter().for_each(|(key, value)| {
297 match value.state {
298 EntryState::Changed => {
299 let sto_key = key.encode();
300 let sto_value = value.value.as_ref().unwrap().encode();
301 runtime::storage_write(sto_key.as_slice(), key_prefix, sto_value.as_slice());
302 }
303 EntryState::Deleted => {
304 let sto_key = key.encode();
305 runtime::storage_delete(sto_key.as_slice(), key_prefix);
306 }
307 _ => {}
308 }
309 });
310 if self.size != self.origin_size {
312 runtime::storage_write(key_prefix, "@HyperMap".as_bytes(), self.size.encode().as_slice())
313 }
314 }
315}
316
317#[cfg(test)]
318mod test {
319 use crate::collections::hyper_map::HyperMap;
320 use std::string::String;
321 use crate::spread::SpreadLayout;
322 use crate::runtime;
323 use scale::Encode;
324 use scale::Decode;
325
326 #[test]
327 fn use_map_normal() {
328 let _mock = fvm_mock::build_runtime();
329 let mut map: HyperMap<String, String> = HyperMap::new();
330 map.insert(String::from("123"), String::from("456"));
331 let res = map.get(&String::from("123")).unwrap();
332 assert_eq!(*res, String::from("456"))
333 }
334
335 #[test]
336 fn map_get() {
337 let mock = fvm_mock::build_runtime();
338 let mut map: HyperMap<i32, i64> = Default::default();
339 assert_eq!(map.get(&1), None);
340
341 mock.storage_write(1.encode().as_slice(), "_".as_bytes(), 100i64.encode());
342 assert_eq!(map.get(&1), Some(&100i64));
343 }
344
345
346 #[test]
347 fn map_get_insert() {
348 let _mock = fvm_mock::build_runtime();
349 let mut map: HyperMap<i32, i32> = Default::default();
350 map.insert(1, 100);
351 map.insert(2, 200);
352 assert_eq!(map.len(), 2);
353 assert_eq!(map.get(&1), Some(&100));
354 map.write_ledger("map".as_bytes(), "invoke".as_bytes());
355 assert_eq!(runtime::storage_read(1.encode().as_slice(), "map".as_bytes()), Some(100.encode()));
357 assert_eq!(runtime::storage_read(2.encode().as_slice(), "map".as_bytes()), Some(200.encode()));
358 assert_eq!(runtime::storage_read(3.encode().as_slice(), "map".as_bytes()), None);
359 assert_eq!(runtime::storage_read("map".as_bytes(), "@HyperMap".as_bytes()), Some(2u64.encode()));
360 }
361
362 #[test]
363 fn map_delete_normal() {
364 let mock = fvm_mock::build_runtime();
365 let mut map: HyperMap<i32, i64> = Default::default();
366 map.origin_size = 1;
367 map.size = 1;
368 assert_eq!(map.remove(&1), None);
369
370 mock.storage_write(1.encode().as_slice(), "_".as_bytes(), 100i64.encode());
371 assert_eq!(map.remove(&1), Some(100i64));
372 }
373
374 #[test]
375 fn map_delete_complex() {
376 #[derive(Encode, Decode, Eq, PartialEq, Debug)]
377 struct Student {
378 id: u32,
379 name: String,
380 }
381
382 let _mock = fvm_mock::build_runtime();
383 let mut map: HyperMap<i32, Student> = Default::default();
384 map.insert(1, Student { id: 0, name: String::from("Xiao Ming") });
385 map.insert(2, Student { id: 1, name: String::from("Xiao Fang") });
386 assert_eq!(map.len(), 2);
387 assert_eq!(map.get(&1), Some(&Student { id: 0, name: String::from("Xiao Ming") }));
388
389 let old_value = map.remove(&1);
391 assert_eq!(old_value, Some(Student { id: 0, name: String::from("Xiao Ming") }));
392 assert_eq!(map.get(&1), None);
393
394 map.write_ledger("map".as_bytes(), "invoke".as_bytes());
395 assert_eq!(runtime::storage_read(1.encode().as_slice(), "map".as_bytes()), None);
397 assert_eq!(runtime::storage_read(2.encode().as_slice(), "map".as_bytes()), Some(vec![1, 0, 0, 0, 36, 88, 105, 97, 111, 32, 70, 97, 110, 103]));
398 assert_eq!(runtime::storage_read(3.encode().as_slice(), "map".as_bytes()), None);
399 assert_eq!(runtime::storage_read("map".as_bytes(), "@HyperMap".as_bytes()), Some(1u64.encode()));
400 }
401
402 #[test]
403 fn map_operate_many_times() {
404 let _mock = fvm_mock::build_runtime();
405 let mut map = HyperMap::new();
406 map.insert(String::from("abc"), String::from("def"));
408 map.insert(String::from("abc"), String::from("ggg"));
409 assert_eq!(map.get(&String::from("abc")), Some(&String::from("ggg")));
410
411 assert_eq!(map.get(&String::from("abc")), Some(&String::from("ggg")));
413 assert_eq!(map.get_mut(&String::from("abc")), Some(&mut String::from("ggg")));
414
415 let old = map.remove(&String::from("abc"));
417 assert_eq!(old, Some(String::from("ggg")));
418 let old = map.remove(&String::from("abc"));
419 assert_eq!(old, None);
420
421 map.write_ledger("map".as_bytes(), "deploy".as_bytes());
423 assert_eq!(runtime::storage_read("abc".encode().as_slice(), "map".as_bytes()), None);
424 assert_eq!(runtime::storage_read("map".as_bytes(), "@HyperMap".as_bytes()), Some(0u64.encode()));
425 }
426
427 #[test]
428 fn map_others_methods() {
429 let _mock = fvm_mock::build_runtime();
430 let mut map = HyperMap::new();
431 assert_eq!(map.is_empty(), true);
432 map.insert(b'A', 100);
433 map.insert(9, 200);
434 assert_eq!(map.is_empty(), false);
435 assert_eq!(map.len(), 2);
436
437 let key_value = map.get_key_value(&b'A');
438 assert!(key_value.is_some());
439 assert_eq!(key_value.unwrap().0, &b'A');
440 assert_eq!(key_value.unwrap().1, &100);
441 }
442}
443