1use alloc::{
2 collections::{
3 BTreeMap,
4 btree_map::{Entry, IntoIter},
5 },
6 sync::Arc,
7 vec::Vec,
8};
9
10use crate::{
11 Felt, Word,
12 utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
13};
14
15#[derive(Debug, Clone, Default, PartialEq, Eq)]
24pub struct AdviceMap(BTreeMap<Word, Arc<[Felt]>>);
25
26type MapEntry = (Word, Arc<[Felt]>);
28
29impl AdviceMap {
30 pub fn get(&self, key: &Word) -> Option<&Arc<[Felt]>> {
32 self.0.get(key)
33 }
34
35 pub fn contains_key(&self, key: &Word) -> bool {
37 self.0.contains_key(key)
38 }
39
40 pub fn insert(&mut self, key: Word, value: impl Into<Arc<[Felt]>>) -> Option<Arc<[Felt]>> {
42 self.0.insert(key, value.into())
43 }
44
45 pub fn remove(&mut self, key: &Word) -> Option<Arc<[Felt]>> {
47 self.0.remove(key)
48 }
49
50 pub fn iter(&self) -> impl Iterator<Item = (&Word, &Arc<[Felt]>)> {
52 self.0.iter()
53 }
54
55 pub fn len(&self) -> usize {
57 self.0.len()
58 }
59
60 pub fn is_empty(&self) -> bool {
62 self.0.is_empty()
63 }
64
65 pub fn entry(&mut self, key: Word) -> Entry<'_, Word, Arc<[Felt]>> {
67 self.0.entry(key)
68 }
69
70 pub fn merge(&mut self, other: &Self) -> Result<(), (MapEntry, Arc<[Felt]>)> {
76 if let Some(conflict) = self.find_conflicting_entry(other) {
77 Err(conflict)
78 } else {
79 self.merge_new(other);
80 Ok(())
81 }
82 }
83
84 fn merge_new(&mut self, other: &Self) {
86 for (key, value) in other.iter() {
87 self.0.entry(*key).or_insert_with(|| value.clone());
88 }
89 }
90
91 fn find_conflicting_entry(&self, other: &Self) -> Option<(MapEntry, Arc<[Felt]>)> {
97 for (key, new_value) in other.iter() {
98 if let Some(existing_value) = self.get(key)
99 && existing_value != new_value
100 {
101 return Some(((*key, existing_value.clone()), new_value.clone()));
103 }
104 }
105 None
107 }
108}
109
110impl From<BTreeMap<Word, Arc<[Felt]>>> for AdviceMap {
111 fn from(value: BTreeMap<Word, Arc<[Felt]>>) -> Self {
112 Self(value)
113 }
114}
115
116impl From<BTreeMap<Word, Vec<Felt>>> for AdviceMap {
117 fn from(value: BTreeMap<Word, Vec<Felt>>) -> Self {
118 value.into_iter().collect()
119 }
120}
121
122impl IntoIterator for AdviceMap {
123 type Item = (Word, Arc<[Felt]>);
124 type IntoIter = IntoIter<Word, Arc<[Felt]>>;
125
126 fn into_iter(self) -> Self::IntoIter {
127 self.0.into_iter()
128 }
129}
130
131impl<V> FromIterator<(Word, V)> for AdviceMap
132where
133 V: Into<Arc<[Felt]>>,
134{
135 fn from_iter<I>(iter: I) -> Self
136 where
137 I: IntoIterator<Item = (Word, V)>,
138 {
139 iter.into_iter()
140 .map(|(key, value)| (key, value.into()))
141 .collect::<BTreeMap<Word, Arc<[Felt]>>>()
142 .into()
143 }
144}
145
146impl<V> Extend<(Word, V)> for AdviceMap
147where
148 V: Into<Arc<[Felt]>>,
149{
150 fn extend<I>(&mut self, iter: I)
151 where
152 I: IntoIterator<Item = (Word, V)>,
153 {
154 self.0.extend(iter.into_iter().map(|(key, value)| (key, value.into())))
155 }
156}
157
158impl Serializable for AdviceMap {
159 fn write_into<W: ByteWriter>(&self, target: &mut W) {
160 target.write_usize(self.0.len());
161 for (key, values) in self.0.iter() {
162 target.write((key, values.to_vec()));
163 }
164 }
165}
166
167impl Deserializable for AdviceMap {
168 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
169 let mut map = BTreeMap::new();
170 let count = source.read_usize()?;
171 for _ in 0..count {
172 let (key, values): (Word, Vec<Felt>) = source.read()?;
173 map.insert(key, Arc::from(values));
174 }
175 Ok(Self(map))
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182
183 #[test]
184 fn test_advice_map_serialization() {
185 let mut map1 = AdviceMap::default();
186 map1.insert(Word::default(), vec![Felt::from(1u32), Felt::from(2u32)]);
187
188 let bytes = map1.to_bytes();
189
190 let map2 = AdviceMap::read_from_bytes(&bytes).unwrap();
191
192 assert_eq!(map1, map2);
193 }
194}