Skip to main content

gear_common/storage/primitives/
double_map.rs

1// Copyright (C) Gear Technologies Inc.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3
4//! Module for double map storing primitive.
5//!
6//! This primitive defines interface of interaction
7//! with globally stored double-key map (Key1 -> Key2 -> Value).
8
9/// Represents logic of managing globally stored
10/// double-key map for more complicated logic.
11///
12/// In fact, represents custom implementation/wrapper
13/// around of Substrate's `StorageDoubleMap` with `OptionQuery`.
14pub trait DoubleMapStorage {
15    /// Map's first key type.
16    type Key1;
17    /// Map's second key type.
18    type Key2;
19    /// Map's stored value type.
20    type Value;
21
22    /// Returns bool, defining does map contain value under given keys.
23    fn contains_keys(key1: &Self::Key1, key2: &Self::Key2) -> bool;
24
25    /// Gets value stored under given keys, if present.
26    fn get(key1: &Self::Key1, key2: &Self::Key2) -> Option<Self::Value>;
27
28    /// Inserts value with given keys.
29    fn insert(key1: Self::Key1, key2: Self::Key2, value: Self::Value);
30
31    /// Mutates value by `Option` reference, which stored (or not
32    /// in `None` case) under given keys with given function.
33    ///
34    /// May return generic type value.
35    fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(
36        key1: Self::Key1,
37        key2: Self::Key2,
38        f: F,
39    ) -> R;
40
41    /// Works the same as `Self::mutate`, but triggers if value present.
42    fn mutate_exists<R, F: FnOnce(&mut Self::Value) -> R>(
43        key1: Self::Key1,
44        key2: Self::Key2,
45        f: F,
46    ) -> Option<R> {
47        Self::mutate(key1, key2, |opt_val| opt_val.as_mut().map(f))
48    }
49
50    /// Mutates all stored values with given convert function.
51    fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(f: F);
52
53    /// Removes value stored under the given keys.
54    fn remove(key1: Self::Key1, key2: Self::Key2);
55
56    /// Removes all values.
57    fn clear();
58
59    /// Gets value stored under given keys, if present,
60    /// and removes it from storage.
61    fn take(key1: Self::Key1, key2: Self::Key2) -> Option<Self::Value>;
62
63    /// Remove items from the map matching a `first_key` prefix.
64    fn clear_prefix(first_key: Self::Key1);
65}
66
67/// Creates new type with specified name and key1-key2-value types and
68/// implements `DoubleMapStorage` for it based on specified storage,
69/// which is a `Substrate`'s `StorageDoubleMap`.
70///
71/// This macro main purpose is to follow newtype pattern
72/// and avoid `Substrate` dependencies in `gear_common`.
73///
74/// Requires `PhantomData` be in scope: from `std`, `core` or `sp_std`.
75///
76/// Requires `Config` be in scope of the crate root where it called.
77#[allow(clippy::crate_in_macro_def)]
78#[macro_export]
79macro_rules! wrap_storage_double_map {
80    (storage: $storage: ident, name: $name: ident, key1: $key1: ty,
81        key2: $key2: ty, value: $val: ty) => {
82        pub struct $name<T>(PhantomData<T>);
83
84        impl<T: crate::Config> DoubleMapStorage for $name<T> {
85            type Key1 = $key1;
86            type Key2 = $key2;
87            type Value = $val;
88
89            fn contains_keys(key1: &Self::Key1, key2: &Self::Key2) -> bool {
90                $storage::<T>::contains_key(key1, key2)
91            }
92
93            fn get(key1: &Self::Key1, key2: &Self::Key2) -> Option<Self::Value> {
94                $storage::<T>::get(key1, key2)
95            }
96
97            fn insert(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
98                $storage::<T>::insert(key1, key2, value)
99            }
100
101            fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(
102                key1: Self::Key1,
103                key2: Self::Key2,
104                f: F,
105            ) -> R {
106                $storage::<T>::mutate(key1, key2, f)
107            }
108
109            fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(mut f: F) {
110                let f = |v| Some(f(v));
111                $storage::<T>::translate_values(f)
112            }
113
114            fn remove(key1: Self::Key1, key2: Self::Key2) {
115                $storage::<T>::remove(key1, key2)
116            }
117
118            fn clear() {
119                let _ = $storage::<T>::clear(u32::MAX, None);
120            }
121
122            fn take(key1: Self::Key1, key2: Self::Key2) -> Option<Self::Value> {
123                $storage::<T>::take(key1, key2)
124            }
125
126            fn clear_prefix(first_key: Self::Key1) {
127                let _ = $storage::<T>::clear_prefix(first_key, u32::MAX, None);
128            }
129        }
130    };
131}
132
133/// Same as `wrap_storage_double_map!`, but with extra implementations
134/// of `CountedByKey`, `IterableMap` and `IterableByKeyMap`
135/// over double map values.
136///
137/// `PrefixIterator` from `frame_support` and `KeyValueIteratorWrap` from
138/// this crate should be in scope.
139#[allow(clippy::crate_in_macro_def)]
140#[macro_export]
141macro_rules! wrap_extended_storage_double_map {
142    (storage: $storage: ident, name: $name: ident, key1: $key1: ty,
143        key2: $key2: ty, value: $val: ty, length: $len: ty) => {
144        $crate::wrap_storage_double_map!(
145            storage: $storage,
146            name: $name,
147            key1: $key1,
148            key2: $key2,
149            value: $val
150        );
151
152        impl<T: crate::Config> CountedByKey for $name<T> {
153            type Key = $key1;
154            type Length = $len;
155
156            fn len(key: &Self::Key) -> Self::Length {
157                $storage::<T>::iter_prefix(key).count()
158            }
159        }
160
161        impl<T: crate::Config> IterableByKeyMap<$val> for $name<T> {
162            type Key = $key1;
163            type DrainIter = IteratorWrap<PrefixIterator<($key2, $val)>, $val, GetSecondPos>;
164            type Iter = IteratorWrap<PrefixIterator<($key2, $val)>, $val, GetSecondPos>;
165
166            fn drain_key(key: Self::Key) -> Self::DrainIter {
167                $storage::<T>::drain_prefix(key).into()
168            }
169
170            fn iter_key(key: Self::Key) -> Self::Iter {
171                $storage::<T>::iter_prefix(key).into()
172            }
173        }
174
175        impl<T: crate::Config> IterableMap<$val> for $name<T> {
176            type DrainIter = IteratorWrap<PrefixIterator<($key1, $key2, $val)>, $val, GetThirdPos>;
177            type Iter = IteratorWrap<PrefixIterator<($key1, $key2, $val)>, $val, GetThirdPos>;
178
179            fn drain() -> Self::DrainIter {
180                $storage::<T>::drain().into()
181            }
182
183            fn iter() -> Self::Iter {
184                $storage::<T>::iter().into()
185            }
186        }
187
188        impl<T: crate::Config> KeyIterableByKeyMap for $name<T> {
189            type Key1 = $key1;
190            type Key2 = $key2;
191            type DrainIter = IteratorWrap<PrefixIterator<($key2, $val)>, $key2, GetFirstPos>;
192            type Iter = IteratorWrap<PrefixIterator<($key2, $val)>, $key2, GetFirstPos>;
193
194            fn drain_prefix_keys(key: Self::Key1) -> Self::DrainIter {
195                $storage::<T>::drain_prefix(key).into()
196            }
197
198            fn iter_prefix_keys(key: Self::Key1) -> Self::Iter {
199                $storage::<T>::iter_prefix(key).into()
200            }
201        }
202    };
203}
204
205#[cfg(feature = "std")]
206pub mod auxiliary_double_map {
207    use crate::storage::{
208        Counted, CountedByKey, DoubleMapStorage, GetFirstPos, GetSecondPos, IterableByKeyMap,
209        IteratorWrap, KeyIterableByKeyMap, MapStorage,
210    };
211    use std::collections::btree_map::{BTreeMap, Entry, IntoIter};
212
213    /// Double key `BTreeMap`.
214    ///
215    /// Basically is just a map of the map.
216    #[derive(Clone)]
217    pub struct DoubleBTreeMap<K1, K2, V> {
218        inner: BTreeMap<K1, BTreeMap<K2, V>>,
219    }
220
221    impl<K1, K2, V> DoubleBTreeMap<K1, K2, V> {
222        /// Instantiate new empty double key map.
223        pub const fn new() -> Self {
224            Self {
225                inner: BTreeMap::new(),
226            }
227        }
228
229        /// Returns `true` if the map contains a value for the specified keys.
230        pub fn contains_keys(&self, key1: &K1, key2: &K2) -> bool
231        where
232            K1: Ord,
233            K2: Ord,
234        {
235            self.inner
236                .get(key1)
237                .map(|map| map.contains_key(key2))
238                .unwrap_or_default()
239        }
240
241        pub fn count_key(&self, key1: &K1) -> usize
242        where
243            K1: Ord,
244        {
245            self.inner
246                .get(key1)
247                .map(|key2_map| key2_map.len())
248                .unwrap_or_default()
249        }
250
251        /// Returns a reference to the value corresponding to the keys.
252        pub fn get(&self, key1: &K1, key2: &K2) -> Option<&V>
253        where
254            K1: Ord,
255            K2: Ord,
256        {
257            self.inner.get(key1).and_then(|map| map.get(key2))
258        }
259
260        /// Inserts a value under provided keys in the map.
261        pub fn insert(&mut self, key1: K1, key2: K2, value: V) -> Option<V>
262        where
263            K1: Ord,
264            K2: Ord,
265        {
266            match self.inner.entry(key1) {
267                Entry::Vacant(vacant) => {
268                    let mut map = BTreeMap::new();
269                    map.insert(key2, value);
270                    vacant.insert(map);
271
272                    None
273                }
274                Entry::Occupied(mut occupied) => occupied.get_mut().insert(key2, value),
275            }
276        }
277
278        /// Removes keys from the map, returning the value at the keys if the keys
279        /// were previously in the map.
280        pub fn remove(&mut self, key1: K1, key2: K2) -> Option<V>
281        where
282            K1: Ord,
283            K2: Ord,
284        {
285            self.inner.get_mut(&key1).and_then(|map| map.remove(&key2))
286        }
287
288        /// Clears the map, removing all elements.
289        pub fn clear(&mut self) {
290            self.inner.clear()
291        }
292    }
293
294    // Iterator related impl
295    impl<K1, K2, V> DoubleBTreeMap<K1, K2, V> {
296        pub fn iter_key(&self, key1: &K1) -> IntoIter<K2, V>
297        where
298            K1: Ord,
299            K2: Clone,
300            V: Clone,
301        {
302            self.inner
303                .get(key1)
304                .cloned()
305                .map(|key2_map| key2_map.into_iter())
306                .unwrap_or_default()
307        }
308
309        pub fn drain_key(&mut self, key1: &K1) -> IntoIter<K2, V>
310        where
311            K1: Ord,
312        {
313            self.inner
314                .remove(key1)
315                .map(|key2_map| key2_map.into_iter())
316                .unwrap_or_default()
317        }
318    }
319
320    impl<K1, K2, V> Default for DoubleBTreeMap<K1, K2, V> {
321        fn default() -> Self {
322            Self::new()
323        }
324    }
325
326    /// An auxiliary storage wrapper type.
327    ///
328    /// Implements DoubleMapStorage and traits like [`IterableByKeyMap`] for such type automatically.
329    pub trait AuxiliaryDoubleStorageWrap {
330        type Key1: Ord + Clone;
331        type Key2: Ord + Clone;
332        type Value: Clone;
333        fn with_storage<F, R>(f: F) -> R
334        where
335            F: FnOnce(&DoubleBTreeMap<Self::Key1, Self::Key2, Self::Value>) -> R;
336
337        fn with_storage_mut<F, R>(f: F) -> R
338        where
339            F: FnOnce(&mut DoubleBTreeMap<Self::Key1, Self::Key2, Self::Value>) -> R;
340    }
341
342    impl<T: AuxiliaryDoubleStorageWrap> DoubleMapStorage for T {
343        type Key1 = T::Key1;
344        type Key2 = T::Key2;
345        type Value = T::Value;
346
347        fn get(key1: &Self::Key1, key2: &Self::Key2) -> Option<Self::Value> {
348            T::with_storage(|map| map.get(key1, key2).cloned())
349        }
350
351        fn insert(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
352            T::with_storage_mut(|map| map.insert(key1, key2, value));
353        }
354
355        fn clear() {
356            T::with_storage_mut(|map| map.clear());
357        }
358
359        fn clear_prefix(first_key: Self::Key1) {
360            T::with_storage_mut(|map| {
361                let keys = map.iter_key(&first_key).map(|(k, _)| k.clone());
362                for key in keys {
363                    map.remove(first_key.clone(), key);
364                }
365            });
366        }
367
368        fn contains_keys(key1: &Self::Key1, key2: &Self::Key2) -> bool {
369            T::with_storage_mut(|map| map.contains_keys(key1, key2))
370        }
371
372        fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(
373            key1: Self::Key1,
374            key2: Self::Key2,
375            f: F,
376        ) -> R {
377            T::with_storage_mut(|map| {
378                let inner_map = map.inner.entry(key1).or_default();
379                match inner_map.entry(key2) {
380                    Entry::Occupied(mut occupied) => {
381                        let mut value = Some(occupied.get().clone());
382                        let result = f(&mut value);
383                        if let Some(value) = value {
384                            *occupied.get_mut() = value;
385                        } else {
386                            occupied.remove();
387                        }
388
389                        result
390                    }
391
392                    Entry::Vacant(vacant) => {
393                        let mut value = None;
394                        let result = f(&mut value);
395                        if let Some(value) = value {
396                            vacant.insert(value);
397                        }
398                        result
399                    }
400                }
401            })
402        }
403
404        fn mutate_exists<R, F: FnOnce(&mut Self::Value) -> R>(
405            key1: Self::Key1,
406            key2: Self::Key2,
407            f: F,
408        ) -> Option<R> {
409            T::with_storage_mut(|map| {
410                if let Some(inner_map) = map.inner.get_mut(&key1)
411                    && let Some(value) = inner_map.get_mut(&key2)
412                {
413                    return Some(f(value));
414                }
415
416                None
417            })
418        }
419
420        fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(mut f: F) {
421            T::with_storage_mut(|map| {
422                for (_, inner_map) in map.inner.iter_mut() {
423                    for (_, value) in inner_map.iter_mut() {
424                        *value = f(value.clone());
425                    }
426                }
427            });
428        }
429
430        fn remove(key1: Self::Key1, key2: Self::Key2) {
431            Self::take(key1, key2);
432        }
433
434        fn take(key1: Self::Key1, key2: Self::Key2) -> Option<Self::Value> {
435            T::with_storage_mut(|map| map.remove(key1, key2))
436        }
437    }
438
439    impl<T: AuxiliaryDoubleStorageWrap> IterableByKeyMap<T::Value> for T {
440        type Key = T::Key1;
441
442        type DrainIter = IteratorWrap<IntoIter<T::Key2, T::Value>, T::Value, GetSecondPos>;
443
444        type Iter = IteratorWrap<IntoIter<T::Key2, T::Value>, T::Value, GetSecondPos>;
445
446        fn drain_key(key: Self::Key) -> Self::DrainIter {
447            T::with_storage_mut(|map| map.drain_key(&key)).into()
448        }
449
450        fn iter_key(key: Self::Key) -> Self::Iter {
451            T::with_storage(|map| map.iter_key(&key)).into()
452        }
453    }
454
455    impl<T: AuxiliaryDoubleStorageWrap> KeyIterableByKeyMap for T {
456        type Key1 = T::Key1;
457        type Key2 = T::Key2;
458        type DrainIter = IteratorWrap<IntoIter<T::Key2, T::Value>, T::Key2, GetFirstPos>;
459        type Iter = IteratorWrap<IntoIter<T::Key2, T::Value>, T::Key2, GetFirstPos>;
460
461        fn drain_prefix_keys(key: Self::Key1) -> Self::DrainIter {
462            T::with_storage_mut(|map| map.drain_key(&key).into())
463        }
464
465        fn iter_prefix_keys(key: Self::Key1) -> Self::Iter {
466            T::with_storage(|map| map.iter_key(&key)).into()
467        }
468    }
469
470    impl<T: AuxiliaryDoubleStorageWrap> CountedByKey for T {
471        type Key = T::Key1;
472        type Length = usize;
473
474        fn len(key: &Self::Key) -> Self::Length {
475            T::with_storage(|map| map.count_key(key))
476        }
477    }
478
479    pub trait AuxiliaryStorageWrap {
480        type Key: Clone + Ord;
481        type Value: Clone;
482
483        fn with_storage<F, R>(f: F) -> R
484        where
485            F: FnOnce(&BTreeMap<Self::Key, Self::Value>) -> R;
486
487        fn with_storage_mut<F, R>(f: F) -> R
488        where
489            F: FnOnce(&mut BTreeMap<Self::Key, Self::Value>) -> R;
490    }
491
492    impl<T: AuxiliaryStorageWrap> MapStorage for T {
493        type Key = T::Key;
494        type Value = T::Value;
495
496        fn clear() {
497            T::with_storage_mut(|map| map.clear());
498        }
499
500        fn contains_key(key: &Self::Key) -> bool {
501            T::with_storage(|map| map.contains_key(key))
502        }
503
504        fn get(key: &Self::Key) -> Option<Self::Value> {
505            T::with_storage(|map| map.get(key).cloned())
506        }
507
508        fn insert(key: Self::Key, value: Self::Value) {
509            T::with_storage_mut(|map| map.insert(key, value));
510        }
511
512        fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(key: Self::Key, f: F) -> R {
513            T::with_storage_mut(|map| match map.entry(key) {
514                Entry::Occupied(mut occupied) => {
515                    let mut value = Some(occupied.get().clone());
516
517                    let result = f(&mut value);
518                    if let Some(value) = value.take() {
519                        *occupied.get_mut() = value;
520                    } else {
521                        occupied.remove();
522                    }
523
524                    result
525                }
526
527                Entry::Vacant(vacant) => {
528                    let mut value = None;
529
530                    let result = f(&mut value);
531
532                    if let Some(value) = value.take() {
533                        vacant.insert(value);
534                    }
535
536                    result
537                }
538            })
539        }
540
541        fn mutate_exists<R, F: FnOnce(&mut Self::Value) -> R>(key: Self::Key, f: F) -> Option<R> {
542            T::with_storage_mut(|map| map.get_mut(&key).map(f))
543        }
544
545        fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(mut f: F) {
546            T::with_storage_mut(|map| {
547                map.iter_mut()
548                    .for_each(|(_, value)| *value = f(value.clone()))
549            });
550        }
551
552        fn remove(key: Self::Key) {
553            Self::take(key);
554        }
555
556        fn take(key: Self::Key) -> Option<Self::Value> {
557            T::with_storage_mut(|map| map.remove(&key))
558        }
559    }
560
561    impl<T: AuxiliaryStorageWrap> Counted for T {
562        type Length = usize;
563        fn len() -> Self::Length {
564            T::with_storage(|map| map.len())
565        }
566    }
567}