1use std::collections::BTreeMap;
2
3use crate::cell::*;
4use crate::error::Error;
5use crate::util::{unlikely, IterStatus};
6
7use super::{
8 build_dict_from_sorted_iter, dict_find_bound, dict_find_bound_owned, dict_find_owned, dict_get,
9 dict_get_owned, dict_get_subdict, dict_insert, dict_load_from_root, dict_remove_bound_owned,
10 dict_remove_owned, dict_split_by_prefix, read_label, DictBound, DictOwnedEntry, SetMode,
11};
12
13pub struct RawDict<const N: u16>(pub(crate) Option<Cell>);
40
41impl<const N: u16> ExactSize for RawDict<N> {
42 #[inline]
43 fn exact_size(&self) -> Size {
44 Size {
45 bits: 1,
46 refs: self.0.is_some() as u8,
47 }
48 }
49}
50
51impl<'a, const N: u16> Load<'a> for RawDict<N> {
52 #[inline]
53 fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
54 match <_>::load_from(slice) {
55 Ok(dict) => Ok(Self(dict)),
56 Err(e) => Err(e),
57 }
58 }
59}
60
61impl<const N: u16> Store for RawDict<N> {
62 #[inline]
63 fn store_into(
64 &self,
65 builder: &mut CellBuilder,
66 context: &mut dyn CellContext,
67 ) -> Result<(), Error> {
68 self.0.store_into(builder, context)
69 }
70}
71
72impl<const N: u16> Default for RawDict<N> {
73 #[inline]
74 fn default() -> Self {
75 Self(None)
76 }
77}
78
79impl<const N: u16> Clone for RawDict<N> {
80 fn clone(&self) -> Self {
81 Self(self.0.clone())
82 }
83}
84
85impl<const N: u16> Eq for RawDict<N> {}
86impl<const N: u16> PartialEq for RawDict<N> {
87 fn eq(&self, other: &Self) -> bool {
88 match (&self.0, &other.0) {
89 (Some(this), Some(other)) => this.as_ref() == other.as_ref(),
90 (None, None) => true,
91 _ => false,
92 }
93 }
94}
95
96impl<const N: u16> From<Option<Cell>> for RawDict<N> {
97 #[inline]
98 fn from(value: Option<Cell>) -> Self {
99 Self(value)
100 }
101}
102
103impl<const N: u16> std::fmt::Debug for RawDict<N> {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 f.debug_struct("RawDict")
106 .field("key_bit_len", &N)
107 .field("root", &self.0)
108 .finish()
109 }
110}
111
112impl<const N: u16> RawDict<N> {
113 const _ASSERT: () = assert!(N > 0, "Dict with 0-bit key is invalid");
114
115 pub const fn new() -> Self {
117 Self(None)
118 }
119
120 pub fn try_from_btree<K, V>(sorted: &BTreeMap<K, V>) -> Result<Self, Error>
122 where
123 K: Store + Ord,
124 V: Store,
125 {
126 let root = ok!(build_dict_from_sorted_iter(
127 sorted,
128 N,
129 &mut Cell::empty_context()
130 ));
131 Ok(Self(root))
132 }
133
134 pub fn try_from_sorted_slice<K, V>(sorted: &[(K, V)]) -> Result<Self, Error>
136 where
137 K: Store + Ord,
138 V: Store,
139 {
140 let root = ok!(build_dict_from_sorted_iter(
141 sorted.iter().map(|(k, v)| (k, v)),
142 N,
143 &mut Cell::empty_context()
144 ));
145 Ok(Self(root))
146 }
147
148 pub const fn is_empty(&self) -> bool {
150 self.0.is_none()
151 }
152
153 #[inline]
155 pub const fn root(&self) -> &Option<Cell> {
156 &self.0
157 }
158
159 #[inline]
161 pub fn into_root(self) -> Option<Cell> {
162 self.0
163 }
164
165 #[inline]
167 pub fn load_from_root_ext(
168 slice: &mut CellSlice<'_>,
169 context: &mut dyn CellContext,
170 ) -> Result<Self, Error> {
171 match dict_load_from_root(slice, N, context) {
172 Ok(root) => Ok(Self(Some(root))),
173 Err(e) => Err(e),
174 }
175 }
176
177 pub fn get<'a>(&'a self, key: CellSlice<'_>) -> Result<Option<CellSlice<'a>>, Error> {
181 dict_get(self.0.as_ref(), N, key, &mut Cell::empty_context())
182 }
183
184 pub fn get_ext<'a>(
186 &'a self,
187 key: CellSlice<'_>,
188 context: &mut dyn CellContext,
189 ) -> Result<Option<CellSlice<'a>>, Error> {
190 dict_get(self.0.as_ref(), N, key, context)
191 }
192
193 pub fn get_next_owned(
196 &self,
197 key: CellSlice<'_>,
198 signed: bool,
199 ) -> Result<Option<(CellBuilder, CellSliceParts)>, Error> {
200 dict_find_owned(
201 self.0.as_ref(),
202 N,
203 key,
204 DictBound::Max,
205 false,
206 signed,
207 &mut Cell::empty_context(),
208 )
209 }
210
211 pub fn get_subdict<'a>(
213 &'a self,
214 mut prefix: CellSlice<'a>,
215 context: &mut dyn CellContext,
216 ) -> Result<Option<Cell>, Error> {
217 dict_get_subdict(self.0.as_ref(), N, &mut prefix, context)
218 }
219
220 pub fn get_prev_owned(
223 &self,
224 key: CellSlice<'_>,
225 signed: bool,
226 ) -> Result<Option<(CellBuilder, CellSliceParts)>, Error> {
227 dict_find_owned(
228 self.0.as_ref(),
229 N,
230 key,
231 DictBound::Min,
232 false,
233 signed,
234 &mut Cell::empty_context(),
235 )
236 }
237
238 pub fn get_or_next_owned(
241 &self,
242 key: CellSlice<'_>,
243 signed: bool,
244 ) -> Result<Option<(CellBuilder, CellSliceParts)>, Error> {
245 dict_find_owned(
246 self.0.as_ref(),
247 N,
248 key,
249 DictBound::Max,
250 true,
251 signed,
252 &mut Cell::empty_context(),
253 )
254 }
255
256 pub fn get_or_prev_owned(
259 &self,
260 key: CellSlice<'_>,
261 signed: bool,
262 ) -> Result<Option<(CellBuilder, CellSliceParts)>, Error> {
263 dict_find_owned(
264 self.0.as_ref(),
265 N,
266 key,
267 DictBound::Min,
268 true,
269 signed,
270 &mut Cell::empty_context(),
271 )
272 }
273
274 pub fn get_owned(&self, key: CellSlice<'_>) -> Result<Option<CellSliceParts>, Error> {
278 dict_get_owned(self.0.as_ref(), N, key, &mut Cell::empty_context())
279 }
280
281 pub fn get_owned_ext(
283 &self,
284 key: CellSlice<'_>,
285 context: &mut dyn CellContext,
286 ) -> Result<Option<CellSliceParts>, Error> {
287 dict_get_owned(self.0.as_ref(), N, key, context)
288 }
289
290 pub fn get_min(&self, signed: bool) -> Result<Option<(CellBuilder, CellSlice<'_>)>, Error> {
292 dict_find_bound(
293 self.0.as_ref(),
294 N,
295 DictBound::Min,
296 signed,
297 &mut Cell::empty_context(),
298 )
299 }
300
301 pub fn get_max(&self, signed: bool) -> Result<Option<(CellBuilder, CellSlice<'_>)>, Error> {
303 dict_find_bound(
304 self.0.as_ref(),
305 N,
306 DictBound::Max,
307 signed,
308 &mut Cell::empty_context(),
309 )
310 }
311
312 pub fn get_bound(
314 &self,
315 bound: DictBound,
316 signed: bool,
317 ) -> Result<Option<(CellBuilder, CellSlice<'_>)>, Error> {
318 dict_find_bound(
319 self.0.as_ref(),
320 N,
321 bound,
322 signed,
323 &mut Cell::empty_context(),
324 )
325 }
326
327 pub fn get_bound_ext(
329 &self,
330 bound: DictBound,
331 signed: bool,
332 context: &mut dyn CellContext,
333 ) -> Result<Option<(CellBuilder, CellSlice<'_>)>, Error> {
334 dict_find_bound(self.0.as_ref(), N, bound, signed, context)
335 }
336
337 pub fn get_min_owned(
339 &self,
340 signed: bool,
341 ) -> Result<Option<(CellBuilder, CellSliceParts)>, Error> {
342 dict_find_bound_owned(
343 self.0.as_ref(),
344 N,
345 DictBound::Min,
346 signed,
347 &mut Cell::empty_context(),
348 )
349 }
350
351 pub fn get_max_owned(
353 &self,
354 signed: bool,
355 ) -> Result<Option<(CellBuilder, CellSliceParts)>, Error> {
356 dict_find_bound_owned(
357 self.0.as_ref(),
358 N,
359 DictBound::Max,
360 signed,
361 &mut Cell::empty_context(),
362 )
363 }
364
365 pub fn get_bound_owned(
367 &self,
368 bound: DictBound,
369 signed: bool,
370 ) -> Result<Option<(CellBuilder, CellSliceParts)>, Error> {
371 dict_find_bound_owned(
372 self.0.as_ref(),
373 N,
374 bound,
375 signed,
376 &mut Cell::empty_context(),
377 )
378 }
379
380 pub fn get_bound_owned_ext(
382 &self,
383 bound: DictBound,
384 signed: bool,
385 context: &mut dyn CellContext,
386 ) -> Result<Option<(CellBuilder, CellSliceParts)>, Error> {
387 dict_find_bound_owned(self.0.as_ref(), N, bound, signed, context)
388 }
389
390 pub fn contains_key(&self, key: CellSlice<'_>) -> Result<bool, Error> {
392 Ok(ok!(dict_get(
393 self.0.as_ref(),
394 N,
395 key,
396 &mut Cell::empty_context()
397 ))
398 .is_some())
399 }
400
401 pub fn set_ext(
403 &mut self,
404 mut key: CellSlice<'_>,
405 value: &dyn Store,
406 context: &mut dyn CellContext,
407 ) -> Result<bool, Error> {
408 dict_insert(&mut self.0, &mut key, N, &value, SetMode::Set, context)
409 }
410
411 pub fn replace_ext(
414 &mut self,
415 mut key: CellSlice<'_>,
416 value: &dyn Store,
417 context: &mut dyn CellContext,
418 ) -> Result<bool, Error> {
419 dict_insert(&mut self.0, &mut key, N, value, SetMode::Replace, context)
420 }
421
422 pub fn add_ext(
425 &mut self,
426 mut key: CellSlice<'_>,
427 value: &dyn Store,
428 context: &mut dyn CellContext,
429 ) -> Result<bool, Error> {
430 dict_insert(&mut self.0, &mut key, N, value, SetMode::Add, context)
431 }
432
433 pub fn remove_ext(
436 &mut self,
437 mut key: CellSlice<'_>,
438 context: &mut dyn CellContext,
439 ) -> Result<Option<CellSliceParts>, Error> {
440 dict_remove_owned(&mut self.0, &mut key, N, false, context)
441 }
442
443 pub fn remove_bound_ext(
446 &mut self,
447 bound: DictBound,
448 signed: bool,
449 context: &mut dyn CellContext,
450 ) -> Result<Option<DictOwnedEntry>, Error> {
451 dict_remove_bound_owned(&mut self.0, N, bound, signed, context)
452 }
453
454 pub fn split(&self) -> Result<(Self, Self), Error> {
456 self.split_by_prefix_ext(&Default::default(), &mut Cell::empty_context())
457 }
458
459 pub fn split_ext(&self, context: &mut dyn CellContext) -> Result<(Self, Self), Error> {
461 self.split_by_prefix_ext(&Default::default(), context)
462 }
463
464 pub fn split_by_prefix(&self, key_prefix: &CellSlice<'_>) -> Result<(Self, Self), Error> {
466 self.split_by_prefix_ext(key_prefix, &mut Cell::empty_context())
467 }
468
469 pub fn split_by_prefix_ext(
471 &self,
472 key_prefix: &CellSlice<'_>,
473 context: &mut dyn CellContext,
474 ) -> Result<(Self, Self), Error> {
475 let (left, right) = ok!(dict_split_by_prefix(
476 self.0.as_ref(),
477 N,
478 key_prefix,
479 context
480 ));
481 Ok((Self(left), Self(right)))
482 }
483
484 pub fn iter(&'_ self) -> RawIter<'_> {
497 RawIter::new(&self.0, N)
498 }
499
500 pub fn iter_union<'a>(&'a self, other: &'a RawDict<N>) -> UnionRawIter<'a> {
514 UnionRawIter::new(&self.0, &other.0, N)
515 }
516
517 pub fn iter_owned(&'_ self) -> RawOwnedIter<'_> {
530 RawOwnedIter::new(&self.0, N)
531 }
532
533 pub fn keys(&'_ self) -> RawKeys<'_> {
546 RawKeys::new(&self.0, N)
547 }
548
549 pub fn values(&'_ self) -> RawValues<'_> {
555 RawValues::new(&self.0, N)
556 }
557
558 pub fn values_owned(&'_ self) -> RawOwnedValues<'_> {
564 RawOwnedValues::new(&self.0, N)
565 }
566
567 pub fn set<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
573 self.set_ext(key, &value, &mut Cell::empty_context())
574 }
575
576 pub fn replace<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
583 self.replace_ext(key, &value, &mut Cell::empty_context())
584 }
585
586 pub fn add<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
593 self.add_ext(key, &value, &mut Cell::empty_context())
594 }
595
596 pub fn remove(&mut self, key: CellSlice<'_>) -> Result<Option<CellSliceParts>, Error> {
603 self.remove_ext(key, &mut Cell::empty_context())
604 }
605
606 pub fn remove_min(&mut self, signed: bool) -> Result<Option<DictOwnedEntry>, Error> {
613 self.remove_bound_ext(DictBound::Min, signed, &mut Cell::empty_context())
614 }
615
616 pub fn remove_max(&mut self, signed: bool) -> Result<Option<DictOwnedEntry>, Error> {
623 self.remove_bound_ext(DictBound::Max, signed, &mut Cell::empty_context())
624 }
625
626 pub fn remove_bound(
633 &mut self,
634 bound: DictBound,
635 signed: bool,
636 ) -> Result<Option<DictOwnedEntry>, Error> {
637 self.remove_bound_ext(bound, signed, &mut Cell::empty_context())
638 }
639}
640
641#[derive(Clone)]
648pub struct RawOwnedIter<'a> {
649 root: &'a Option<Cell>,
650 inner: RawIter<'a>,
651}
652
653impl<'a> RawOwnedIter<'a> {
654 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
656 Self {
657 inner: RawIter::new(root, bit_len),
658 root,
659 }
660 }
661
662 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
665 Self {
666 inner: RawIter::new_ext(root, bit_len, reversed, signed),
667 root,
668 }
669 }
670
671 #[inline]
673 pub fn reversed(mut self) -> Self {
674 self.inner.reversed = true;
675 self
676 }
677
678 #[inline]
680 pub fn signed(mut self) -> Self {
681 self.inner.signed = true;
682 self
683 }
684
685 #[inline]
687 pub fn is_reversed(&self) -> bool {
688 self.inner.reversed
689 }
690
691 #[inline]
693 pub fn is_signed(&self) -> bool {
694 self.inner.signed
695 }
696}
697
698impl<'a> Iterator for RawOwnedIter<'a> {
699 type Item = Result<(CellBuilder, CellSliceParts), Error>;
700
701 fn next(&mut self) -> Option<Self::Item> {
702 self.inner.next_owned(self.root)
703 }
704}
705
706#[derive(Clone)]
715pub struct RawIter<'a> {
716 segments: Vec<IterSegment<'a>>,
717 status: IterStatus,
718 builder: Box<CellBuilder>,
719 reversed: bool,
720 signed: bool,
721}
722
723impl<'a> RawIter<'a> {
724 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
726 Self::new_ext(root, bit_len, false, false)
727 }
728
729 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
732 let mut segments = Vec::new();
733
734 if let Some(root) = root {
736 let Ok(data) = root.as_slice() else {
737 return Self {
738 segments: Vec::new(),
739 status: IterStatus::Pruned,
740 builder: Box::default(),
741 reversed,
742 signed,
743 };
744 };
745
746 segments.push(IterSegment {
747 data,
748 remaining_bit_len: bit_len,
749 prefix: None,
750 });
751 }
752
753 Self {
754 segments,
755 status: IterStatus::Valid,
756 builder: Default::default(),
757 reversed,
758 signed,
759 }
760 }
761
762 #[inline]
764 pub fn reversed(mut self) -> Self {
765 self.reversed = true;
766 self
767 }
768
769 #[inline]
771 pub fn signed(mut self) -> Self {
772 self.signed = true;
773 self
774 }
775
776 #[inline]
778 pub fn is_reversed(&self) -> bool {
779 self.reversed
780 }
781
782 #[inline]
784 pub fn is_signed(&self) -> bool {
785 self.signed
786 }
787
788 pub fn next_owned(
790 &mut self,
791 root: &Option<Cell>,
792 ) -> Option<Result<(CellBuilder, CellSliceParts), Error>> {
793 Some(match self.next()? {
794 Ok((key, slice)) => {
795 let parent = match self.segments.last() {
796 Some(segment) => {
797 let refs_offset = segment.data.offset_refs();
798 debug_assert!(
799 segment.prefix.is_some() && (refs_offset == 1 || refs_offset == 2)
800 );
801
802 let next_bit = (refs_offset != 1)
803 ^ self.reversed
804 ^ (self.signed
805 && self.segments.len() == 1
806 && segment.prefix.unwrap().is_data_empty());
807
808 match segment.data.cell().reference_cloned(next_bit as u8) {
809 Some(cell) => cell,
810 None => return Some(Err(self.finish(Error::CellUnderflow))),
811 }
812 }
813 None => match root {
814 Some(root) => root.clone(),
815 None => {
816 debug_assert!(false, "Non-empty iterator for empty dict");
817 unsafe { std::hint::unreachable_unchecked() };
818 }
819 },
820 };
821 Ok((key, (parent, slice.range())))
822 }
823 Err(e) => Err(e),
824 })
825 }
826
827 #[inline]
828 pub(crate) fn finish(&mut self, err: Error) -> Error {
829 self.status = IterStatus::Broken;
830 err
831 }
832}
833
834impl<'a> Iterator for RawIter<'a> {
835 type Item = Result<(CellBuilder, CellSlice<'a>), Error>;
836
837 fn next(&mut self) -> Option<Self::Item> {
838 if unlikely(!self.status.is_valid()) {
839 return if self.status.is_pruned() {
840 self.status = IterStatus::Broken;
841 Some(Err(Error::PrunedBranchAccess))
842 } else {
843 None
844 };
845 }
846
847 fn next_impl<'a>(
848 reverse: bool,
849 signed: bool,
850 segments: &mut Vec<IterSegment<'a>>,
851 builder: &mut CellBuilder,
852 ) -> Result<Option<(CellBuilder, CellSlice<'a>)>, Error> {
853 #[allow(clippy::never_loop)]
854 loop {
855 let mut to_rewind = 0;
856 let segment = loop {
857 let is_root = segments.len() == 1;
858 let Some(segment) = segments.last_mut() else {
859 return Ok(None);
860 };
861
862 let Some(prefix) = &segment.prefix else {
864 break segment;
865 };
866
867 let refs_offset = segment.data.offset_refs();
868 if refs_offset < 2 {
869 let remaining_bit_len = segment.remaining_bit_len;
871 let next_bit = (refs_offset != 0)
872 ^ reverse
873 ^ (signed && is_root && prefix.is_data_empty());
874
875 let data = ok!(segment.data.cell().get_reference_as_slice(next_bit as u8));
876 segment.data.skip_first(0, 1).ok();
877
878 ok!(builder.rewind(to_rewind));
879 ok!(builder.store_bit(next_bit));
880 segments.push(IterSegment {
881 data,
882 prefix: None,
883 remaining_bit_len,
884 });
885 break (unsafe { segments.last_mut().unwrap_unchecked() });
887 } else {
888 to_rewind += prefix.size_bits();
890 segments.pop();
892 to_rewind += !segments.is_empty() as u16;
894 }
895 };
896
897 let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
899
900 return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
902 Some(0) => {
904 let mut key = builder.clone();
906 ok!(key.store_slice_data(prefix));
907
908 let data = segment.data;
909
910 segments.pop();
912 ok!(builder.rewind(!segments.is_empty() as u16));
913
914 Ok(Some((key, data)))
915 }
916 Some(remaining) => {
918 if segment.data.size_refs() < 2 {
919 return Err(Error::CellUnderflow);
920 }
921
922 ok!(builder.store_slice_data(prefix));
924
925 segment.prefix = Some(prefix);
927 segment.remaining_bit_len = remaining - 1;
928
929 continue;
931 }
932 None => Err(Error::CellUnderflow),
933 };
934 }
935 }
936
937 match next_impl(
938 self.reversed,
939 self.signed,
940 &mut self.segments,
941 &mut self.builder,
942 ) {
943 Ok(res) => res.map(Ok),
944 Err(e) => Some(Err(self.finish(e))),
945 }
946 }
947}
948
949#[derive(Clone)]
950struct IterSegment<'a> {
951 data: CellSlice<'a>,
952 remaining_bit_len: u16,
953 prefix: Option<CellSlice<'a>>,
954}
955
956#[derive(Clone)]
965pub struct UnionRawIter<'a> {
966 left: RawIter<'a>,
967 left_peeked: Option<Box<(CellBuilder, CellSlice<'a>)>>,
968 left_finished: bool,
969 right: RawIter<'a>,
970 right_peeked: Option<Box<(CellBuilder, CellSlice<'a>)>>,
971 right_finished: bool,
972}
973
974impl<'a> UnionRawIter<'a> {
975 pub fn new(left_root: &'a Option<Cell>, right_root: &'a Option<Cell>, bit_len: u16) -> Self {
977 Self::new_ext(left_root, right_root, bit_len, false, false)
978 }
979
980 pub fn new_ext(
983 left_root: &'a Option<Cell>,
984 right_root: &'a Option<Cell>,
985 bit_len: u16,
986 reversed: bool,
987 signed: bool,
988 ) -> Self {
989 Self {
990 left: RawIter::new_ext(left_root, bit_len, reversed, signed),
991 left_peeked: None,
992 left_finished: false,
993 right: RawIter::new_ext(right_root, bit_len, reversed, signed),
994 right_peeked: None,
995 right_finished: false,
996 }
997 }
998
999 #[inline]
1001 pub fn reversed(mut self) -> Self {
1002 self.left.reversed = true;
1003 self.right.reversed = true;
1004 self
1005 }
1006
1007 #[inline]
1009 pub fn signed(mut self) -> Self {
1010 self.left.signed = true;
1011 self.right.signed = true;
1012 self
1013 }
1014
1015 #[inline]
1017 pub fn is_reversed(&self) -> bool {
1018 self.left.reversed
1019 }
1020
1021 #[inline]
1023 pub fn is_signed(&self) -> bool {
1024 self.left.signed
1025 }
1026
1027 #[inline]
1028 pub(crate) fn finish(&mut self, err: Error) -> Error {
1029 self.left.status = IterStatus::Broken;
1030 self.right.status = IterStatus::Broken;
1031 err
1032 }
1033
1034 fn peek<'p>(
1035 iter: &mut RawIter<'a>,
1036 finished: &mut bool,
1037 peeked: &'p mut Option<Box<(CellBuilder, CellSlice<'a>)>>,
1038 ) -> Result<Option<&'p (CellBuilder, CellSlice<'a>)>, Error> {
1039 if !*finished && peeked.is_none() {
1040 match iter.next() {
1041 Some(Ok(next)) => {
1042 *peeked = Some(Box::new(next));
1043 }
1044 Some(Err(e)) => {
1045 *finished = true;
1046 return Err(e);
1047 }
1048 None => *finished = true,
1049 }
1050 }
1051 Ok(peeked.as_deref())
1052 }
1053}
1054
1055impl<'a> Iterator for UnionRawIter<'a> {
1056 type Item = Result<(CellBuilder, Option<CellSlice<'a>>, Option<CellSlice<'a>>), Error>;
1057
1058 fn next(&mut self) -> Option<Self::Item> {
1059 if unlikely(!self.left.status.is_valid() || !self.right.status.is_valid()) {
1060 if !self.left.status.is_pruned() && !self.right.status.is_pruned() {
1061 return None;
1062 }
1063
1064 self.left.status = IterStatus::Broken;
1065 self.right.status = IterStatus::Broken;
1066 return Some(Err(Error::PrunedBranchAccess));
1067 }
1068
1069 let reversed = self.is_reversed();
1070 let signed = self.is_signed();
1071
1072 let left = match Self::peek(
1073 &mut self.left,
1074 &mut self.left_finished,
1075 &mut self.left_peeked,
1076 ) {
1077 Ok(res) => res,
1078 Err(e) => return Some(Err(self.finish(e))),
1079 };
1080
1081 let right = match Self::peek(
1082 &mut self.right,
1083 &mut self.right_finished,
1084 &mut self.right_peeked,
1085 ) {
1086 Ok(res) => res,
1087 Err(e) => return Some(Err(self.finish(e))),
1088 };
1089
1090 match (left, right) {
1091 (None, None) => None,
1092 (Some((left_key, left_value)), None) => {
1093 let res = Some(Ok((left_key.clone(), Some(*left_value), None)));
1094 self.left_peeked = None;
1095 res
1096 }
1097 (None, Some((right_key, right_value))) => {
1098 let res = Some(Ok((right_key.clone(), None, Some(*right_value))));
1099 self.right_peeked = None;
1100 res
1101 }
1102 (Some((left_key, left_value)), Some((right_key, right_value))) => {
1103 let cmp = {
1104 let left_key = left_key.as_data_slice();
1105 let right_key = right_key.as_data_slice();
1106
1107 let mut reversed = reversed;
1108 if signed {
1109 let left_is_neg = left_key.get_bit(0).ok().unwrap_or_default();
1110 let right_is_neg = right_key.get_bit(0).ok().unwrap_or_default();
1111 reversed ^= left_is_neg != right_is_neg;
1112 }
1113
1114 let cmp = match left_key.lex_cmp(&right_key) {
1115 Ok(cmp) => cmp,
1116 Err(e) => return Some(Err(self.finish(e))),
1117 };
1118
1119 if reversed {
1120 cmp.reverse()
1121 } else {
1122 cmp
1123 }
1124 };
1125
1126 match cmp {
1127 std::cmp::Ordering::Less => {
1128 let res = Some(Ok((left_key.clone(), Some(*left_value), None)));
1129 self.left_peeked = None;
1130 res
1131 }
1132 std::cmp::Ordering::Greater => {
1133 let res = Some(Ok((right_key.clone(), None, Some(*right_value))));
1134 self.right_peeked = None;
1135 res
1136 }
1137 std::cmp::Ordering::Equal => {
1138 let res = Some(Ok((
1139 left_key.clone(),
1140 Some(*left_value),
1141 Some(*right_value),
1142 )));
1143 self.left_peeked = None;
1144 self.right_peeked = None;
1145 res
1146 }
1147 }
1148 }
1149 }
1150 }
1151}
1152
1153#[derive(Clone)]
1162pub struct RawKeys<'a> {
1163 inner: RawIter<'a>,
1164}
1165
1166impl<'a> RawKeys<'a> {
1167 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1169 Self {
1170 inner: RawIter::new(root, bit_len),
1171 }
1172 }
1173
1174 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1177 Self {
1178 inner: RawIter::new_ext(root, bit_len, reversed, signed),
1179 }
1180 }
1181
1182 #[inline]
1184 pub fn reversed(mut self) -> Self {
1185 self.inner.reversed = true;
1186 self
1187 }
1188
1189 #[inline]
1191 pub fn signed(mut self) -> Self {
1192 self.inner.signed = true;
1193 self
1194 }
1195
1196 #[inline]
1198 pub fn is_reversed(&self) -> bool {
1199 self.inner.reversed
1200 }
1201
1202 #[inline]
1204 pub fn is_signed(&self) -> bool {
1205 self.inner.signed
1206 }
1207}
1208
1209impl<'a> Iterator for RawKeys<'a> {
1210 type Item = Result<CellBuilder, Error>;
1211
1212 fn next(&mut self) -> Option<Self::Item> {
1213 match self.inner.next()? {
1214 Ok((key, _)) => Some(Ok(key)),
1215 Err(e) => Some(Err(e)),
1216 }
1217 }
1218}
1219
1220#[derive(Clone)]
1227pub struct RawOwnedValues<'a> {
1228 root: &'a Option<Cell>,
1229 inner: RawValues<'a>,
1230}
1231
1232impl<'a> RawOwnedValues<'a> {
1233 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1235 Self {
1236 inner: RawValues::new(root, bit_len),
1237 root,
1238 }
1239 }
1240
1241 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1244 Self {
1245 inner: RawValues::new_ext(root, bit_len, reversed, signed),
1246 root,
1247 }
1248 }
1249
1250 #[inline]
1252 pub fn reversed(mut self) -> Self {
1253 self.inner.reversed = true;
1254 self
1255 }
1256
1257 #[inline]
1259 pub fn signed(mut self) -> Self {
1260 self.inner.signed = true;
1261 self
1262 }
1263
1264 #[inline]
1266 pub fn is_reversed(&self) -> bool {
1267 self.inner.reversed
1268 }
1269
1270 #[inline]
1272 pub fn is_signed(&self) -> bool {
1273 self.inner.signed
1274 }
1275}
1276
1277impl<'a> Iterator for RawOwnedValues<'a> {
1278 type Item = Result<CellSliceParts, Error>;
1279
1280 fn next(&mut self) -> Option<Self::Item> {
1281 Some(match self.inner.next()? {
1282 Ok(slice) => {
1283 let parent = match self.inner.segments.last() {
1284 Some(segment) => {
1285 let refs_offset = segment.data.offset_refs();
1286 debug_assert!(refs_offset > 0);
1287 match segment.data.cell().reference_cloned(refs_offset - 1) {
1288 Some(cell) => cell,
1289 None => return Some(Err(self.inner.finish(Error::CellUnderflow))),
1290 }
1291 }
1292 None => match self.root {
1293 Some(root) => root.clone(),
1294 None => {
1295 debug_assert!(false, "Non-empty iterator for empty dict");
1296 unsafe { std::hint::unreachable_unchecked() };
1297 }
1298 },
1299 };
1300 Ok((parent, slice.range()))
1301 }
1302 Err(e) => Err(e),
1303 })
1304 }
1305}
1306
1307#[derive(Clone)]
1316pub struct RawValues<'a> {
1317 segments: Vec<ValuesSegment<'a>>,
1318 status: IterStatus,
1319 reversed: bool,
1320 signed: bool,
1321}
1322
1323impl<'a> RawValues<'a> {
1324 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1326 Self::new_ext(root, bit_len, false, false)
1327 }
1328
1329 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1332 let mut segments = Vec::new();
1333 if let Some(root) = root {
1334 let Ok(data) = root.as_slice() else {
1335 return Self {
1336 segments: Vec::new(),
1337 status: IterStatus::Pruned,
1338 reversed,
1339 signed,
1340 };
1341 };
1342
1343 segments.push(ValuesSegment {
1344 data,
1345 remaining_bit_len: bit_len,
1346 });
1347 }
1348 Self {
1349 segments,
1350 status: IterStatus::Valid,
1351 reversed,
1352 signed,
1353 }
1354 }
1355
1356 #[inline]
1358 pub fn reversed(mut self) -> Self {
1359 self.reversed = true;
1360 self
1361 }
1362
1363 #[inline]
1365 pub fn signed(mut self) -> Self {
1366 self.signed = true;
1367 self
1368 }
1369
1370 #[inline]
1372 pub fn is_reversed(&self) -> bool {
1373 self.reversed
1374 }
1375
1376 #[inline]
1378 pub fn is_signed(&self) -> bool {
1379 self.signed
1380 }
1381
1382 #[inline]
1383 pub(crate) fn finish(&mut self, err: Error) -> Error {
1384 self.status = IterStatus::Broken;
1385 err
1386 }
1387}
1388
1389impl<'a> Iterator for RawValues<'a> {
1390 type Item = Result<CellSlice<'a>, Error>;
1391
1392 fn next(&mut self) -> Option<Self::Item> {
1393 if unlikely(!self.status.is_valid()) {
1394 return if self.status.is_pruned() {
1395 self.status = IterStatus::Broken;
1396 Some(Err(Error::PrunedBranchAccess))
1397 } else {
1398 None
1399 };
1400 }
1401
1402 fn next_impl<'a>(
1403 reverse: bool,
1404 signed: bool,
1405 segments: &mut Vec<ValuesSegment<'a>>,
1406 ) -> Result<Option<CellSlice<'a>>, Error> {
1407 #[allow(clippy::never_loop)]
1408 loop {
1409 let segment = loop {
1411 let is_root = segments.len() == 1;
1412 let Some(segment) = segments.last_mut() else {
1413 return Ok(None);
1414 };
1415
1416 if segment.data.offset_bits() == 0 {
1417 break segment;
1418 }
1419
1420 let refs_offset = segment.data.offset_refs();
1421 if refs_offset < 2 {
1422 let remaining_bit_len = segment.remaining_bit_len;
1424 let next_bit = (refs_offset != 0)
1425 ^ reverse
1426 ^ (signed && is_root && segment.data.is_data_empty());
1427 let data = ok!(segment.data.cell().get_reference_as_slice(next_bit as u8));
1428 segment.data.skip_first(0, 1).ok();
1429
1430 segments.push(ValuesSegment {
1431 data,
1432 remaining_bit_len,
1433 });
1434 break (unsafe { segments.last_mut().unwrap_unchecked() });
1436 } else {
1437 segments.pop();
1438 }
1439 };
1440
1441 let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
1443
1444 return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
1446 Some(0) => {
1448 let data = segment.data;
1449 segments.pop();
1451 Ok(Some(data))
1452 }
1453 Some(remaining) => {
1455 if segment.data.size_refs() < 2 {
1456 return Err(Error::CellUnderflow);
1457 }
1458 segment.remaining_bit_len = remaining - 1;
1459 continue;
1461 }
1462 None => Err(Error::CellUnderflow),
1463 };
1464 }
1465 }
1466
1467 match next_impl(self.reversed, self.signed, &mut self.segments) {
1468 Ok(res) => res.map(Ok),
1469 Err(e) => Some(Err(self.finish(e))),
1470 }
1471 }
1472}
1473
1474#[derive(Copy, Clone)]
1475struct ValuesSegment<'a> {
1476 data: CellSlice<'a>,
1477 remaining_bit_len: u16,
1478}
1479
1480#[cfg(test)]
1481mod tests {
1482
1483 use super::*;
1484 use crate::prelude::*;
1485
1486 fn build_cell<F: FnOnce(&mut CellBuilder) -> Result<(), Error>>(f: F) -> Cell {
1487 let mut builder = CellBuilder::new();
1488 f(&mut builder).unwrap();
1489 builder.build().unwrap()
1490 }
1491
1492 #[test]
1493 fn dict_set() -> anyhow::Result<()> {
1494 let mut dict = RawDict::<32>::new();
1495
1496 let key = CellBuilder::build_from(123u32)?;
1497
1498 dict.set(key.as_slice()?, ())?;
1499 {
1500 let mut values = dict.values();
1501 let value = values.next().unwrap().unwrap();
1502 assert!(value.is_data_empty() && value.is_refs_empty());
1503 assert!(values.next().is_none());
1504 }
1505
1506 dict.set(key.as_slice()?, 0xffffu16)?;
1507 {
1508 let mut values = dict.values();
1509 let mut value = values.next().unwrap()?;
1510 assert_eq!(value.load_u16(), Ok(0xffff));
1511 assert!(value.is_data_empty() && value.is_refs_empty());
1512 assert!(values.next().is_none());
1513 }
1514
1515 Ok(())
1516 }
1517
1518 #[test]
1519 #[cfg_attr(miri, ignore)] fn dict_set_complex() -> anyhow::Result<()> {
1521 let mut dict = RawDict::<32>::new();
1522 for i in 0..520 {
1523 let key = build_cell(|b| b.store_u32(i));
1524 dict.set(key.as_slice()?, true)?;
1525
1526 let mut total = 0;
1527 for (i, item) in dict.iter().enumerate() {
1528 total += 1;
1529 let (key, value) = item?;
1530 let key = key.build()?;
1531 assert_eq!(value.size_bits(), 1);
1532 assert_eq!(key.bit_len(), 32);
1533 let key = key.as_slice()?.load_u32()?;
1534 assert_eq!(key, i as u32);
1535 }
1536 assert_eq!(total, i + 1);
1537 }
1538
1539 Ok(())
1540 }
1541
1542 #[test]
1543 fn dict_replace() -> anyhow::Result<()> {
1544 let mut dict = RawDict::<32>::new();
1545
1546 dict.replace(build_cell(|b| b.store_u32(123)).as_slice()?, false)
1548 .unwrap();
1549 assert!(!dict
1550 .contains_key(build_cell(|b| b.store_u32(123)).as_slice()?)
1551 .unwrap());
1552
1553 dict.set(build_cell(|b| b.store_u32(123)).as_slice()?, false)
1555 .unwrap();
1556 dict.replace(build_cell(|b| b.store_u32(123)).as_slice()?, true)
1557 .unwrap();
1558
1559 let mut value = dict
1560 .get(build_cell(|b| b.store_u32(123)).as_slice()?)
1561 .unwrap()
1562 .unwrap();
1563 assert_eq!(value.size_bits(), 1);
1564 assert_eq!(value.load_bit(), Ok(true));
1565
1566 Ok(())
1567 }
1568
1569 #[test]
1570 fn dict_add() -> anyhow::Result<()> {
1571 let mut dict = RawDict::<32>::new();
1572
1573 let key = build_cell(|b| b.store_u32(123));
1574
1575 dict.add(key.as_slice()?, false)?;
1577 let mut value = dict.get(key.as_slice()?)?.unwrap();
1578 assert_eq!(value.size_bits(), 1);
1579 assert_eq!(value.load_bit(), Ok(false));
1580
1581 dict.add(key.as_slice()?, true)?;
1583 let mut value = dict.get(key.as_slice()?)?.unwrap();
1584 assert_eq!(value.size_bits(), 1);
1585 assert_eq!(value.load_bit(), Ok(false));
1586
1587 Ok(())
1588 }
1589
1590 #[test]
1591 fn dict_split() -> anyhow::Result<()> {
1592 let mut dict = RawDict::<4>::new();
1593 for i in 0..16 {
1594 let key = build_cell(|b| b.store_small_uint(i, 4));
1595 dict.add(key.as_slice()?, i)?;
1596 }
1597
1598 let (left, right) = dict.split()?;
1599 assert!(!left.is_empty());
1600 assert!(!right.is_empty());
1601 assert_eq!(left.iter().count(), 8);
1602 assert_eq!(right.iter().count(), 8);
1603
1604 let (ll, lr) = left.split()?;
1605 assert!(!ll.is_empty());
1606 assert!(lr.is_empty());
1607 assert_eq!(ll.iter().count(), 8);
1608
1609 let (rl, rr) = right.split()?;
1610 assert!(rl.is_empty());
1611 assert!(!rr.is_empty());
1612 assert_eq!(rr.iter().count(), 8);
1613
1614 let (left, right) = RawDict::<4>::new().split()?;
1615 assert!(left.is_empty());
1616 assert!(right.is_empty());
1617
1618 Ok(())
1619 }
1620
1621 #[test]
1622 fn dict_split_by_prefix() -> anyhow::Result<()> {
1623 fn check_range(dict: &RawDict<4>, mut range: std::ops::Range<u8>) {
1624 for key in dict.keys() {
1625 let key = key.unwrap();
1626 let key = key.as_data_slice().load_small_uint(4).unwrap();
1627 assert_eq!(key, range.next().unwrap());
1628 }
1629 assert_eq!(range.next(), None);
1630 }
1631
1632 let mut dict = RawDict::<4>::new();
1633 for i in 0..16 {
1634 let key = build_cell(|b| b.store_small_uint(i, 4));
1635 dict.add(key.as_slice()?, i)?;
1636 }
1637
1638 let (left, right) = dict.split()?;
1639 check_range(&left, 0..8);
1640 check_range(&right, 8..16);
1641
1642 {
1643 let mut prefix = CellBuilder::new();
1644 prefix.store_bit_one()?;
1645 let res = dict.split_by_prefix(&prefix.as_data_slice());
1646 assert!(matches!(res, Err(Error::CellUnderflow)));
1647 }
1648
1649 let (ll, lr) = {
1650 let mut prefix = CellBuilder::new();
1651 prefix.store_bit_zero()?;
1652 left.split_by_prefix(&prefix.as_data_slice())?
1653 };
1654 check_range(&ll, 0..4);
1655 check_range(&lr, 4..8);
1656
1657 let (rl, rr) = {
1658 let mut prefix = CellBuilder::new();
1659 prefix.store_bit_one()?;
1660 right.split_by_prefix(&prefix.as_data_slice())?
1661 };
1662 check_range(&rl, 8..12);
1663 check_range(&rr, 12..16);
1664
1665 Ok(())
1666 }
1667
1668 #[test]
1669 fn dict_get_subdict() -> anyhow::Result<()> {
1670 let mut dict = RawDict::<32>::new();
1671 for i in 0u32..4 {
1672 let key = CellBuilder::build_from(i)?;
1674 println!("ADDING KEY {}", key.display_data());
1675 dict.add(key.as_slice()?, i)?;
1676 }
1677
1678 let cell = dict.root().as_ref().unwrap();
1679 let boc = Boc::encode_base64(cell);
1680
1681 println!("{}", boc);
1682
1683 let key = CellBuilder::build_from(1u16 << 8)?;
1684
1685 println!("KEY: {}", key.display_data());
1686
1687 let context = &mut SimpleContext::default();
1688
1689 let value: Cell = dict.get_subdict(key.as_slice()?, context)?.unwrap();
1690
1691 print!("{}", value.display_tree());
1692
1693 Ok(())
1694 }
1695
1696 #[test]
1697 fn dict_get() -> anyhow::Result<()> {
1698 let boc =
1699 Boc::decode_base64("te6ccgECOwEAASoAAQHAAQIBIBACAgEgAwMCASAEBAIBIAUFAgEgBgYCASAHBwIBIAgIAgEgCQkCASAoCgIBIAsZAgEgDBsCASArDQIBIA4fAgEgLQ8CASAuIQIBIBERAgEgEhICASATEwIBIBQUAgEgFRUCASAWFgIBIBcXAgEgKBgCASAaGQIBIBsbAgEgHRsCASAcHAIBIB8fAgEgKx4CASAiHwIBICAgAgEgISECASAlJQIBIC0jAgEgLiQCASAvJQIBIDMmAgFiNicCAUg4OAIBICkpAgEgKioCASArKwIBICwsAgEgLS0CASAuLgIBIC8vAgEgMzACAWI2MQIBIDcyAAnWAAAmbwIBIDQ0AgEgNTUCASA2NgIBIDc3AgEgODgCASA5OQIBIDo6AAnQAAAmbw==")?;
1700
1701 let dict = boc.parse::<RawDict<32>>()?;
1704
1705 let key = CellBuilder::build_from(u32::from_be_bytes(123u32.to_le_bytes()))?;
1706 let value = dict.get(key.as_slice()?)?.unwrap();
1707
1708 {
1709 let (cell, range) = dict.get_owned(key.as_slice()?)?.unwrap();
1710 assert_eq!(range.apply(&cell).unwrap(), value);
1711 }
1712
1713 let value = {
1714 let mut builder = CellBuilder::new();
1715 builder.store_slice(value)?;
1716 builder.build()?
1717 };
1718 println!("{}", value.display_tree());
1719
1720 Ok(())
1721 }
1722
1723 #[test]
1724 fn dict_iter() -> anyhow::Result<()> {
1725 let boc = Boc::decode_base64("te6ccgEBFAEAeAABAcABAgPOQAUCAgHUBAMACQAAAI3gAAkAAACjoAIBIA0GAgEgCgcCASAJCAAJAAAAciAACQAAAIfgAgEgDAsACQAAAFZgAAkAAABsIAIBIBEOAgEgEA8ACQAAADqgAAkAAABQYAIBIBMSAAkAAAAe4AAJAAAAv2A=")?;
1726 let dict = boc.parse::<RawDict<32>>()?;
1727
1728 let size = dict.values().count();
1729 assert_eq!(size, 10);
1730
1731 let mut rev_iter_items = dict.iter().reversed().collect::<Vec<_>>();
1732 rev_iter_items.reverse();
1733 let mut rev_iter_items = rev_iter_items.into_iter();
1734
1735 for (i, entry) in dict.iter().enumerate() {
1736 let (key, value) = entry?;
1737
1738 let (rev_key, rev_value) = rev_iter_items.next().unwrap().unwrap();
1739 assert_eq!(key, rev_key);
1740 assert_eq!(value.lex_cmp(&rev_value), Ok(std::cmp::Ordering::Equal));
1741
1742 let key = {
1743 let key_cell = key.build()?;
1744 key_cell.as_slice()?.load_u32()?
1745 };
1746 assert_eq!(key, i as u32);
1747 }
1748 assert!(rev_iter_items.next().is_none());
1749
1750 let mut last = None;
1751 for (i, entry) in dict.iter_owned().enumerate() {
1752 let (key, (cell, range)) = entry?;
1753
1754 {
1755 let mut slice = range.apply(&cell).unwrap();
1756 assert_eq!(slice.size_bits(), 32);
1757 u32::load_from(&mut slice).unwrap();
1758 }
1759
1760 let key = {
1761 let key_cell = key.build()?;
1762 key_cell.as_slice()?.load_u32()?
1763 };
1764 assert_eq!(key, i as u32);
1765 last = Some(key);
1766 }
1767 assert_eq!(last, Some(9));
1768
1769 let mut values_ref = dict.values();
1770 let mut values_owned = dict.values_owned();
1771 for (value_ref, value_owned) in (&mut values_ref).zip(&mut values_owned) {
1772 let value_ref = value_ref.unwrap();
1773 let (cell, range) = value_owned.unwrap();
1774 let value_owned = range.apply(&cell).unwrap();
1775 assert_eq!(
1776 value_ref.lex_cmp(&value_owned),
1777 Ok(std::cmp::Ordering::Equal)
1778 );
1779 }
1780 assert!(values_ref.next().is_none());
1781 assert!(values_owned.next().is_none());
1782
1783 Ok(())
1784 }
1785
1786 #[test]
1787 fn dict_iter_union() -> anyhow::Result<()> {
1788 let mut left = RawDict::<32>::new();
1789 let mut right = RawDict::<32>::new();
1790
1791 for i in -4i32..4 {
1793 let key = build_cell(|b| b.store_u32(i as _));
1794 left.set(key.as_slice()?, i)?;
1795 }
1796 for i in -2i32..6 {
1797 let key = build_cell(|b| b.store_u32(i as _));
1798 right.set(key.as_slice()?, i + 100)?;
1799 }
1800
1801 fn compare_iter_values(iter: UnionRawIter<'_>, values: &[(i32, Option<i32>, Option<i32>)]) {
1802 let mut values = values.iter();
1803
1804 for entry in iter {
1805 let (key, left_value, right_value) = entry.unwrap();
1806 let key = key.as_data_slice().load_u32().unwrap() as i32;
1807 let left_value = left_value.map(|v| v.get_u32(0).unwrap() as i32);
1808 let right_value = right_value.map(|v| v.get_u32(0).unwrap() as i32);
1809
1810 assert_eq!(values.next(), Some(&(key, left_value, right_value)));
1811 }
1812 assert_eq!(values.next(), None);
1813 }
1814
1815 compare_iter_values(
1817 left.iter_union(&right),
1818 &[
1819 (0, Some(0), Some(100)),
1820 (1, Some(1), Some(101)),
1821 (2, Some(2), Some(102)),
1822 (3, Some(3), Some(103)),
1823 (4, None, Some(104)),
1824 (5, None, Some(105)),
1825 (-4, Some(-4), None),
1826 (-3, Some(-3), None),
1827 (-2, Some(-2), Some(98)),
1828 (-1, Some(-1), Some(99)),
1829 ],
1830 );
1831
1832 compare_iter_values(
1834 left.iter_union(&right).reversed(),
1835 &[
1836 (-1, Some(-1), Some(99)),
1837 (-2, Some(-2), Some(98)),
1838 (-3, Some(-3), None),
1839 (-4, Some(-4), None),
1840 (5, None, Some(105)),
1841 (4, None, Some(104)),
1842 (3, Some(3), Some(103)),
1843 (2, Some(2), Some(102)),
1844 (1, Some(1), Some(101)),
1845 (0, Some(0), Some(100)),
1846 ],
1847 );
1848
1849 compare_iter_values(
1851 left.iter_union(&right).signed(),
1852 &[
1853 (-4, Some(-4), None),
1854 (-3, Some(-3), None),
1855 (-2, Some(-2), Some(98)),
1856 (-1, Some(-1), Some(99)),
1857 (0, Some(0), Some(100)),
1858 (1, Some(1), Some(101)),
1859 (2, Some(2), Some(102)),
1860 (3, Some(3), Some(103)),
1861 (4, None, Some(104)),
1862 (5, None, Some(105)),
1863 ],
1864 );
1865
1866 compare_iter_values(
1868 left.iter_union(&right).signed().reversed(),
1869 &[
1870 (5, None, Some(105)),
1871 (4, None, Some(104)),
1872 (3, Some(3), Some(103)),
1873 (2, Some(2), Some(102)),
1874 (1, Some(1), Some(101)),
1875 (0, Some(0), Some(100)),
1876 (-1, Some(-1), Some(99)),
1877 (-2, Some(-2), Some(98)),
1878 (-3, Some(-3), None),
1879 (-4, Some(-4), None),
1880 ],
1881 );
1882
1883 Ok(())
1884 }
1885
1886 #[derive(Debug, Default)]
1887 struct SimpleContext {
1888 used_gas: u64,
1889 loaded_cells: ahash::HashSet<HashBytes>,
1890 empty_context: <Cell as CellFamily>::EmptyCellContext,
1891 }
1892
1893 impl SimpleContext {
1894 const BUILD_CELL_GAS: u64 = 500;
1895 const NEW_CELL_GAS: u64 = 100;
1896 const OLD_CELL_GAS: u64 = 25;
1897
1898 fn consume_gas(&mut self, cell: &DynCell, mode: LoadMode) {
1899 if mode.use_gas() {
1900 self.used_gas += if self.loaded_cells.insert(*cell.repr_hash()) {
1901 Self::NEW_CELL_GAS
1902 } else {
1903 Self::OLD_CELL_GAS
1904 };
1905 }
1906 }
1907 }
1908
1909 impl CellContext for SimpleContext {
1910 #[inline]
1911 fn finalize_cell(&mut self, cell: CellParts<'_>) -> Result<Cell, Error> {
1912 self.used_gas += Self::BUILD_CELL_GAS;
1913 self.empty_context.finalize_cell(cell)
1914 }
1915
1916 #[inline]
1917 fn load_cell(&mut self, cell: Cell, mode: LoadMode) -> Result<Cell, Error> {
1918 self.consume_gas(cell.as_ref(), mode);
1919 Ok(cell)
1920 }
1921
1922 #[inline]
1923 fn load_dyn_cell<'a>(
1924 &mut self,
1925 cell: &'a DynCell,
1926 mode: LoadMode,
1927 ) -> Result<&'a DynCell, Error> {
1928 self.consume_gas(cell, mode);
1929 Ok(cell)
1930 }
1931 }
1932
1933 #[test]
1934 fn dict_get_gas_usage() -> anyhow::Result<()> {
1935 let mut dict = RawDict::<32>::new();
1937 for i in 0..10 {
1938 let mut key = CellBuilder::new();
1939 key.store_u32(i)?;
1940 dict.set(key.as_data_slice(), i)?;
1941 }
1942
1943 let context = &mut SimpleContext::default();
1945
1946 let mut key = CellBuilder::new();
1947 key.store_u32(5)?;
1948
1949 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1950 assert_eq!(context.used_gas, SimpleContext::NEW_CELL_GAS * 5);
1951
1952 context.used_gas = 0;
1953 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1954 assert_eq!(context.used_gas, SimpleContext::OLD_CELL_GAS * 5);
1955
1956 context.used_gas = 0;
1958 let mut key = CellBuilder::new();
1959 key.store_u32(9)?;
1960
1961 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1962 assert_eq!(
1963 context.used_gas,
1964 SimpleContext::OLD_CELL_GAS + SimpleContext::NEW_CELL_GAS * 2
1965 );
1966
1967 context.used_gas = 0;
1968 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1969 assert_eq!(context.used_gas, SimpleContext::OLD_CELL_GAS * 3);
1970
1971 Ok(())
1972 }
1973
1974 #[test]
1975 fn dict_get_owned_gas_usage() -> anyhow::Result<()> {
1976 let mut dict = RawDict::<32>::new();
1978 for i in 0..10 {
1979 let mut key = CellBuilder::new();
1980 key.store_u32(i)?;
1981 dict.set(key.as_data_slice(), i)?;
1982 }
1983
1984 let context = &mut SimpleContext::default();
1986
1987 let mut key = CellBuilder::new();
1988 key.store_u32(5)?;
1989
1990 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1991 assert_eq!(context.used_gas, SimpleContext::NEW_CELL_GAS * 5);
1992
1993 context.used_gas = 0;
1994 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1995 assert_eq!(context.used_gas, SimpleContext::OLD_CELL_GAS * 5);
1996
1997 context.used_gas = 0;
1999 let mut key = CellBuilder::new();
2000 key.store_u32(9)?;
2001
2002 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
2003 assert_eq!(
2004 context.used_gas,
2005 SimpleContext::OLD_CELL_GAS + SimpleContext::NEW_CELL_GAS * 2
2006 );
2007
2008 context.used_gas = 0;
2009 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
2010 assert_eq!(context.used_gas, SimpleContext::OLD_CELL_GAS * 3);
2011
2012 Ok(())
2013 }
2014
2015 #[test]
2016 fn dict_remove_gas_usage() -> anyhow::Result<()> {
2017 let mut dict = RawDict::<32>::new();
2018 for i in 0..10 {
2019 let mut key = CellBuilder::new();
2020 key.store_u32(i)?;
2021 dict.set(key.as_data_slice(), i)?;
2022 }
2023
2024 let mut key = CellBuilder::new();
2026 key.store_u32(10)?;
2027
2028 let context = &mut SimpleContext::default();
2029 assert!(dict.remove_ext(key.as_data_slice(), context)?.is_none());
2030
2031 assert_eq!(context.used_gas, SimpleContext::NEW_CELL_GAS * 2);
2032
2033 let target_gas = [
2035 SimpleContext::NEW_CELL_GAS * 6 + SimpleContext::BUILD_CELL_GAS * 4,
2036 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2037 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2038 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2039 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2040 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2041 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2042 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS,
2043 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS,
2044 SimpleContext::NEW_CELL_GAS,
2045 ];
2046
2047 for i in 0..10 {
2048 println!("===");
2049
2050 let context = &mut SimpleContext::default();
2051
2052 let mut key = CellBuilder::new();
2053 key.store_u32(i)?;
2054
2055 let removed = dict.remove_ext(key.as_data_slice(), context)?;
2056 assert!(removed.is_some());
2057
2058 assert_eq!(context.used_gas, target_gas[i as usize]);
2059 }
2060
2061 Ok(())
2062 }
2063
2064 #[test]
2065 fn dict_remove_bound() -> anyhow::Result<()> {
2066 let make_dict = |range: std::ops::Range<i32>| {
2067 let mut dict = RawDict::<32>::new();
2068 for i in range {
2069 let mut key = CellBuilder::new();
2070 key.store_u32(i as u32)?;
2071 dict.set(key.as_data_slice(), i)?;
2072 }
2073 Ok::<_, anyhow::Error>(dict)
2074 };
2075
2076 let check_range =
2077 |range: std::ops::Range<i32>, bound: DictBound, signed: bool, target_gas: &[u64]| {
2078 let mut dict = make_dict(range.clone())?;
2079 for &target_gas in target_gas {
2080 println!("=== {range:?} bound={bound:?} signed={signed} [non-owned]");
2081 let context = &mut SimpleContext::default();
2082 let (key, _) = dict.get_bound_ext(bound, signed, context)?.unwrap();
2083 let removed = dict.clone().remove_ext(key.as_data_slice(), context)?;
2084 assert!(removed.is_some());
2085 assert_eq!(context.used_gas, target_gas);
2086
2087 println!("=== {range:?} bound={bound:?} signed={signed} [owned]");
2088 let context = &mut SimpleContext::default();
2089 let (key, _) = dict.get_bound_owned_ext(bound, signed, context)?.unwrap();
2090 let removed = dict.remove_ext(key.as_data_slice(), context)?;
2091 assert!(removed.is_some());
2092 assert_eq!(context.used_gas, target_gas);
2093 }
2094
2095 Ok::<_, anyhow::Error>(())
2096 };
2097
2098 let target_gas = [
2100 SimpleContext::NEW_CELL_GAS * 6
2101 + SimpleContext::OLD_CELL_GAS * 5
2102 + SimpleContext::BUILD_CELL_GAS * 4,
2103 SimpleContext::NEW_CELL_GAS * 5
2104 + SimpleContext::OLD_CELL_GAS * 4
2105 + SimpleContext::BUILD_CELL_GAS * 3,
2106 SimpleContext::NEW_CELL_GAS * 5
2107 + SimpleContext::OLD_CELL_GAS * 4
2108 + SimpleContext::BUILD_CELL_GAS * 3,
2109 SimpleContext::NEW_CELL_GAS * 4
2110 + SimpleContext::OLD_CELL_GAS * 3
2111 + SimpleContext::BUILD_CELL_GAS * 2,
2112 SimpleContext::NEW_CELL_GAS * 5
2113 + SimpleContext::OLD_CELL_GAS * 4
2114 + SimpleContext::BUILD_CELL_GAS * 3,
2115 SimpleContext::NEW_CELL_GAS * 4
2116 + SimpleContext::OLD_CELL_GAS * 3
2117 + SimpleContext::BUILD_CELL_GAS * 2,
2118 SimpleContext::NEW_CELL_GAS * 4
2119 + SimpleContext::OLD_CELL_GAS * 3
2120 + SimpleContext::BUILD_CELL_GAS * 2,
2121 SimpleContext::NEW_CELL_GAS * 3
2122 + SimpleContext::OLD_CELL_GAS * 2
2123 + SimpleContext::BUILD_CELL_GAS,
2124 SimpleContext::NEW_CELL_GAS * 3
2125 + SimpleContext::OLD_CELL_GAS * 2
2126 + SimpleContext::BUILD_CELL_GAS,
2127 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2128 ];
2129 check_range(0..10, DictBound::Min, false, &target_gas)?;
2130
2131 let target_gas = [
2133 SimpleContext::NEW_CELL_GAS * 4
2134 + SimpleContext::OLD_CELL_GAS * 3
2135 + SimpleContext::BUILD_CELL_GAS * 2,
2136 SimpleContext::NEW_CELL_GAS * 3
2137 + SimpleContext::OLD_CELL_GAS * 2
2138 + SimpleContext::BUILD_CELL_GAS,
2139 SimpleContext::NEW_CELL_GAS * 5
2140 + SimpleContext::OLD_CELL_GAS * 4
2141 + SimpleContext::BUILD_CELL_GAS * 3,
2142 SimpleContext::NEW_CELL_GAS * 4
2143 + SimpleContext::OLD_CELL_GAS * 3
2144 + SimpleContext::BUILD_CELL_GAS * 2,
2145 SimpleContext::NEW_CELL_GAS * 4
2146 + SimpleContext::OLD_CELL_GAS * 3
2147 + SimpleContext::BUILD_CELL_GAS * 2,
2148 SimpleContext::NEW_CELL_GAS * 3
2149 + SimpleContext::OLD_CELL_GAS * 2
2150 + SimpleContext::BUILD_CELL_GAS,
2151 SimpleContext::NEW_CELL_GAS * 4
2152 + SimpleContext::OLD_CELL_GAS * 3
2153 + SimpleContext::BUILD_CELL_GAS * 2,
2154 SimpleContext::NEW_CELL_GAS * 3
2155 + SimpleContext::OLD_CELL_GAS * 2
2156 + SimpleContext::BUILD_CELL_GAS,
2157 SimpleContext::NEW_CELL_GAS * 3
2158 + SimpleContext::OLD_CELL_GAS * 2
2159 + SimpleContext::BUILD_CELL_GAS,
2160 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2161 ];
2162 check_range(0..10, DictBound::Max, false, &target_gas)?;
2163
2164 let target_gas = [
2166 SimpleContext::NEW_CELL_GAS * 4
2167 + SimpleContext::OLD_CELL_GAS * 3
2168 + SimpleContext::BUILD_CELL_GAS * 2,
2169 SimpleContext::NEW_CELL_GAS * 5
2170 + SimpleContext::OLD_CELL_GAS * 4
2171 + SimpleContext::BUILD_CELL_GAS * 3,
2172 SimpleContext::NEW_CELL_GAS * 4
2173 + SimpleContext::OLD_CELL_GAS * 3
2174 + SimpleContext::BUILD_CELL_GAS * 2,
2175 SimpleContext::NEW_CELL_GAS * 4
2176 + SimpleContext::OLD_CELL_GAS * 3
2177 + SimpleContext::BUILD_CELL_GAS * 2,
2178 SimpleContext::NEW_CELL_GAS * 3
2179 + SimpleContext::OLD_CELL_GAS * 2
2180 + SimpleContext::BUILD_CELL_GAS,
2181 SimpleContext::NEW_CELL_GAS * 5
2182 + SimpleContext::OLD_CELL_GAS * 4
2183 + SimpleContext::BUILD_CELL_GAS * 3,
2184 SimpleContext::NEW_CELL_GAS * 4
2185 + SimpleContext::OLD_CELL_GAS * 3
2186 + SimpleContext::BUILD_CELL_GAS * 2,
2187 SimpleContext::NEW_CELL_GAS * 4
2188 + SimpleContext::OLD_CELL_GAS * 3
2189 + SimpleContext::BUILD_CELL_GAS * 2,
2190 SimpleContext::NEW_CELL_GAS * 3
2191 + SimpleContext::OLD_CELL_GAS * 2
2192 + SimpleContext::BUILD_CELL_GAS,
2193 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2194 ];
2195
2196 check_range(-5..5, DictBound::Min, true, &target_gas)?;
2198 check_range(-5..5, DictBound::Max, true, &target_gas)?;
2199
2200 Ok(())
2201 }
2202
2203 #[test]
2204 fn dict_insert_gas_usage() -> anyhow::Result<()> {
2205 let target_gas = [
2206 SimpleContext::BUILD_CELL_GAS,
2207 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2208 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2209 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2210 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2211 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2212 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2213 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS * 5,
2214 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2215 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2216 ];
2217
2218 let mut dict = RawDict::<32>::new();
2220 for i in 0..10 {
2221 let context = &mut SimpleContext::default();
2222
2223 let mut key = CellBuilder::new();
2224 key.store_u32(i)?;
2225
2226 dict.set_ext(key.as_data_slice(), &i, context)?;
2227
2228 assert_eq!(context.used_gas, target_gas[i as usize]);
2229
2230 println!("===");
2231 }
2232
2233 let mut dict = None::<Cell>;
2235 for i in 0..10 {
2236 let mut key = CellBuilder::new();
2237 key.store_u32(i)?;
2238
2239 let context = &mut SimpleContext::default();
2240 let mut old_root = dict.clone();
2241 dict_insert(
2242 &mut dict,
2243 &mut key.as_data_slice(),
2244 32,
2245 &i,
2246 SetMode::Set,
2247 context,
2248 )?;
2249 assert_eq!(context.used_gas, target_gas[i as usize]);
2250
2251 println!("===");
2252
2253 let context = &mut SimpleContext::default();
2254 let expected_new_root = dict.clone();
2255 crate::dict::dict_insert_owned(
2256 &mut old_root,
2257 &mut key.as_data_slice(),
2258 32,
2259 &i,
2260 SetMode::Set,
2261 context,
2262 )?;
2263 assert_eq!(dict, expected_new_root);
2264
2265 assert_eq!(context.used_gas, target_gas[i as usize]);
2266
2267 println!("===");
2268 }
2269
2270 let mut key = CellBuilder::new();
2272 key.store_u32(5)?;
2273
2274 let context = &mut SimpleContext::default();
2275 dict_insert(
2276 &mut dict,
2277 &mut key.as_data_slice(),
2278 32,
2279 &5u32,
2280 SetMode::Add,
2281 context,
2282 )?;
2283 assert_eq!(context.used_gas, SimpleContext::NEW_CELL_GAS * 5); println!("===");
2286
2287 let context = &mut SimpleContext::default();
2288 crate::dict::dict_insert_owned(
2289 &mut dict,
2290 &mut key.as_data_slice(),
2291 32,
2292 &5u32,
2293 SetMode::Add,
2294 context,
2295 )?;
2296 assert_eq!(context.used_gas, SimpleContext::NEW_CELL_GAS * 5); Ok(())
2299 }
2300}