1use std::{any::Any, collections::BTreeMap, sync::Arc};
2
3use tendermint::abci;
4
5use crate::{
6 store::{multistore::MultistoreConfig, substore::SubstoreConfig},
7 StateWrite,
8};
9
10#[derive(Default, Debug)]
14pub struct Cache {
15 pub(crate) unwritten_changes: BTreeMap<String, Option<Vec<u8>>>,
17 pub(crate) nonverifiable_changes: BTreeMap<Vec<u8>, Option<Vec<u8>>>,
19 pub(crate) ephemeral_objects: BTreeMap<&'static str, Option<Box<dyn Any + Send + Sync>>>,
21 pub(crate) events: Vec<abci::Event>,
23}
24
25impl Cache {
26 pub fn unwritten_changes(&self) -> &BTreeMap<String, Option<Vec<u8>>> {
28 &self.unwritten_changes
29 }
30
31 pub fn nonverifiable_changes(&self) -> &BTreeMap<Vec<u8>, Option<Vec<u8>>> {
33 &self.nonverifiable_changes
34 }
35
36 pub fn merge(&mut self, other: Cache) {
38 self.unwritten_changes.extend(other.unwritten_changes);
44 self.nonverifiable_changes
45 .extend(other.nonverifiable_changes);
46 self.ephemeral_objects.extend(other.ephemeral_objects);
47 self.events.extend(other.events);
48 }
49
50 pub fn apply_to<S: StateWrite>(self, mut state: S) {
52 for (key, value) in self.unwritten_changes {
53 if let Some(value) = value {
54 state.put_raw(key, value);
55 } else {
56 state.delete(key);
57 }
58 }
59
60 for (key, value) in self.nonverifiable_changes {
61 if let Some(value) = value {
62 state.nonverifiable_put_raw(key, value);
63 } else {
64 state.nonverifiable_delete(key);
65 }
66 }
67
68 state.object_merge(self.ephemeral_objects);
71
72 for event in self.events {
73 state.record(event);
74 }
75 }
76
77 pub fn is_dirty(&self) -> bool {
79 !(self.unwritten_changes.is_empty()
80 && self.nonverifiable_changes.is_empty()
81 && self.ephemeral_objects.is_empty())
82 }
83
84 pub fn take_events(&mut self) -> Vec<abci::Event> {
86 std::mem::take(&mut self.events)
87 }
88
89 pub fn shard_by_prefix(
93 self,
94 prefixes: &MultistoreConfig,
95 ) -> BTreeMap<Arc<SubstoreConfig>, Self> {
96 let mut changes_by_substore = BTreeMap::new();
97 for (key, some_value) in self.unwritten_changes.into_iter() {
98 let (truncated_key, substore_config) = prefixes.route_key_str(&key);
99 changes_by_substore
100 .entry(substore_config)
101 .or_insert_with(Cache::default)
102 .unwritten_changes
103 .insert(truncated_key.to_string(), some_value);
104 }
105
106 for (key, some_value) in self.nonverifiable_changes {
107 let (truncated_key, substore_config) = prefixes.route_key_bytes(&key);
108 changes_by_substore
109 .entry(substore_config)
110 .or_insert_with(Cache::default)
111 .nonverifiable_changes
112 .insert(truncated_key.to_vec(), some_value);
113 }
114 changes_by_substore
115 }
116
117 pub(crate) fn clone_changes(&self) -> Self {
118 Self {
119 unwritten_changes: self.unwritten_changes.clone(),
120 nonverifiable_changes: self.nonverifiable_changes.clone(),
121 ephemeral_objects: Default::default(),
122 events: Default::default(),
123 }
124 }
125}