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