1use std::any::type_name;
2use std::collections::HashMap;
3use std::convert::TryInto;
4use std::marker::PhantomData;
5use std::sync::Mutex;
6
7use serde::Deserialize;
8use serde::{de::DeserializeOwned, Serialize};
9
10use cosmwasm_std::{StdError, StdResult, Storage};
11use cosmwasm_storage::to_length_prefixed;
12
13use secret_toolkit_serialization::{Bincode2, Serde};
14
15use crate::{IterOption, WithIter, WithoutIter};
16
17const INDEXES: &[u8] = b"indexes";
18const MAP_LENGTH: &[u8] = b"length";
19
20const DEFAULT_PAGE_SIZE: u32 = 1;
21
22#[derive(Serialize, Deserialize)]
23struct InternalItem<T, Ser>
24where
25 T: Serialize + DeserializeOwned,
26 Ser: Serde,
27{
28 item_vec: Vec<u8>,
29 index_pos: Option<u32>,
31 item_type: PhantomData<T>,
32 serialization_type: PhantomData<Ser>,
33}
34
35impl<T: Serialize + DeserializeOwned, Ser: Serde> InternalItem<T, Ser> {
36 fn new(index_pos: Option<u32>, item: &T) -> StdResult<Self> {
37 Ok(Self {
38 item_vec: Ser::serialize(item)?,
39 index_pos,
40 item_type: PhantomData,
41 serialization_type: PhantomData,
42 })
43 }
44
45 fn get_item(&self) -> StdResult<T> {
46 Ser::deserialize(&self.item_vec)
47 }
48}
49
50pub struct KeymapBuilder<'a, K, T, Ser = Bincode2, I = WithIter> {
51 namespace: &'a [u8],
53 page_size: u32,
54 key_type: PhantomData<K>,
55 item_type: PhantomData<T>,
56 serialization_type: PhantomData<Ser>,
57 iter_option: PhantomData<I>,
58}
59
60impl<'a, K, T, Ser> KeymapBuilder<'a, K, T, Ser, WithIter>
61where
62 K: Serialize + DeserializeOwned,
63 T: Serialize + DeserializeOwned,
64 Ser: Serde,
65{
66 pub const fn new(namespace: &'a [u8]) -> Self {
68 Self {
69 namespace,
70 page_size: DEFAULT_PAGE_SIZE,
71 key_type: PhantomData,
72 item_type: PhantomData,
73 serialization_type: PhantomData,
74 iter_option: PhantomData,
75 }
76 }
77 pub const fn with_page_size(&self, indexes_size: u32) -> Self {
79 if indexes_size == 0 {
80 panic!("zero index page size used in keymap")
81 }
82 Self {
83 namespace: self.namespace,
84 page_size: indexes_size,
85 key_type: self.key_type,
86 item_type: self.item_type,
87 serialization_type: self.serialization_type,
88 iter_option: self.iter_option,
89 }
90 }
91 pub const fn without_iter(&self) -> KeymapBuilder<'a, K, T, Ser, WithoutIter> {
93 KeymapBuilder {
94 namespace: self.namespace,
95 page_size: self.page_size,
96 key_type: PhantomData,
97 item_type: PhantomData,
98 serialization_type: PhantomData,
99 iter_option: PhantomData,
100 }
101 }
102 pub const fn build(&self) -> Keymap<'a, K, T, Ser, WithIter> {
104 Keymap {
105 namespace: self.namespace,
106 prefix: None,
107 page_size: self.page_size,
108 length: Mutex::new(None),
109 key_type: self.key_type,
110 item_type: self.item_type,
111 iter_option: self.iter_option,
112 serialization_type: self.serialization_type,
113 }
114 }
115}
116
117impl<'a, K, T, Ser> KeymapBuilder<'a, K, T, Ser, WithoutIter>
119where
120 K: Serialize + DeserializeOwned,
121 T: Serialize + DeserializeOwned,
122 Ser: Serde,
123{
124 pub const fn build(&self) -> Keymap<'a, K, T, Ser, WithoutIter> {
125 Keymap {
126 namespace: self.namespace,
127 prefix: None,
128 page_size: self.page_size,
129 length: Mutex::new(None),
130 key_type: self.key_type,
131 item_type: self.item_type,
132 iter_option: self.iter_option,
133 serialization_type: self.serialization_type,
134 }
135 }
136}
137
138pub struct Keymap<'a, K, T, Ser = Bincode2, I = WithIter>
139where
140 K: Serialize + DeserializeOwned,
141 T: Serialize + DeserializeOwned,
142 Ser: Serde,
143 I: IterOption,
144{
145 namespace: &'a [u8],
147 prefix: Option<Vec<u8>>,
149 page_size: u32,
150 length: Mutex<Option<u32>>,
151 key_type: PhantomData<K>,
152 item_type: PhantomData<T>,
153 iter_option: PhantomData<I>,
154 serialization_type: PhantomData<Ser>,
155}
156
157impl<'a, K: Serialize + DeserializeOwned, T: Serialize + DeserializeOwned, Ser: Serde>
158 Keymap<'a, K, T, Ser>
159{
160 pub const fn new(namespace: &'a [u8]) -> Self {
162 Self {
163 namespace,
164 prefix: None,
165 page_size: DEFAULT_PAGE_SIZE,
166 length: Mutex::new(None),
167 key_type: PhantomData,
168 item_type: PhantomData,
169 serialization_type: PhantomData,
170 iter_option: PhantomData,
171 }
172 }
173
174 pub fn add_suffix(&self, suffix: &[u8]) -> Self {
177 let suffix = to_length_prefixed(suffix);
178 let prefix = self.prefix.as_deref().unwrap_or(self.namespace);
179 let prefix = [prefix, suffix.as_slice()].concat();
180 Self {
181 namespace: self.namespace,
182 prefix: Some(prefix),
183 page_size: self.page_size,
184 length: Mutex::new(None),
185 key_type: self.key_type,
186 item_type: self.item_type,
187 serialization_type: self.serialization_type,
188 iter_option: self.iter_option,
189 }
190 }
191}
192
193impl<K: Serialize + DeserializeOwned, T: Serialize + DeserializeOwned, Ser: Serde>
194 Keymap<'_, K, T, Ser, WithoutIter>
195{
196 fn serialize_key(&self, key: &K) -> StdResult<Vec<u8>> {
198 Ser::serialize(key)
199 }
200
201 pub fn get(&self, storage: &dyn Storage, key: &K) -> Option<T> {
203 self.get_from_key(storage, key).ok()
204 }
205
206 fn get_from_key(&self, storage: &dyn Storage, key: &K) -> StdResult<T> {
208 let key_vec = self.serialize_key(key)?;
209 self.load_impl(storage, &key_vec)
210 }
211
212 pub fn remove(&self, storage: &mut dyn Storage, key: &K) -> StdResult<()> {
214 let key_vec = self.serialize_key(key)?;
215 self.remove_impl(storage, &key_vec);
216
217 Ok(())
218 }
219
220 pub fn insert(&self, storage: &mut dyn Storage, key: &K, item: &T) -> StdResult<()> {
222 let key_vec = self.serialize_key(key)?;
223 self.save_impl(storage, &key_vec, item)
224 }
225
226 pub fn contains(&self, storage: &dyn Storage, key: &K) -> bool {
228 match self.serialize_key(key) {
229 Ok(key_vec) => self.contains_impl(storage, &key_vec),
230 Err(_) => false,
231 }
232 }
233}
234
235impl<'a, K: Serialize + DeserializeOwned, T: Serialize + DeserializeOwned, Ser: Serde>
236 Keymap<'a, K, T, Ser, WithIter>
237{
238 fn serialize_key(&self, key: &K) -> StdResult<Vec<u8>> {
240 Ser::serialize(key)
241 }
242
243 fn deserialize_key(&self, key_data: &[u8]) -> StdResult<K> {
245 Ser::deserialize(key_data)
246 }
247
248 fn page_from_position(&self, position: u32) -> u32 {
249 position / self.page_size
250 }
251
252 pub fn get_len(&self, storage: &dyn Storage) -> StdResult<u32> {
254 let mut may_len = self.length.lock().unwrap();
255 match *may_len {
256 Some(length) => Ok(length),
257 None => {
258 let len_key = [self.as_slice(), MAP_LENGTH].concat();
259 if let Some(len_vec) = storage.get(&len_key) {
260 let len_bytes = len_vec
261 .as_slice()
262 .try_into()
263 .map_err(|err| StdError::parse_err("u32", err))?;
264 let len = u32::from_be_bytes(len_bytes);
265 *may_len = Some(len);
266 Ok(len)
267 } else {
268 *may_len = Some(0);
269 Ok(0)
270 }
271 }
272 }
273 }
274
275 pub fn is_empty(&self, storage: &dyn Storage) -> StdResult<bool> {
277 Ok(self.get_len(storage)? == 0)
278 }
279
280 fn set_len(&self, storage: &mut dyn Storage, len: u32) -> StdResult<()> {
282 let len_key = [self.as_slice(), MAP_LENGTH].concat();
283 storage.set(&len_key, &len.to_be_bytes());
284
285 let mut may_len = self.length.lock().unwrap();
286 *may_len = Some(len);
287
288 Ok(())
289 }
290
291 fn get_indexes(&self, storage: &dyn Storage, page: u32) -> StdResult<Vec<Vec<u8>>> {
293 let indexes_key = [self.as_slice(), INDEXES, page.to_be_bytes().as_slice()].concat();
294 if self.page_size == 1 {
295 let maybe_item_data = storage.get(&indexes_key);
296 match maybe_item_data {
297 Some(item_data) => Ok(vec![item_data]),
298 None => Ok(vec![]),
299 }
300 } else {
301 let maybe_serialized = storage.get(&indexes_key);
302 match maybe_serialized {
303 Some(serialized) => Bincode2::deserialize(&serialized),
304 None => Ok(vec![]),
305 }
306 }
307 }
308
309 fn set_indexes_page(
311 &self,
312 storage: &mut dyn Storage,
313 page: u32,
314 indexes: &Vec<Vec<u8>>,
315 ) -> StdResult<()> {
316 let indexes_key = [self.as_slice(), INDEXES, page.to_be_bytes().as_slice()].concat();
317 if self.page_size == 1 {
318 if let Some(item_data) = indexes.first() {
319 storage.set(&indexes_key, item_data);
320 } else {
321 storage.remove(&indexes_key);
322 }
323 } else {
324 storage.set(&indexes_key, &Bincode2::serialize(indexes)?);
325 }
326 Ok(())
327 }
328
329 pub fn get(&self, storage: &dyn Storage, key: &K) -> Option<T> {
331 if let Ok(internal_item) = self.get_from_key(storage, key) {
332 internal_item.get_item().ok()
333 } else {
334 None
335 }
336 }
337
338 fn get_from_key(&self, storage: &dyn Storage, key: &K) -> StdResult<InternalItem<T, Ser>> {
340 let key_vec = self.serialize_key(key)?;
341 self.load_impl(storage, &key_vec)
342 }
343
344 pub fn remove(&self, storage: &mut dyn Storage, key: &K) -> StdResult<()> {
346 let key_vec = self.serialize_key(key)?;
347
348 let removed_pos = self.get_from_key(storage, key)?.index_pos.unwrap();
349
350 let page = self.page_from_position(removed_pos);
351
352 let mut len = self.get_len(storage)?;
353 len -= 1;
354 self.set_len(storage, len)?;
355
356 let mut indexes = self.get_indexes(storage, page)?;
357
358 let pos_in_indexes = (removed_pos % self.page_size) as usize;
359
360 if indexes[pos_in_indexes] != key_vec {
361 return Err(StdError::generic_err(
362 "tried to remove from keymap, but key not found in indexes - should never happen",
363 ));
364 }
365
366 if len == 0 || len == removed_pos {
368 indexes.pop();
369 self.set_indexes_page(storage, page, &indexes)?;
370 self.remove_impl(storage, &key_vec);
371 return Ok(());
372 }
373
374 let max_page = self.page_from_position(len);
376 if max_page == page {
377 let last_key = indexes.pop().ok_or_else(|| {
379 StdError::generic_err("last item's key not found - should never happen")
380 })?;
381 let mut last_internal_item = self.load_impl(storage, &last_key)?;
383 last_internal_item.index_pos = Some(removed_pos);
384 self.save_impl(storage, &last_key, &last_internal_item)?;
385 indexes[pos_in_indexes] = last_key;
387 self.set_indexes_page(storage, page, &indexes)?;
388 } else {
389 let mut last_page_indexes = self.get_indexes(storage, max_page)?;
390 let last_key = last_page_indexes.pop().ok_or_else(|| {
391 StdError::generic_err("last item's key not found - should never happen")
392 })?;
393 let mut last_internal_item = self.load_impl(storage, &last_key)?;
395 last_internal_item.index_pos = Some(removed_pos);
396 self.save_impl(storage, &last_key, &last_internal_item)?;
397 indexes[pos_in_indexes] = last_key;
399 self.set_indexes_page(storage, page, &indexes)?;
400 self.set_indexes_page(storage, max_page, &last_page_indexes)?;
401 }
402
403 self.remove_impl(storage, &key_vec);
404
405 Ok(())
406 }
407
408 pub fn insert(&self, storage: &mut dyn Storage, key: &K, item: &T) -> StdResult<()> {
410 let key_vec = self.serialize_key(key)?;
411
412 match self.may_load_impl(storage, &key_vec)? {
413 Some(existing_internal_item) => {
414 let new_internal_item = InternalItem::new(existing_internal_item.index_pos, item)?;
416 self.save_impl(storage, &key_vec, &new_internal_item)
417 }
418 None => {
419 let pos = self.get_len(storage)?;
421 self.set_len(storage, pos + 1)?;
422 let page = self.page_from_position(pos);
423 let internal_item = InternalItem::new(Some(pos), item)?;
425 self.save_impl(storage, &key_vec, &internal_item)?;
426 let mut indexes = self.get_indexes(storage, page)?;
428 indexes.push(key_vec);
429 self.set_indexes_page(storage, page, &indexes)
430 }
431 }
432 }
433
434 pub fn contains(&self, storage: &dyn Storage, key: &K) -> bool {
436 match self.serialize_key(key) {
437 Ok(key_vec) => self.contains_impl(storage, &key_vec),
438 Err(_) => false,
439 }
440 }
441
442 pub fn paging(
444 &self,
445 storage: &dyn Storage,
446 start_page: u32,
447 size: u32,
448 ) -> StdResult<Vec<(K, T)>> {
449 let start_pos = start_page * size;
450
451 let max_size = self.get_len(storage)?;
452
453 if max_size == 0 {
454 return Ok(vec![]);
455 }
456
457 if start_pos > max_size {
458 return Err(StdError::not_found("out of bounds"));
459 }
460
461 self.iter(storage)?
462 .skip(start_pos as usize)
463 .take(size as usize)
464 .collect()
465 }
466
467 pub fn paging_keys(
469 &self,
470 storage: &dyn Storage,
471 start_page: u32,
472 size: u32,
473 ) -> StdResult<Vec<K>> {
474 let start_pos = start_page * size;
475
476 let max_size = self.get_len(storage)?;
477
478 if max_size == 0 {
479 return Ok(vec![]);
480 }
481
482 if start_pos > max_size {
483 return Err(StdError::not_found("out of bounds"));
484 }
485
486 self.iter_keys(storage)?
487 .skip(start_pos as usize)
488 .take(size as usize)
489 .collect()
490 }
491
492 pub fn iter_keys(&self, storage: &'a dyn Storage) -> StdResult<KeyIter<K, T, Ser>> {
494 let len = self.get_len(storage)?;
495 let iter = KeyIter::new(self, storage, 0, len);
496 Ok(iter)
497 }
498
499 pub fn iter(&self, storage: &'a dyn Storage) -> StdResult<KeyItemIter<K, T, Ser>> {
501 let len = self.get_len(storage)?;
502 let iter = KeyItemIter::new(self, storage, 0, len);
503 Ok(iter)
504 }
505}
506
507impl<K: Serialize + DeserializeOwned, T: Serialize + DeserializeOwned, Ser: Serde>
508 PrefixedTypedStorage<InternalItem<T, Ser>, Bincode2> for Keymap<'_, K, T, Ser, WithIter>
509{
510 fn as_slice(&self) -> &[u8] {
511 if let Some(prefix) = &self.prefix {
512 prefix
513 } else {
514 self.namespace
515 }
516 }
517}
518
519impl<K: Serialize + DeserializeOwned, T: Serialize + DeserializeOwned, Ser: Serde>
520 PrefixedTypedStorage<T, Ser> for Keymap<'_, K, T, Ser, WithoutIter>
521{
522 fn as_slice(&self) -> &[u8] {
523 if let Some(prefix) = &self.prefix {
524 prefix
525 } else {
526 self.namespace
527 }
528 }
529}
530
531pub struct KeyIter<'a, K, T, Ser>
533where
534 K: Serialize + DeserializeOwned,
535 T: Serialize + DeserializeOwned,
536 Ser: Serde,
537{
538 keymap: &'a Keymap<'a, K, T, Ser>,
539 storage: &'a dyn Storage,
540 start: u32,
541 end: u32,
542 cache: HashMap<u32, Vec<Vec<u8>>>,
543}
544
545impl<'a, K, T, Ser> KeyIter<'a, K, T, Ser>
546where
547 K: Serialize + DeserializeOwned,
548 T: Serialize + DeserializeOwned,
549 Ser: Serde,
550{
551 pub fn new(
553 keymap: &'a Keymap<'a, K, T, Ser>,
554 storage: &'a dyn Storage,
555 start: u32,
556 end: u32,
557 ) -> Self {
558 Self {
559 keymap,
560 storage,
561 start,
562 end,
563 cache: HashMap::new(),
564 }
565 }
566}
567
568impl<K, T, Ser> Iterator for KeyIter<'_, K, T, Ser>
569where
570 K: Serialize + DeserializeOwned,
571 T: Serialize + DeserializeOwned,
572 Ser: Serde,
573{
574 type Item = StdResult<K>;
575
576 fn next(&mut self) -> Option<Self::Item> {
577 if self.start >= self.end {
578 return None;
579 }
580
581 let key;
582 let page = self.keymap.page_from_position(self.start);
583 let indexes_pos = (self.start % self.keymap.page_size) as usize;
584
585 match self.cache.get(&page) {
586 Some(indexes) => {
587 let key_data = &indexes[indexes_pos];
588 key = self.keymap.deserialize_key(key_data);
589 }
590 None => match self.keymap.get_indexes(self.storage, page) {
591 Ok(indexes) => {
592 let key_data = &indexes[indexes_pos];
593 key = self.keymap.deserialize_key(key_data);
594 self.cache.insert(page, indexes);
595 }
596 Err(e) => key = Err(e),
597 },
598 }
599 self.start += 1;
600 Some(key)
601 }
602
603 fn size_hint(&self) -> (usize, Option<usize>) {
605 let len = (self.end - self.start) as usize;
606 (len, Some(len))
607 }
608
609 fn nth(&mut self, n: usize) -> Option<Self::Item> {
616 self.start = self.start.saturating_add(n as u32);
617 self.next()
618 }
619}
620
621impl<K, T, Ser> DoubleEndedIterator for KeyIter<'_, K, T, Ser>
622where
623 K: Serialize + DeserializeOwned,
624 T: Serialize + DeserializeOwned,
625 Ser: Serde,
626{
627 fn next_back(&mut self) -> Option<Self::Item> {
628 if self.start >= self.end {
629 return None;
630 }
631 self.end -= 1;
632
633 let key;
634 let page = self.keymap.page_from_position(self.end);
635 let indexes_pos = (self.end % self.keymap.page_size) as usize;
636
637 match self.cache.get(&page) {
638 Some(indexes) => {
639 let key_data = &indexes[indexes_pos];
640 key = self.keymap.deserialize_key(key_data);
641 }
642 None => match self.keymap.get_indexes(self.storage, page) {
643 Ok(indexes) => {
644 let key_data = &indexes[indexes_pos];
645 key = self.keymap.deserialize_key(key_data);
646 self.cache.insert(page, indexes);
647 }
648 Err(e) => key = Err(e),
649 },
650 }
651 Some(key)
652 }
653
654 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
661 self.end = self.end.saturating_sub(n as u32);
662 self.next_back()
663 }
664}
665
666impl<K, T, Ser> ExactSizeIterator for KeyIter<'_, K, T, Ser>
668where
669 K: Serialize + DeserializeOwned,
670 T: Serialize + DeserializeOwned,
671 Ser: Serde,
672{
673}
674
675pub struct KeyItemIter<'a, K, T, Ser>
679where
680 K: Serialize + DeserializeOwned,
681 T: Serialize + DeserializeOwned,
682 Ser: Serde,
683{
684 keymap: &'a Keymap<'a, K, T, Ser>,
685 storage: &'a dyn Storage,
686 start: u32,
687 end: u32,
688 cache: HashMap<u32, Vec<Vec<u8>>>,
689}
690
691impl<'a, K, T, Ser> KeyItemIter<'a, K, T, Ser>
692where
693 K: Serialize + DeserializeOwned,
694 T: Serialize + DeserializeOwned,
695 Ser: Serde,
696{
697 pub fn new(
699 keymap: &'a Keymap<'a, K, T, Ser>,
700 storage: &'a dyn Storage,
701 start: u32,
702 end: u32,
703 ) -> Self {
704 Self {
705 keymap,
706 storage,
707 start,
708 end,
709 cache: HashMap::new(),
710 }
711 }
712}
713
714impl<K, T, Ser> Iterator for KeyItemIter<'_, K, T, Ser>
715where
716 K: Serialize + DeserializeOwned,
717 T: Serialize + DeserializeOwned,
718 Ser: Serde,
719{
720 type Item = StdResult<(K, T)>;
721
722 fn next(&mut self) -> Option<Self::Item> {
723 if self.start >= self.end {
724 return None;
725 }
726
727 let key;
728 let page = self.keymap.page_from_position(self.start);
729 let indexes_pos = (self.start % self.keymap.page_size) as usize;
730
731 match self.cache.get(&page) {
732 Some(indexes) => {
733 let key_data = &indexes[indexes_pos];
734 key = self.keymap.deserialize_key(key_data);
735 }
736 None => match self.keymap.get_indexes(self.storage, page) {
737 Ok(indexes) => {
738 let key_data = &indexes[indexes_pos];
739 key = self.keymap.deserialize_key(key_data);
740 self.cache.insert(page, indexes);
741 }
742 Err(e) => key = Err(e),
743 },
744 }
745 self.start += 1;
746 let pair = match key {
748 Ok(k) => match self.keymap.get_from_key(self.storage, &k) {
749 Ok(internal_item) => match internal_item.get_item() {
750 Ok(item) => Ok((k, item)),
751 Err(e) => Err(e),
752 },
753 Err(e) => Err(e),
754 },
755 Err(e) => Err(e),
756 };
757 Some(pair)
758 }
759
760 fn size_hint(&self) -> (usize, Option<usize>) {
762 let len = (self.end - self.start) as usize;
763 (len, Some(len))
764 }
765
766 fn nth(&mut self, n: usize) -> Option<Self::Item> {
773 self.start = self.start.saturating_add(n as u32);
774 self.next()
775 }
776}
777
778impl<K, T, Ser> DoubleEndedIterator for KeyItemIter<'_, K, T, Ser>
779where
780 K: Serialize + DeserializeOwned,
781 T: Serialize + DeserializeOwned,
782 Ser: Serde,
783{
784 fn next_back(&mut self) -> Option<Self::Item> {
785 if self.start >= self.end {
786 return None;
787 }
788 self.end -= 1;
789
790 let key;
791 let page = self.keymap.page_from_position(self.end);
792 let indexes_pos = (self.end % self.keymap.page_size) as usize;
793
794 match self.cache.get(&page) {
795 Some(indexes) => {
796 let key_data = &indexes[indexes_pos];
797 key = self.keymap.deserialize_key(key_data);
798 }
799 None => match self.keymap.get_indexes(self.storage, page) {
800 Ok(indexes) => {
801 let key_data = &indexes[indexes_pos];
802 key = self.keymap.deserialize_key(key_data);
803 self.cache.insert(page, indexes);
804 }
805 Err(e) => key = Err(e),
806 },
807 }
808 let pair = match key {
810 Ok(k) => match self.keymap.get_from_key(self.storage, &k) {
811 Ok(internal_item) => match internal_item.get_item() {
812 Ok(item) => Ok((k, item)),
813 Err(e) => Err(e),
814 },
815 Err(e) => Err(e),
816 },
817 Err(e) => Err(e),
818 };
819 Some(pair)
820 }
821
822 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
829 self.end = self.end.saturating_sub(n as u32);
830 self.next_back()
831 }
832}
833
834impl<K, T, Ser> ExactSizeIterator for KeyItemIter<'_, K, T, Ser>
836where
837 K: Serialize + DeserializeOwned,
838 T: Serialize + DeserializeOwned,
839 Ser: Serde,
840{
841}
842
843trait PrefixedTypedStorage<T: Serialize + DeserializeOwned, Ser: Serde> {
844 fn as_slice(&self) -> &[u8];
845
846 fn contains_impl(&self, storage: &dyn Storage, key: &[u8]) -> bool {
853 let prefixed_key = [self.as_slice(), key].concat();
854 storage.get(&prefixed_key).is_some()
855 }
856
857 fn load_impl(&self, storage: &dyn Storage, key: &[u8]) -> StdResult<T> {
865 let prefixed_key = [self.as_slice(), key].concat();
866 Ser::deserialize(
867 &storage
868 .get(&prefixed_key)
869 .ok_or_else(|| StdError::not_found(type_name::<T>()))?,
870 )
871 }
872
873 fn may_load_impl(&self, storage: &dyn Storage, key: &[u8]) -> StdResult<Option<T>> {
881 let prefixed_key = [self.as_slice(), key].concat();
882 match storage.get(&prefixed_key) {
883 Some(value) => Ser::deserialize(&value).map(Some),
884 None => Ok(None),
885 }
886 }
887
888 fn save_impl(&self, storage: &mut dyn Storage, key: &[u8], value: &T) -> StdResult<()> {
896 let prefixed_key = [self.as_slice(), key].concat();
897 storage.set(&prefixed_key, &Ser::serialize(value)?);
898 Ok(())
899 }
900
901 fn remove_impl(&self, storage: &mut dyn Storage, key: &[u8]) {
908 let prefixed_key = [self.as_slice(), key].concat();
909 storage.remove(&prefixed_key);
910 }
911}
912
913#[cfg(test)]
914mod tests {
915 use secret_toolkit_serialization::Json;
916 use serde::{Deserialize, Serialize};
917
918 use cosmwasm_std::testing::MockStorage;
919
920 use super::*;
921
922 #[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)]
923 struct Foo {
924 string: String,
925 number: i32,
926 }
927 #[test]
928 fn test_keymap_perf_insert() -> StdResult<()> {
929 let mut storage = MockStorage::new();
930
931 let total_items: i32 = 1000;
932
933 let keymap: Keymap<Vec<u8>, i32> = Keymap::new(b"test");
934
935 for i in 0..total_items {
936 let key: Vec<u8> = i.to_be_bytes().to_vec();
937 keymap.insert(&mut storage, &key, &i)?;
938 }
939
940 assert_eq!(keymap.get_len(&storage)?, 1000);
941
942 Ok(())
943 }
944
945 #[test]
946 fn test_keymap_perf_insert_remove() -> StdResult<()> {
947 let mut storage = MockStorage::new();
948
949 let total_items = 100;
950
951 let keymap: Keymap<i32, i32> = Keymap::new(b"test");
952
953 for i in 0..total_items {
954 keymap.insert(&mut storage, &i, &i)?;
955 }
956
957 for i in 0..total_items {
958 keymap.remove(&mut storage, &i)?;
959 }
960
961 assert_eq!(keymap.get_len(&storage)?, 0);
962
963 Ok(())
964 }
965
966 #[test]
967 fn test_keymap_paging() -> StdResult<()> {
968 let mut storage = MockStorage::new();
969
970 let page_size: u32 = 5;
971 let total_items: u32 = 50;
972 let keymap: Keymap<Vec<u8>, u32> = Keymap::new(b"test");
973
974 for i in 0..total_items {
975 let key: Vec<u8> = (i as i32).to_be_bytes().to_vec();
976 keymap.insert(&mut storage, &key, &i)?;
977 }
978
979 for i in 0..((total_items / page_size) - 1) {
980 let start_page = i;
981
982 let values = keymap.paging(&storage, start_page, page_size)?;
983
984 for (index, (key_value, value)) in values.iter().enumerate() {
985 let i = page_size * start_page + index as u32;
986 let key: Vec<u8> = (i as i32).to_be_bytes().to_vec();
987 assert_eq!(key_value, &key);
988 assert_eq!(value, &i);
989 }
990 }
991
992 Ok(())
993 }
994
995 #[test]
996 fn test_keymap_paging_overflow() -> StdResult<()> {
997 let mut storage = MockStorage::new();
998
999 let page_size = 50;
1000 let total_items = 10;
1001 let keymap: Keymap<i32, u32> = Keymap::new(b"test");
1002
1003 for i in 0..total_items {
1004 keymap.insert(&mut storage, &(i as i32), &i)?;
1005 }
1006
1007 let values = keymap.paging_keys(&storage, 0, page_size)?;
1008
1009 assert_eq!(values.len(), total_items as usize);
1010
1011 for (index, value) in values.iter().enumerate() {
1012 assert_eq!(value, &(index as i32))
1013 }
1014
1015 Ok(())
1016 }
1017
1018 #[test]
1019 fn test_keymap_insert_multiple() -> StdResult<()> {
1020 let mut storage = MockStorage::new();
1021
1022 let keymap: Keymap<Vec<u8>, Foo> = Keymap::new(b"test");
1023 let foo1 = Foo {
1024 string: "string one".to_string(),
1025 number: 1111,
1026 };
1027 let foo2 = Foo {
1028 string: "string two".to_string(),
1029 number: 1111,
1030 };
1031
1032 keymap.insert(&mut storage, &b"key1".to_vec(), &foo1)?;
1033 keymap.insert(&mut storage, &b"key2".to_vec(), &foo2)?;
1034
1035 let read_foo1 = keymap.get(&storage, &b"key1".to_vec()).unwrap();
1036 let read_foo2 = keymap.get(&storage, &b"key2".to_vec()).unwrap();
1037
1038 assert_eq!(foo1, read_foo1);
1039 assert_eq!(foo2, read_foo2);
1040 Ok(())
1041 }
1042
1043 #[test]
1044 fn test_keymap_contains() -> StdResult<()> {
1045 let mut storage = MockStorage::new();
1046
1047 let keymap: Keymap<Vec<u8>, Foo> = Keymap::new(b"test");
1048 let foo1 = Foo {
1049 string: "string one".to_string(),
1050 number: 1111,
1051 };
1052
1053 keymap.insert(&mut storage, &b"key1".to_vec(), &foo1)?;
1054 let contains_k1 = keymap.contains(&storage, &b"key1".to_vec());
1055
1056 assert!(contains_k1);
1057
1058 Ok(())
1059 }
1060
1061 #[test]
1062 fn test_keymap_iter() -> StdResult<()> {
1063 let mut storage = MockStorage::new();
1064
1065 let keymap: Keymap<Vec<u8>, Foo> = Keymap::new(b"test");
1066 let foo1 = Foo {
1067 string: "string one".to_string(),
1068 number: 1111,
1069 };
1070 let foo2 = Foo {
1071 string: "string two".to_string(),
1072 number: 1111,
1073 };
1074
1075 keymap.insert(&mut storage, &b"key1".to_vec(), &foo1)?;
1076 keymap.insert(&mut storage, &b"key2".to_vec(), &foo2)?;
1077
1078 let mut x = keymap.iter(&storage)?;
1079 let (len, _) = x.size_hint();
1080 assert_eq!(len, 2);
1081
1082 assert_eq!(x.next().unwrap()?, (b"key1".to_vec(), foo1));
1083
1084 assert_eq!(x.next().unwrap()?, (b"key2".to_vec(), foo2));
1085
1086 Ok(())
1087 }
1088
1089 #[test]
1090 fn test_keymap_iter_keys() -> StdResult<()> {
1091 let mut storage = MockStorage::new();
1092
1093 let keymap: Keymap<String, Foo> = Keymap::new(b"test");
1094 let foo1 = Foo {
1095 string: "string one".to_string(),
1096 number: 1111,
1097 };
1098 let foo2 = Foo {
1099 string: "string two".to_string(),
1100 number: 1111,
1101 };
1102
1103 let key1 = "key1".to_string();
1104 let key2 = "key2".to_string();
1105
1106 keymap.insert(&mut storage, &key1, &foo1)?;
1107 keymap.insert(&mut storage, &key2, &foo2)?;
1108
1109 let mut x = keymap.iter_keys(&storage)?;
1110 let (len, _) = x.size_hint();
1111 assert_eq!(len, 2);
1112
1113 assert_eq!(x.next().unwrap()?, key1);
1114
1115 assert_eq!(x.next().unwrap()?, key2);
1116
1117 Ok(())
1118 }
1119
1120 #[test]
1121 fn test_keymap_overwrite() -> StdResult<()> {
1122 let mut storage = MockStorage::new();
1123
1124 let keymap: Keymap<Vec<u8>, Foo> = Keymap::new(b"test");
1125 let foo1 = Foo {
1126 string: "string one".to_string(),
1127 number: 1111,
1128 };
1129 let foo2 = Foo {
1130 string: "string two".to_string(),
1131 number: 2222,
1132 };
1133
1134 keymap.insert(&mut storage, &b"key1".to_vec(), &foo1)?;
1135 keymap.insert(&mut storage, &b"key1".to_vec(), &foo2)?;
1136
1137 let foo3 = keymap.get(&storage, &b"key1".to_vec()).unwrap();
1138
1139 assert_eq!(foo3, foo2);
1140
1141 Ok(())
1142 }
1143
1144 #[test]
1145 fn test_keymap_suffixed_basics() -> StdResult<()> {
1146 let mut storage = MockStorage::new();
1147
1148 let original_keymap: Keymap<String, Foo> = Keymap::new(b"test");
1149 let keymap = original_keymap.add_suffix(b"test_suffix");
1150 let foo1 = Foo {
1151 string: "string one".to_string(),
1152 number: 1111,
1153 };
1154 let foo2 = Foo {
1155 string: "string one".to_string(),
1156 number: 1111,
1157 };
1158 keymap.insert(&mut storage, &"key1".to_string(), &foo1)?;
1159 keymap.insert(&mut storage, &"key2".to_string(), &foo2)?;
1160
1161 let read_foo1 = keymap.get(&storage, &"key1".to_string()).unwrap();
1162 let read_foo2 = keymap.get(&storage, &"key2".to_string()).unwrap();
1163
1164 assert_eq!(original_keymap.get_len(&storage)?, 0);
1165 assert_eq!(foo1, read_foo1);
1166 assert_eq!(foo2, read_foo2);
1167
1168 let alternative_keymap: Keymap<String, Foo> = Keymap::new(b"alternative");
1169 let alt_same_suffix = alternative_keymap.add_suffix(b"test_suffix");
1170
1171 assert!(alt_same_suffix.is_empty(&storage)?);
1172
1173 let before_remove_foo1 = keymap.get(&storage, &"key1".to_string());
1175 assert!(before_remove_foo1.is_some());
1176 assert_eq!(foo1, before_remove_foo1.unwrap());
1177 keymap.remove(&mut storage, &"key1".to_string())?;
1179 let removed_foo1 = keymap.get(&storage, &"key1".to_string());
1180 assert!(removed_foo1.is_none());
1181
1182 assert!(keymap.get(&storage, &"key3".to_string()).is_none());
1184
1185 Ok(())
1186 }
1187
1188 #[test]
1189 fn test_keymap_length() -> StdResult<()> {
1190 test_keymap_length_with_page_size(1)?;
1191 test_keymap_length_with_page_size(5)?;
1192 test_keymap_length_with_page_size(13)?;
1193 Ok(())
1194 }
1195
1196 fn test_keymap_length_with_page_size(page_size: u32) -> StdResult<()> {
1197 let mut storage = MockStorage::new();
1198
1199 let keymap: Keymap<String, Foo> = KeymapBuilder::new(b"test")
1200 .with_page_size(page_size)
1201 .build();
1202 let foo1 = Foo {
1203 string: "string one".to_string(),
1204 number: 1111,
1205 };
1206 let foo2 = Foo {
1207 string: "string one".to_string(),
1208 number: 1111,
1209 };
1210
1211 assert!(keymap.length.lock().unwrap().eq(&None));
1212 assert_eq!(keymap.get_len(&storage)?, 0);
1213 assert!(keymap.length.lock().unwrap().eq(&Some(0)));
1214
1215 let key1 = "k1".to_string();
1216 let key2 = "k2".to_string();
1217
1218 keymap.insert(&mut storage, &key1, &foo1)?;
1219 assert_eq!(keymap.get_len(&storage)?, 1);
1220 assert!(keymap.length.lock().unwrap().eq(&Some(1)));
1221
1222 keymap.insert(&mut storage, &key2, &foo2)?;
1224 assert_eq!(keymap.get_len(&storage)?, 2);
1225 assert!(keymap.length.lock().unwrap().eq(&Some(2)));
1226
1227 keymap.remove(&mut storage, &key1)?;
1229 assert_eq!(keymap.get_len(&storage)?, 1);
1230 assert!(keymap.length.lock().unwrap().eq(&Some(1)));
1231
1232 keymap.insert(&mut storage, &key2, &foo1)?;
1234 assert_eq!(keymap.get_len(&storage)?, 1);
1235 assert!(keymap.length.lock().unwrap().eq(&Some(1)));
1236
1237 keymap.remove(&mut storage, &key2)?;
1239 assert_eq!(keymap.get_len(&storage)?, 0);
1240 assert!(keymap.length.lock().unwrap().eq(&Some(0)));
1241
1242 Ok(())
1243 }
1244
1245 #[test]
1246 fn test_keymap_without_iter() -> StdResult<()> {
1247 test_keymap_without_iter_custom_page(1)?;
1248 test_keymap_without_iter_custom_page(2)?;
1249 test_keymap_without_iter_custom_page(3)?;
1250 Ok(())
1251 }
1252
1253 fn test_keymap_without_iter_custom_page(page_size: u32) -> StdResult<()> {
1254 let mut storage = MockStorage::new();
1255
1256 let keymap: Keymap<String, Foo, Json, _> = KeymapBuilder::new(b"test")
1257 .with_page_size(page_size)
1258 .without_iter()
1259 .build();
1260
1261 let foo1 = Foo {
1262 string: "string one".to_string(),
1263 number: 1111,
1264 };
1265 let foo2 = Foo {
1266 string: "string one".to_string(),
1267 number: 1111,
1268 };
1269 keymap.insert(&mut storage, &"key1".to_string(), &foo1)?;
1270 keymap.insert(&mut storage, &"key2".to_string(), &foo2)?;
1271
1272 let read_foo1 = keymap.get(&storage, &"key1".to_string()).unwrap();
1273 let read_foo2 = keymap.get(&storage, &"key2".to_string()).unwrap();
1274
1275 assert_eq!(foo1, read_foo1);
1276 assert_eq!(foo2, read_foo2);
1277 assert!(keymap.contains(&storage, &"key1".to_string()));
1278
1279 keymap.remove(&mut storage, &"key1".to_string())?;
1280
1281 let read_foo1 = keymap.get(&storage, &"key1".to_string());
1282 let read_foo2 = keymap.get(&storage, &"key2".to_string()).unwrap();
1283
1284 assert!(read_foo1.is_none());
1285 assert_eq!(foo2, read_foo2);
1286
1287 Ok(())
1288 }
1289
1290 #[test]
1291 fn test_keymap_custom_paging() -> StdResult<()> {
1292 let mut storage = MockStorage::new();
1293
1294 let page_size: u32 = 5;
1295 let total_items: u32 = 50;
1296 let keymap: Keymap<Vec<u8>, u32> = KeymapBuilder::new(b"test").with_page_size(13).build();
1297
1298 for i in 0..total_items {
1299 let key: Vec<u8> = (i as i32).to_be_bytes().to_vec();
1300 keymap.insert(&mut storage, &key, &i)?;
1301 }
1302
1303 for i in 0..((total_items / page_size) - 1) {
1304 let start_page = i;
1305
1306 let values = keymap.paging(&storage, start_page, page_size)?;
1307
1308 for (index, (key_value, value)) in values.iter().enumerate() {
1309 let i = page_size * start_page + index as u32;
1310 let key: Vec<u8> = (i as i32).to_be_bytes().to_vec();
1311 assert_eq!(key_value, &key);
1312 assert_eq!(value, &i);
1313 }
1314 }
1315
1316 Ok(())
1317 }
1318
1319 #[test]
1320 fn test_keymap_custom_paging_overflow() -> StdResult<()> {
1321 let mut storage = MockStorage::new();
1322
1323 let page_size = 50;
1324 let total_items = 10;
1325 let keymap: Keymap<i32, u32, Json> = KeymapBuilder::new(b"test").with_page_size(3).build();
1326
1327 for i in 0..total_items {
1328 keymap.insert(&mut storage, &(i as i32), &i)?;
1329 }
1330
1331 let values = keymap.paging_keys(&storage, 0, page_size)?;
1332
1333 assert_eq!(values.len(), total_items as usize);
1334
1335 for (index, value) in values.iter().enumerate() {
1336 assert_eq!(value, &(index as i32))
1337 }
1338
1339 Ok(())
1340 }
1341
1342 #[test]
1343 fn test_keymap_custom_page_iter() -> StdResult<()> {
1344 let mut storage = MockStorage::new();
1345
1346 let keymap: Keymap<Vec<u8>, Foo> = KeymapBuilder::new(b"test").with_page_size(2).build();
1347 let foo1 = Foo {
1348 string: "string one".to_string(),
1349 number: 1111,
1350 };
1351 let foo2 = Foo {
1352 string: "string two".to_string(),
1353 number: 1111,
1354 };
1355 let foo3 = Foo {
1356 string: "string three".to_string(),
1357 number: 1111,
1358 };
1359
1360 keymap.insert(&mut storage, &b"key1".to_vec(), &foo1)?;
1361 keymap.insert(&mut storage, &b"key2".to_vec(), &foo2)?;
1362 keymap.insert(&mut storage, &b"key3".to_vec(), &foo3)?;
1363
1364 let mut x = keymap.iter(&storage)?;
1365 let (len, _) = x.size_hint();
1366 assert_eq!(len, 3);
1367
1368 assert_eq!(x.next().unwrap()?, (b"key1".to_vec(), foo1));
1369
1370 assert_eq!(x.next().unwrap()?, (b"key2".to_vec(), foo2));
1371
1372 assert_eq!(x.next().unwrap()?, (b"key3".to_vec(), foo3));
1373
1374 assert_eq!(x.next(), None);
1375
1376 Ok(())
1377 }
1378
1379 #[test]
1380 fn test_keymap_reverse_iter() -> StdResult<()> {
1381 test_keymap_custom_page_reverse_iterator(1)?;
1382 test_keymap_custom_page_reverse_iterator(2)?;
1383 test_keymap_custom_page_reverse_iterator(5)?;
1384 test_keymap_custom_page_reverse_iterator(25)?;
1385 Ok(())
1386 }
1387
1388 fn test_keymap_custom_page_reverse_iterator(page_size: u32) -> StdResult<()> {
1389 let mut storage = MockStorage::new();
1390 let keymap: Keymap<i32, i32> = KeymapBuilder::new(b"test")
1391 .with_page_size(page_size)
1392 .build();
1393 keymap.insert(&mut storage, &1234, &1234)?;
1394 keymap.insert(&mut storage, &2143, &2143)?;
1395 keymap.insert(&mut storage, &3412, &3412)?;
1396 keymap.insert(&mut storage, &4321, &4321)?;
1397
1398 let mut iter = keymap.iter(&storage)?.rev();
1399 assert_eq!(iter.next(), Some(Ok((4321, 4321))));
1400 assert_eq!(iter.next(), Some(Ok((3412, 3412))));
1401 assert_eq!(iter.next(), Some(Ok((2143, 2143))));
1402 assert_eq!(iter.next(), Some(Ok((1234, 1234))));
1403 assert_eq!(iter.next(), None);
1404
1405 let mut iter = keymap.iter(&storage)?.rev();
1407 assert_eq!(iter.next(), Some(Ok((4321, 4321))));
1408 assert_eq!(iter.next(), Some(Ok((3412, 3412))));
1409 assert_eq!(iter.next(), Some(Ok((2143, 2143))));
1410 assert_eq!(iter.next(), Some(Ok((1234, 1234))));
1411 assert_eq!(iter.next(), None);
1412
1413 let mut iter = keymap.iter(&storage)?.rev().skip(2);
1415 assert_eq!(iter.next(), Some(Ok((2143, 2143))));
1416 assert_eq!(iter.next(), Some(Ok((1234, 1234))));
1417 assert_eq!(iter.next(), None);
1418
1419 let mut iter = keymap.iter(&storage)?.skip(2).rev();
1421 assert_eq!(iter.next(), Some(Ok((4321, 4321))));
1422 assert_eq!(iter.next(), Some(Ok((3412, 3412))));
1423 assert_eq!(iter.next(), None);
1424
1425 Ok(())
1426 }
1427
1428 #[test]
1429 fn test_serializations() -> StdResult<()> {
1430 test_serializations_with_page_size(1)?;
1431 test_serializations_with_page_size(3)?;
1432 test_serializations_with_page_size(19)?;
1433 Ok(())
1434 }
1435
1436 fn test_serializations_with_page_size(page_size: u32) -> StdResult<()> {
1437 let mut storage = MockStorage::new();
1439
1440 let keymap: Keymap<i32, i32> = KeymapBuilder::new(b"test")
1441 .with_page_size(page_size)
1442 .build();
1443 keymap.insert(&mut storage, &1234, &1234)?;
1444
1445 let page_key = [keymap.as_slice(), INDEXES, &0_u32.to_be_bytes()].concat();
1446 if keymap.page_size == 1 {
1447 let item_data = storage.get(&page_key);
1448 let expected_data = Bincode2::serialize(&1234)?;
1449 assert_eq!(item_data, Some(expected_data));
1450 } else {
1451 let page_bytes = storage.get(&page_key);
1452 let expected_bincode2 = Bincode2::serialize(&vec![Bincode2::serialize(&1234)?])?;
1453 assert_eq!(page_bytes, Some(expected_bincode2));
1454 }
1455
1456 let mut storage = MockStorage::new();
1458 let json_keymap: Keymap<i32, i32, Json> = KeymapBuilder::new(b"test2")
1459 .with_page_size(page_size)
1460 .build();
1461 json_keymap.insert(&mut storage, &1234, &1234)?;
1462
1463 let key = [json_keymap.as_slice(), INDEXES, &0_u32.to_be_bytes()].concat();
1464 if json_keymap.page_size == 1 {
1465 let item_data = storage.get(&key);
1466 let expected = b"1234".to_vec();
1467 assert_eq!(item_data, Some(expected));
1468 } else {
1469 let bytes = storage.get(&key);
1470 let expected = Bincode2::serialize(&vec![b"1234".to_vec()])?;
1471 assert_eq!(bytes, Some(expected));
1472 }
1473
1474 Ok(())
1475 }
1476
1477 #[test]
1478 fn test_keymap_paging_last_page() -> StdResult<()> {
1479 let mut storage = MockStorage::new();
1480
1481 let total_items: u32 = 20;
1482 let keymap: Keymap<Vec<u8>, u32> = Keymap::new(b"test");
1483
1484 for i in 0..total_items {
1485 let key: Vec<u8> = (i as i32).to_be_bytes().to_vec();
1486 keymap.insert(&mut storage, &key, &i)?;
1487 }
1488
1489 assert_eq!(keymap.paging(&storage, 0, 23)?.len(), 20);
1490 assert_eq!(keymap.paging_keys(&storage, 0, 23)?.len(), 20);
1491 assert_eq!(keymap.paging(&storage, 2, 8)?.len(), 4);
1492 assert_eq!(keymap.paging_keys(&storage, 2, 8)?.len(), 4);
1493 assert_eq!(keymap.paging(&storage, 2, 7)?.len(), 6);
1494 assert_eq!(keymap.paging_keys(&storage, 2, 7)?.len(), 6);
1495
1496 Ok(())
1497 }
1498
1499 #[test]
1500 fn test_add_remove_one() -> StdResult<()> {
1501 let mut storage = MockStorage::new();
1502 let keymap: Keymap<i32, i32> = Keymap::new(b"test");
1503 keymap.insert(&mut storage, &1, &1)?;
1504 assert_eq!(keymap.get_len(&storage)?, 1);
1505 keymap.remove(&mut storage, &1)?;
1506 assert_eq!(keymap.get_len(&storage)?, 0);
1507 assert!(keymap.get(&storage, &1).is_none());
1508 keymap.insert(&mut storage, &1, &1)?;
1509 assert_eq!(keymap.get_len(&storage)?, 1);
1510 Ok(())
1511 }
1512}