radix_substate_store_impls/
substate_database_overlay.rs1use radix_common::prelude::*;
2use radix_rust::prelude::borrow::*;
3use radix_substate_store_interface::interface::*;
4
5pub type UnmergeableSubstateDatabaseOverlay<'a, S> = SubstateDatabaseOverlay<&'a S, S>;
6pub type MergeableSubstateDatabaseOverlay<'a, S> = SubstateDatabaseOverlay<&'a mut S, S>;
7pub type OwnedSubstateDatabaseOverlay<S> = SubstateDatabaseOverlay<S, S>;
8
9pub struct SubstateDatabaseOverlay<S, D> {
10 overlay: StagingDatabaseUpdates,
13
14 root: S,
18
19 substate_database_type: PhantomData<D>,
21}
22
23impl<'a, D> UnmergeableSubstateDatabaseOverlay<'a, D> {
24 pub fn new_unmergeable(root_database: &'a D) -> Self {
25 Self::new(root_database)
26 }
27}
28
29impl<'a, D> MergeableSubstateDatabaseOverlay<'a, D> {
30 pub fn new_mergeable(root_database: &'a mut D) -> Self {
31 Self::new(root_database)
32 }
33}
34
35impl<D> OwnedSubstateDatabaseOverlay<D> {
36 pub fn new_owned(root_database: D) -> Self {
37 Self::new(root_database)
38 }
39}
40
41impl<S, D> SubstateDatabaseOverlay<S, D> {
42 pub fn new(root_database: S) -> Self {
43 Self {
44 overlay: Default::default(),
45 root: root_database,
46 substate_database_type: PhantomData,
47 }
48 }
49
50 pub fn deconstruct(self) -> (S, DatabaseUpdates) {
51 (self.root, self.overlay.into())
52 }
53
54 pub fn database_updates(&self) -> DatabaseUpdates {
55 self.overlay.clone().into()
56 }
57
58 pub fn into_database_updates(self) -> DatabaseUpdates {
59 self.overlay.into()
60 }
61}
62
63impl<S: Borrow<D>, D> SubstateDatabaseOverlay<S, D> {
64 fn get_readable_root(&self) -> &D {
65 self.root.borrow()
66 }
67}
68
69impl<S: BorrowMut<D>, D> SubstateDatabaseOverlay<S, D> {
70 fn get_writable_root(&mut self) -> &mut D {
71 self.root.borrow_mut()
72 }
73}
74
75impl<S: BorrowMut<D>, D: CommittableSubstateDatabase> SubstateDatabaseOverlay<S, D> {
76 pub fn commit_overlay_into_root_store(&mut self) {
77 let overlay = mem::replace(&mut self.overlay, StagingDatabaseUpdates::default());
78 self.get_writable_root().commit(&overlay.into());
79 }
80}
81
82impl<S: Borrow<D>, D: SubstateDatabase> SubstateDatabase for SubstateDatabaseOverlay<S, D> {
83 fn get_raw_substate_by_db_key(
84 &self,
85 partition_key @ DbPartitionKey {
86 node_key,
87 partition_num,
88 }: &DbPartitionKey,
89 sort_key: &DbSortKey,
90 ) -> Option<DbSubstateValue> {
91 let overlay_lookup_result = match self.overlay.node_updates.get(node_key) {
92 Some(StagingNodeDatabaseUpdates { partition_updates }) => {
95 match partition_updates.get(partition_num) {
96 Some(StagingPartitionDatabaseUpdates::Delta { substate_updates }) => {
98 match substate_updates.get(sort_key) {
99 Some(DatabaseUpdate::Set(substate_value)) => {
102 OverlayLookupResult::Found(Some(substate_value))
103 }
104 Some(DatabaseUpdate::Delete) => OverlayLookupResult::Found(None),
107 None => OverlayLookupResult::NotFound,
110 }
111 }
112 Some(StagingPartitionDatabaseUpdates::Reset {
113 new_substate_values,
114 }) => match new_substate_values.get(sort_key) {
115 Some(substate_value) => OverlayLookupResult::Found(Some(substate_value)),
117 None => OverlayLookupResult::Found(None),
124 },
125 None => OverlayLookupResult::NotFound,
128 }
129 }
130 None => OverlayLookupResult::NotFound,
133 };
134
135 match overlay_lookup_result {
136 OverlayLookupResult::Found(substate_value) => substate_value.cloned(),
137 OverlayLookupResult::NotFound => self
138 .get_readable_root()
139 .get_raw_substate_by_db_key(partition_key, sort_key),
140 }
141 }
142
143 fn list_raw_values_from_db_key(
144 &self,
145 partition_key @ DbPartitionKey {
146 node_key,
147 partition_num,
148 }: &DbPartitionKey,
149 from_sort_key: Option<&DbSortKey>,
150 ) -> Box<dyn Iterator<Item = PartitionEntry> + '_> {
151 let from_sort_key = from_sort_key.cloned();
156 match self.overlay.node_updates.get(node_key) {
157 Some(StagingNodeDatabaseUpdates { partition_updates }) => {
159 match partition_updates.get(partition_num) {
160 Some(StagingPartitionDatabaseUpdates::Reset {
164 new_substate_values,
165 }) => {
166 match from_sort_key {
167 Some(from_sort_key) => {
172 Box::new(new_substate_values.range(from_sort_key..).map(
173 |(sort_key, substate_value)| {
174 (sort_key.clone(), substate_value.clone())
175 },
176 ))
177 }
178 None => Box::new(new_substate_values.iter().map(
180 |(sort_key, substate_value)| {
181 (sort_key.clone(), substate_value.clone())
182 },
183 )),
184 }
185 }
186 Some(StagingPartitionDatabaseUpdates::Delta { substate_updates }) => {
188 let underlying = self
189 .get_readable_root()
190 .list_raw_values_from_db_key(partition_key, from_sort_key.as_ref());
191
192 match from_sort_key {
193 Some(from_sort_key) => {
198 let overlaying = substate_updates.range(from_sort_key..).map(
199 |(sort_key, database_update)| match database_update {
200 DatabaseUpdate::Set(substate_value) => {
201 (sort_key.clone(), Some(substate_value.clone()))
202 }
203 DatabaseUpdate::Delete => (sort_key.clone(), None),
204 },
205 );
206 Box::new(OverlayingIterator::new(underlying, overlaying))
207 }
208 None => {
210 let overlaying =
211 substate_updates.iter().map(|(sort_key, database_update)| {
212 match database_update {
213 DatabaseUpdate::Set(substate_value) => {
214 (sort_key.clone(), Some(substate_value.clone()))
215 }
216 DatabaseUpdate::Delete => (sort_key.clone(), None),
217 }
218 });
219 Box::new(OverlayingIterator::new(underlying, overlaying))
220 }
221 }
222 }
223 None => self
226 .get_readable_root()
227 .list_raw_values_from_db_key(partition_key, from_sort_key.as_ref()),
228 }
229 }
230 None => self
233 .get_readable_root()
234 .list_raw_values_from_db_key(partition_key, from_sort_key.as_ref()),
235 }
236 }
237}
238
239impl<S, D> CommittableSubstateDatabase for SubstateDatabaseOverlay<S, D> {
240 fn commit(&mut self, database_updates: &DatabaseUpdates) {
241 merge_database_updates(&mut self.overlay, database_updates.clone())
242 }
243}
244
245impl<S: Borrow<D>, D: ListableSubstateDatabase> ListableSubstateDatabase
246 for SubstateDatabaseOverlay<S, D>
247{
248 fn list_partition_keys(&self) -> Box<dyn Iterator<Item = DbPartitionKey> + '_> {
249 let overlying = self
250 .overlay
251 .node_updates
252 .iter()
253 .flat_map(
254 |(node_key, StagingNodeDatabaseUpdates { partition_updates })| {
255 partition_updates
256 .keys()
257 .map(|partition_num| DbPartitionKey {
258 node_key: node_key.clone(),
259 partition_num: *partition_num,
260 })
261 },
262 )
263 .map(|partition_key| (partition_key, Some(())));
264 let underlying = self
265 .get_readable_root()
266 .list_partition_keys()
267 .map(|partition_key| (partition_key, ()));
268
269 Box::new(OverlayingIterator::new(underlying, overlying).map(|(value, _)| value))
270 }
271}
272
273pub enum OverlayLookupResult<T> {
274 Found(T),
275 NotFound,
276}
277
278fn merge_database_updates(this: &mut StagingDatabaseUpdates, other: DatabaseUpdates) {
279 for (
280 other_node_key,
281 NodeDatabaseUpdates {
282 partition_updates: other_partition_updates,
283 },
284 ) in other.node_updates.into_iter()
285 {
286 match this.node_updates.get_mut(&other_node_key) {
288 Some(StagingNodeDatabaseUpdates {
290 partition_updates: this_partition_updates,
291 }) => {
292 for (other_partition_num, other_partition_database_updates) in
293 other_partition_updates.into_iter()
294 {
295 match this_partition_updates.get_mut(&other_partition_num) {
297 Some(this_partition_database_updates) => {
300 match (
301 this_partition_database_updates,
302 other_partition_database_updates,
303 ) {
304 (
308 StagingPartitionDatabaseUpdates::Delta {
309 substate_updates: this_substate_updates,
310 },
311 PartitionDatabaseUpdates::Delta {
312 substate_updates: other_substate_updates,
313 },
314 ) => this_substate_updates.extend(other_substate_updates),
315 (
317 StagingPartitionDatabaseUpdates::Reset {
318 new_substate_values: this_new_substate_values,
319 },
320 PartitionDatabaseUpdates::Delta {
321 substate_updates: other_substate_updates,
322 },
323 ) => {
324 for (other_sort_key, other_database_update) in
325 other_substate_updates.into_iter()
326 {
327 match other_database_update {
328 DatabaseUpdate::Set(other_substate_value) => {
329 this_new_substate_values
330 .insert(other_sort_key, other_substate_value);
331 }
332 DatabaseUpdate::Delete => {
333 this_new_substate_values.remove(&other_sort_key);
334 }
335 }
336 }
337 }
338 (
341 this_partition_database_updates,
342 other_partition_database_updates @ PartitionDatabaseUpdates::Reset { .. },
343 ) => {
344 *this_partition_database_updates = other_partition_database_updates.into();
345 }
346 }
347 }
348 None => {
351 this_partition_updates.insert(
352 other_partition_num,
353 other_partition_database_updates.into(),
354 );
355 }
356 }
357 }
358 }
359 None => {
362 this.node_updates.insert(
363 other_node_key,
364 NodeDatabaseUpdates {
365 partition_updates: other_partition_updates,
366 }
367 .into(),
368 );
369 }
370 }
371 }
372}
373
374#[derive(Debug, Clone, PartialEq, Eq, Sbor, Default)]
375struct StagingDatabaseUpdates {
376 node_updates: BTreeMap<DbNodeKey, StagingNodeDatabaseUpdates>,
377}
378
379impl From<StagingDatabaseUpdates> for DatabaseUpdates {
380 fn from(value: StagingDatabaseUpdates) -> Self {
381 Self {
382 node_updates: value
383 .node_updates
384 .into_iter()
385 .map(|(key, value)| (key, NodeDatabaseUpdates::from(value)))
386 .collect(),
387 }
388 }
389}
390
391impl From<DatabaseUpdates> for StagingDatabaseUpdates {
392 fn from(value: DatabaseUpdates) -> Self {
393 Self {
394 node_updates: value
395 .node_updates
396 .into_iter()
397 .map(|(key, value)| (key, StagingNodeDatabaseUpdates::from(value)))
398 .collect(),
399 }
400 }
401}
402
403#[derive(Debug, Clone, PartialEq, Eq, Sbor, Default)]
404struct StagingNodeDatabaseUpdates {
405 partition_updates: BTreeMap<DbPartitionNum, StagingPartitionDatabaseUpdates>,
406}
407
408impl From<StagingNodeDatabaseUpdates> for NodeDatabaseUpdates {
409 fn from(value: StagingNodeDatabaseUpdates) -> Self {
410 Self {
411 partition_updates: value
412 .partition_updates
413 .into_iter()
414 .map(|(key, value)| (key, PartitionDatabaseUpdates::from(value)))
415 .collect(),
416 }
417 }
418}
419
420impl From<NodeDatabaseUpdates> for StagingNodeDatabaseUpdates {
421 fn from(value: NodeDatabaseUpdates) -> Self {
422 Self {
423 partition_updates: value
424 .partition_updates
425 .into_iter()
426 .map(|(key, value)| (key, StagingPartitionDatabaseUpdates::from(value)))
427 .collect(),
428 }
429 }
430}
431
432#[derive(Debug, Clone, PartialEq, Eq, Sbor)]
433enum StagingPartitionDatabaseUpdates {
434 Delta {
435 substate_updates: BTreeMap<DbSortKey, DatabaseUpdate>,
436 },
437
438 Reset {
439 new_substate_values: BTreeMap<DbSortKey, DbSubstateValue>,
440 },
441}
442
443impl From<StagingPartitionDatabaseUpdates> for PartitionDatabaseUpdates {
444 fn from(value: StagingPartitionDatabaseUpdates) -> Self {
445 match value {
446 StagingPartitionDatabaseUpdates::Delta { substate_updates } => Self::Delta {
447 substate_updates: substate_updates.into_iter().collect(),
448 },
449 StagingPartitionDatabaseUpdates::Reset {
450 new_substate_values,
451 } => Self::Reset {
452 new_substate_values: new_substate_values.into_iter().collect(),
453 },
454 }
455 }
456}
457
458impl From<PartitionDatabaseUpdates> for StagingPartitionDatabaseUpdates {
459 fn from(value: PartitionDatabaseUpdates) -> Self {
460 match value {
461 PartitionDatabaseUpdates::Delta { substate_updates } => Self::Delta {
462 substate_updates: substate_updates.into_iter().collect(),
463 },
464 PartitionDatabaseUpdates::Reset {
465 new_substate_values,
466 } => Self::Reset {
467 new_substate_values: new_substate_values.into_iter().collect(),
468 },
469 }
470 }
471}