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}