snarkvm_ledger_store/helpers/traits/
map.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM 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
16use console::network::prelude::{Deserialize, Result, Serialize};
17
18use core::{borrow::Borrow, hash::Hash};
19use std::borrow::Cow;
20
21/// A trait representing map-like storage operations with read-write capabilities.
22pub trait Map<
23    'a,
24    K: 'a + Copy + Clone + PartialEq + Eq + Hash + Serialize + Deserialize<'a> + Send + Sync,
25    V: 'a + Clone + PartialEq + Eq + 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.
93pub trait MapRead<
94    'a,
95    K: 'a + Copy + Clone + PartialEq + Eq + Hash + Serialize + Deserialize<'a> + Sync,
96    V: 'a + Clone + PartialEq + Eq + 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}