/ ledger / store / src / helpers / traits / map.rs
map.rs
  1  // Copyright (c) 2019-2025 Alpha-Delta Network Inc.
  2  // This file is part of the deltavm library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  use console::network::prelude::{Deserialize, Result, Serialize};
 17  
 18  use core::{borrow::Borrow, hash::Hash};
 19  use std::borrow::Cow;
 20  
 21  /// A trait representing map-like storage operations with read-write capabilities.
 22  pub trait Map<
 23      'a,
 24      K: 'a + Copy + Clone + PartialEq + Eq + Hash + Serialize + Deserialize<'a> + Send + Sync,
 25      V: 'a + Clone + Serialize + Deserialize<'a> + Send + Sync,
 26  >: Clone + MapRead<'a, K, V> + Send + Sync
 27  {
 28      ///
 29      /// Inserts the given key-value pair into the map.
 30      ///
 31      fn insert(&self, key: K, value: V) -> Result<()>;
 32  
 33      ///
 34      /// Removes the key-value pair for the given key from the map.
 35      ///
 36      fn remove(&self, key: &K) -> Result<()>;
 37  
 38      ///
 39      /// Begins an atomic operation. Any further calls to `insert` and `remove` will be queued
 40      /// without an actual write taking place until `finish_atomic` is called.
 41      ///
 42      fn start_atomic(&self);
 43  
 44      ///
 45      /// Checks whether an atomic operation is currently in progress. This can be done to ensure
 46      /// that lower-level operations don't start or finish their individual atomic write batch
 47      /// if they are already part of a larger one.
 48      ///
 49      fn is_atomic_in_progress(&self) -> bool;
 50  
 51      ///
 52      /// Saves the current list of pending operations, so that if `atomic_rewind` is called,
 53      /// we roll back all future operations, and return to the start of this checkpoint.
 54      ///
 55      fn atomic_checkpoint(&self);
 56  
 57      ///
 58      /// Removes the latest atomic checkpoint.
 59      ///
 60      fn clear_latest_checkpoint(&self);
 61  
 62      ///
 63      /// Removes all pending operations to the last `atomic_checkpoint`
 64      /// (or to `start_atomic` if no checkpoints have been created).
 65      ///
 66      fn atomic_rewind(&self);
 67  
 68      ///
 69      /// Aborts the current atomic operation.
 70      ///
 71      fn abort_atomic(&self);
 72  
 73      ///
 74      /// Finishes an atomic operation, performing all the queued writes.
 75      ///
 76      fn finish_atomic(&self) -> Result<()>;
 77  
 78      ///
 79      /// Once called, the subsequent atomic write batches will be queued instead of being executed
 80      /// at the end of their scope. `unpause_atomic_writes` needs to be called in order to
 81      /// restore the usual behavior.
 82      ///
 83      fn pause_atomic_writes(&self) -> Result<()>;
 84  
 85      ///
 86      /// Executes all of the queued writes as a single atomic operation and restores the usual
 87      /// behavior of atomic write batches that was altered by calling `pause_atomic_writes`.
 88      ///
 89      fn unpause_atomic_writes<const DISCARD_BATCH: bool>(&self) -> Result<()>;
 90  }
 91  
 92  /// A trait representing map-like storage operations with read-only capabilities.
 93  pub trait MapRead<
 94      'a,
 95      K: 'a + Copy + Clone + PartialEq + Eq + Hash + Serialize + Deserialize<'a> + Sync,
 96      V: 'a + Clone + Serialize + Deserialize<'a> + Sync,
 97  >
 98  {
 99      type PendingIterator: Iterator<Item = (Cow<'a, K>, Option<Cow<'a, V>>)>;
100      type Iterator: Iterator<Item = (Cow<'a, K>, Cow<'a, V>)>;
101      type Keys: Iterator<Item = Cow<'a, K>>;
102      type Values: Iterator<Item = Cow<'a, V>>;
103  
104      ///
105      /// Returns the number of confirmed entries in the map.
106      ///
107      fn len_confirmed(&self) -> usize;
108  
109      ///
110      /// Checks whether there are any confirmed entries in the map.
111      ///
112      fn is_empty_confirmed(&self) -> bool {
113          self.len_confirmed() == 0
114      }
115  
116      ///
117      /// Returns `true` if the given key exists in the map.
118      ///
119      fn contains_key_confirmed<Q>(&self, key: &Q) -> Result<bool>
120      where
121          K: Borrow<Q>,
122          Q: PartialEq + Eq + Hash + Serialize + ?Sized;
123  
124      ///
125      /// Returns `true` if the given key exists in the map.
126      /// This method first checks the atomic batch, and if it does not exist, then checks the map.
127      ///
128      fn contains_key_speculative<Q>(&self, key: &Q) -> Result<bool>
129      where
130          K: Borrow<Q>,
131          Q: PartialEq + Eq + Hash + Serialize + ?Sized;
132  
133      ///
134      /// Returns the value for the given key from the map, if it exists.
135      ///
136      fn get_confirmed<Q>(&'a self, key: &Q) -> Result<Option<Cow<'a, V>>>
137      where
138          K: Borrow<Q>,
139          Q: PartialEq + Eq + Hash + Serialize + ?Sized;
140  
141      ///
142      /// Returns the current value for the given key if it is scheduled
143      /// to be inserted as part of an atomic batch.
144      ///
145      /// If the key does not exist, returns `None`.
146      /// If the key is removed in the batch, returns `Some(None)`.
147      /// If the key is inserted in the batch, returns `Some(Some(value))`.
148      ///
149      fn get_pending<Q>(&self, key: &Q) -> Option<Option<V>>
150      where
151          K: Borrow<Q>,
152          Q: PartialEq + Eq + Hash + Serialize + ?Sized;
153  
154      ///
155      /// Returns the value for the given key from the atomic batch first, if it exists,
156      /// or return from the map, otherwise.
157      ///
158      fn get_speculative<Q>(&'a self, key: &Q) -> Result<Option<Cow<'a, V>>>
159      where
160          K: Borrow<Q>,
161          Q: PartialEq + Eq + Hash + Serialize + ?Sized,
162      {
163          // Return the atomic batch value, if it exists, or the map value, otherwise.
164          match self.get_pending(key) {
165              Some(Some(value)) => Ok(Some(Cow::Owned(value))),
166              Some(None) => Ok(None),
167              None => Ok(self.get_confirmed(key)?),
168          }
169      }
170  
171      ///
172      /// Returns an iterator visiting each key-value pair in the atomic batch.
173      ///
174      fn iter_pending(&'a self) -> Self::PendingIterator;
175  
176      ///
177      /// Returns an iterator visiting each key-value pair in the map.
178      ///
179      fn iter_confirmed(&'a self) -> Self::Iterator;
180  
181      ///
182      /// Returns an iterator over each key in the map.
183      ///
184      fn keys_confirmed(&'a self) -> Self::Keys;
185  
186      ///
187      /// Returns an iterator over each value in the map.
188      ///
189      fn values_confirmed(&'a self) -> Self::Values;
190  }