1use std::collections::BTreeMap;
2
3use super::{
4 build_dict_from_sorted_iter, dict_find_bound, dict_find_bound_owned, dict_find_owned, dict_get,
5 dict_get_owned, dict_get_subdict, dict_insert, dict_load_from_root, dict_remove_bound_owned,
6 dict_remove_owned, dict_split_by_prefix, read_label, DictBound, DictOwnedEntry, SetMode,
7 StoreDictKey,
8};
9use crate::cell::*;
10use crate::error::Error;
11use crate::util::{unlikely, IterStatus};
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: &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: StoreDictKey + Ord,
124 V: Store,
125 {
126 assert_eq!(K::BITS, N);
127 let root = ok!(build_dict_from_sorted_iter(sorted, Cell::empty_context()));
128 Ok(Self(root))
129 }
130
131 pub fn try_from_sorted_slice<K, V>(sorted: &[(K, V)]) -> Result<Self, Error>
133 where
134 K: StoreDictKey + Ord,
135 V: Store,
136 {
137 assert_eq!(K::BITS, N);
138 let root = ok!(build_dict_from_sorted_iter(
139 sorted.iter().map(|(k, v)| (k, v)),
140 Cell::empty_context()
141 ));
142 Ok(Self(root))
143 }
144
145 pub const fn is_empty(&self) -> bool {
147 self.0.is_none()
148 }
149
150 #[inline]
152 pub const fn root(&self) -> &Option<Cell> {
153 &self.0
154 }
155
156 #[inline]
158 pub fn into_root(self) -> Option<Cell> {
159 self.0
160 }
161
162 #[inline]
164 pub fn load_from_root_ext(
165 slice: &mut CellSlice<'_>,
166 context: &dyn CellContext,
167 ) -> Result<Self, Error> {
168 match dict_load_from_root(slice, N, context) {
169 Ok(root) => Ok(Self(Some(root))),
170 Err(e) => Err(e),
171 }
172 }
173
174 pub fn get<'a>(&'a self, key: CellSlice<'_>) -> Result<Option<CellSlice<'a>>, Error> {
178 dict_get(self.0.as_ref(), N, key, Cell::empty_context())
179 }
180
181 pub fn get_ext<'a, 'c: 'a>(
183 &'a self,
184 key: CellSlice<'_>,
185 context: &'c dyn CellContext,
186 ) -> Result<Option<CellSlice<'a>>, Error> {
187 dict_get(self.0.as_ref(), N, key, context)
188 }
189
190 pub fn get_next_owned(
193 &self,
194 key: CellSlice<'_>,
195 signed: bool,
196 ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
197 dict_find_owned(
198 self.0.as_ref(),
199 N,
200 key,
201 DictBound::Max,
202 false,
203 signed,
204 Cell::empty_context(),
205 )
206 }
207
208 pub fn get_subdict<'a, 'c: 'a>(
210 &'a self,
211 mut prefix: CellSlice<'a>,
212 context: &'c dyn CellContext,
213 ) -> Result<Option<Cell>, Error> {
214 dict_get_subdict(self.0.as_ref(), N, &mut prefix, context)
215 }
216
217 pub fn get_prev_owned(
220 &self,
221 key: CellSlice<'_>,
222 signed: bool,
223 ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
224 dict_find_owned(
225 self.0.as_ref(),
226 N,
227 key,
228 DictBound::Min,
229 false,
230 signed,
231 Cell::empty_context(),
232 )
233 }
234
235 pub fn get_or_next_owned(
238 &self,
239 key: CellSlice<'_>,
240 signed: bool,
241 ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
242 dict_find_owned(
243 self.0.as_ref(),
244 N,
245 key,
246 DictBound::Max,
247 true,
248 signed,
249 Cell::empty_context(),
250 )
251 }
252
253 pub fn get_or_prev_owned(
256 &self,
257 key: CellSlice<'_>,
258 signed: bool,
259 ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
260 dict_find_owned(
261 self.0.as_ref(),
262 N,
263 key,
264 DictBound::Min,
265 true,
266 signed,
267 Cell::empty_context(),
268 )
269 }
270
271 pub fn get_owned(&self, key: CellSlice<'_>) -> Result<Option<CellSliceParts>, Error> {
275 dict_get_owned(self.0.as_ref(), N, key, Cell::empty_context())
276 }
277
278 pub fn get_owned_ext(
280 &self,
281 key: CellSlice<'_>,
282 context: &dyn CellContext,
283 ) -> Result<Option<CellSliceParts>, Error> {
284 dict_get_owned(self.0.as_ref(), N, key, context)
285 }
286
287 pub fn get_min(&self, signed: bool) -> Result<Option<(CellDataBuilder, CellSlice<'_>)>, Error> {
289 dict_find_bound(
290 self.0.as_ref(),
291 N,
292 DictBound::Min,
293 signed,
294 Cell::empty_context(),
295 )
296 }
297
298 pub fn get_max(&self, signed: bool) -> Result<Option<(CellDataBuilder, CellSlice<'_>)>, Error> {
300 dict_find_bound(
301 self.0.as_ref(),
302 N,
303 DictBound::Max,
304 signed,
305 Cell::empty_context(),
306 )
307 }
308
309 pub fn get_bound(
311 &self,
312 bound: DictBound,
313 signed: bool,
314 ) -> Result<Option<(CellDataBuilder, CellSlice<'_>)>, Error> {
315 dict_find_bound(self.0.as_ref(), N, bound, signed, Cell::empty_context())
316 }
317
318 pub fn get_bound_ext<'a, 'c: 'a>(
320 &'a self,
321 bound: DictBound,
322 signed: bool,
323 context: &'c dyn CellContext,
324 ) -> Result<Option<(CellDataBuilder, CellSlice<'a>)>, Error> {
325 dict_find_bound(self.0.as_ref(), N, bound, signed, context)
326 }
327
328 pub fn get_min_owned(
330 &self,
331 signed: bool,
332 ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
333 dict_find_bound_owned(
334 self.0.as_ref(),
335 N,
336 DictBound::Min,
337 signed,
338 Cell::empty_context(),
339 )
340 }
341
342 pub fn get_max_owned(
344 &self,
345 signed: bool,
346 ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
347 dict_find_bound_owned(
348 self.0.as_ref(),
349 N,
350 DictBound::Max,
351 signed,
352 Cell::empty_context(),
353 )
354 }
355
356 pub fn get_bound_owned(
358 &self,
359 bound: DictBound,
360 signed: bool,
361 ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
362 dict_find_bound_owned(self.0.as_ref(), N, bound, signed, Cell::empty_context())
363 }
364
365 pub fn get_bound_owned_ext(
367 &self,
368 bound: DictBound,
369 signed: bool,
370 context: &dyn CellContext,
371 ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
372 dict_find_bound_owned(self.0.as_ref(), N, bound, signed, context)
373 }
374
375 pub fn contains_key(&self, key: CellSlice<'_>) -> Result<bool, Error> {
377 Ok(ok!(dict_get(self.0.as_ref(), N, key, Cell::empty_context())).is_some())
378 }
379
380 pub fn set_ext(
382 &mut self,
383 mut key: CellSlice<'_>,
384 value: &dyn Store,
385 context: &dyn CellContext,
386 ) -> Result<bool, Error> {
387 dict_insert(&mut self.0, &mut key, N, &value, SetMode::Set, context)
388 }
389
390 pub fn replace_ext(
393 &mut self,
394 mut key: CellSlice<'_>,
395 value: &dyn Store,
396 context: &dyn CellContext,
397 ) -> Result<bool, Error> {
398 dict_insert(&mut self.0, &mut key, N, value, SetMode::Replace, context)
399 }
400
401 pub fn add_ext(
404 &mut self,
405 mut key: CellSlice<'_>,
406 value: &dyn Store,
407 context: &dyn CellContext,
408 ) -> Result<bool, Error> {
409 dict_insert(&mut self.0, &mut key, N, value, SetMode::Add, context)
410 }
411
412 pub fn remove_ext(
415 &mut self,
416 mut key: CellSlice<'_>,
417 context: &dyn CellContext,
418 ) -> Result<Option<CellSliceParts>, Error> {
419 dict_remove_owned(&mut self.0, &mut key, N, false, context)
420 }
421
422 pub fn remove_bound_ext(
425 &mut self,
426 bound: DictBound,
427 signed: bool,
428 context: &dyn CellContext,
429 ) -> Result<Option<DictOwnedEntry>, Error> {
430 dict_remove_bound_owned(&mut self.0, N, bound, signed, context)
431 }
432
433 pub fn split(&self) -> Result<(Self, Self), Error> {
435 self.split_by_prefix_ext(&Default::default(), Cell::empty_context())
436 }
437
438 pub fn split_ext(&self, context: &dyn CellContext) -> Result<(Self, Self), Error> {
440 self.split_by_prefix_ext(&Default::default(), context)
441 }
442
443 pub fn split_by_prefix(&self, key_prefix: &CellSlice<'_>) -> Result<(Self, Self), Error> {
445 self.split_by_prefix_ext(key_prefix, Cell::empty_context())
446 }
447
448 pub fn split_by_prefix_ext(
450 &self,
451 key_prefix: &CellSlice<'_>,
452 context: &dyn CellContext,
453 ) -> Result<(Self, Self), Error> {
454 let (left, right) = ok!(dict_split_by_prefix(
455 self.0.as_ref(),
456 N,
457 key_prefix,
458 context
459 ));
460 Ok((Self(left), Self(right)))
461 }
462
463 pub fn iter(&'_ self) -> RawIter<'_> {
476 RawIter::new(&self.0, N)
477 }
478
479 pub fn iter_union<'a>(&'a self, other: &'a RawDict<N>) -> UnionRawIter<'a> {
493 UnionRawIter::new(&self.0, &other.0, N)
494 }
495
496 pub fn iter_owned(&'_ self) -> RawOwnedIter<'_> {
509 RawOwnedIter::new(&self.0, N)
510 }
511
512 pub fn keys(&'_ self) -> RawKeys<'_> {
525 RawKeys::new(&self.0, N)
526 }
527
528 pub fn values(&'_ self) -> RawValues<'_> {
534 RawValues::new(&self.0, N)
535 }
536
537 pub fn values_owned(&'_ self) -> RawOwnedValues<'_> {
543 RawOwnedValues::new(&self.0, N)
544 }
545
546 pub fn set<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
552 self.set_ext(key, &value, Cell::empty_context())
553 }
554
555 pub fn replace<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
562 self.replace_ext(key, &value, Cell::empty_context())
563 }
564
565 pub fn add<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
572 self.add_ext(key, &value, Cell::empty_context())
573 }
574
575 pub fn remove(&mut self, key: CellSlice<'_>) -> Result<Option<CellSliceParts>, Error> {
582 self.remove_ext(key, Cell::empty_context())
583 }
584
585 pub fn remove_min(&mut self, signed: bool) -> Result<Option<DictOwnedEntry>, Error> {
592 self.remove_bound_ext(DictBound::Min, signed, Cell::empty_context())
593 }
594
595 pub fn remove_max(&mut self, signed: bool) -> Result<Option<DictOwnedEntry>, Error> {
602 self.remove_bound_ext(DictBound::Max, signed, Cell::empty_context())
603 }
604
605 pub fn remove_bound(
612 &mut self,
613 bound: DictBound,
614 signed: bool,
615 ) -> Result<Option<DictOwnedEntry>, Error> {
616 self.remove_bound_ext(bound, signed, Cell::empty_context())
617 }
618}
619
620#[derive(Clone)]
627pub struct RawOwnedIter<'a> {
628 root: &'a Option<Cell>,
629 inner: RawIter<'a>,
630}
631
632impl<'a> RawOwnedIter<'a> {
633 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
635 Self {
636 inner: RawIter::new(root, bit_len),
637 root,
638 }
639 }
640
641 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
644 Self {
645 inner: RawIter::new_ext(root, bit_len, reversed, signed),
646 root,
647 }
648 }
649
650 #[inline]
652 pub fn reversed(mut self) -> Self {
653 self.inner.reversed = true;
654 self
655 }
656
657 #[inline]
659 pub fn signed(mut self) -> Self {
660 self.inner.signed = true;
661 self
662 }
663
664 #[inline]
666 pub fn is_reversed(&self) -> bool {
667 self.inner.reversed
668 }
669
670 #[inline]
672 pub fn is_signed(&self) -> bool {
673 self.inner.signed
674 }
675}
676
677impl Iterator for RawOwnedIter<'_> {
678 type Item = Result<(CellDataBuilder, CellSliceParts), Error>;
679
680 fn next(&mut self) -> Option<Self::Item> {
681 self.inner.next_owned(self.root)
682 }
683}
684
685#[derive(Clone)]
694pub struct RawIter<'a> {
695 segments: Vec<IterSegment<'a>>,
696 status: IterStatus,
697 builder: Box<CellDataBuilder>,
698 reversed: bool,
699 signed: bool,
700}
701
702impl<'a> RawIter<'a> {
703 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
705 Self::new_ext(root, bit_len, false, false)
706 }
707
708 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
711 let mut segments = Vec::new();
712
713 if let Some(root) = root {
715 let Ok(data) = root.as_slice() else {
716 return Self {
717 segments: Vec::new(),
718 status: IterStatus::UnexpectedCell,
719 builder: Box::default(),
720 reversed,
721 signed,
722 };
723 };
724
725 segments.push(IterSegment {
726 data,
727 remaining_bit_len: bit_len,
728 prefix: None,
729 });
730 }
731
732 Self {
733 segments,
734 status: IterStatus::Valid,
735 builder: Default::default(),
736 reversed,
737 signed,
738 }
739 }
740
741 #[inline]
743 pub fn reversed(mut self) -> Self {
744 self.reversed = true;
745 self
746 }
747
748 #[inline]
750 pub fn signed(mut self) -> Self {
751 self.signed = true;
752 self
753 }
754
755 #[inline]
757 pub fn is_reversed(&self) -> bool {
758 self.reversed
759 }
760
761 #[inline]
763 pub fn is_signed(&self) -> bool {
764 self.signed
765 }
766
767 pub fn next_owned(
769 &mut self,
770 root: &Option<Cell>,
771 ) -> Option<Result<(CellDataBuilder, CellSliceParts), Error>> {
772 Some(match self.next()? {
773 Ok((key, slice)) => {
774 let parent = match self.segments.last() {
775 Some(segment) => {
776 let refs_offset = segment.data.offset_refs();
777 debug_assert!(
778 segment.prefix.is_some() && (refs_offset == 1 || refs_offset == 2)
779 );
780
781 let next_bit = (refs_offset != 1)
782 ^ self.reversed
783 ^ (self.signed
784 && self.segments.len() == 1
785 && segment.prefix.unwrap().is_data_empty());
786
787 match segment.data.cell().reference_cloned(next_bit as u8) {
788 Some(cell) => cell,
789 None => return Some(Err(self.finish(Error::CellUnderflow))),
790 }
791 }
792 None => match root {
793 Some(root) => root.clone(),
794 None => {
795 debug_assert!(false, "Non-empty iterator for empty dict");
796 unsafe { std::hint::unreachable_unchecked() };
797 }
798 },
799 };
800 Ok((key, (slice.range(), parent)))
801 }
802 Err(e) => Err(e),
803 })
804 }
805
806 #[inline]
807 pub(crate) fn finish(&mut self, err: Error) -> Error {
808 self.status = IterStatus::Broken;
809 err
810 }
811}
812
813impl<'a> Iterator for RawIter<'a> {
814 type Item = Result<(CellDataBuilder, CellSlice<'a>), Error>;
815
816 fn next(&mut self) -> Option<Self::Item> {
817 if unlikely(!self.status.is_valid()) {
818 return if self.status.is_unexpected_cell() {
819 self.status = IterStatus::Broken;
820 Some(Err(Error::UnexpectedExoticCell))
821 } else {
822 None
823 };
824 }
825
826 fn next_impl<'a>(
827 reverse: bool,
828 signed: bool,
829 segments: &mut Vec<IterSegment<'a>>,
830 builder: &mut CellDataBuilder,
831 ) -> Result<Option<(CellDataBuilder, CellSlice<'a>)>, Error> {
832 #[allow(clippy::never_loop)]
833 loop {
834 let mut to_rewind = 0;
835 let segment = loop {
836 let is_root = segments.len() == 1;
837 let Some(segment) = segments.last_mut() else {
838 return Ok(None);
839 };
840
841 let Some(prefix) = &segment.prefix else {
843 break segment;
844 };
845
846 let refs_offset = segment.data.offset_refs();
847 if refs_offset < 2 {
848 let remaining_bit_len = segment.remaining_bit_len;
850 let next_bit = (refs_offset != 0)
851 ^ reverse
852 ^ (signed && is_root && prefix.is_data_empty());
853
854 let data = ok!(segment.data.cell().get_reference_as_slice(next_bit as u8));
855 segment.data.skip_first(0, 1).ok();
856
857 ok!(builder.rewind_bits(to_rewind));
858 ok!(builder.store_bit(next_bit));
859 segments.push(IterSegment {
860 data,
861 prefix: None,
862 remaining_bit_len,
863 });
864 break unsafe { segments.last_mut().unwrap_unchecked() };
866 } else {
867 to_rewind += prefix.size_bits();
869 segments.pop();
871 to_rewind += !segments.is_empty() as u16;
873 }
874 };
875
876 let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
878
879 return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
881 Some(0) => {
883 let mut key = builder.clone();
885 ok!(key.store_slice_data(prefix));
886
887 let data = segment.data;
888
889 segments.pop();
891 ok!(builder.rewind_bits(!segments.is_empty() as u16));
892
893 Ok(Some((key, data)))
894 }
895 Some(remaining) => {
897 if segment.data.size_refs() < 2 {
898 return Err(Error::CellUnderflow);
899 }
900
901 ok!(builder.store_slice_data(prefix));
903
904 segment.prefix = Some(prefix);
906 segment.remaining_bit_len = remaining - 1;
907
908 continue;
910 }
911 None => Err(Error::CellUnderflow),
912 };
913 }
914 }
915
916 match next_impl(
917 self.reversed,
918 self.signed,
919 &mut self.segments,
920 &mut self.builder,
921 ) {
922 Ok(res) => res.map(Ok),
923 Err(e) => Some(Err(self.finish(e))),
924 }
925 }
926}
927
928#[derive(Clone)]
929struct IterSegment<'a> {
930 data: CellSlice<'a>,
931 remaining_bit_len: u16,
932 prefix: Option<CellSlice<'a>>,
933}
934
935#[derive(Clone)]
944pub struct UnionRawIter<'a> {
945 left: RawIter<'a>,
946 left_peeked: Option<Box<(CellDataBuilder, CellSlice<'a>)>>,
947 left_finished: bool,
948 right: RawIter<'a>,
949 right_peeked: Option<Box<(CellDataBuilder, CellSlice<'a>)>>,
950 right_finished: bool,
951}
952
953impl<'a> UnionRawIter<'a> {
954 pub fn new(left_root: &'a Option<Cell>, right_root: &'a Option<Cell>, bit_len: u16) -> Self {
956 Self::new_ext(left_root, right_root, bit_len, false, false)
957 }
958
959 pub fn new_ext(
962 left_root: &'a Option<Cell>,
963 right_root: &'a Option<Cell>,
964 bit_len: u16,
965 reversed: bool,
966 signed: bool,
967 ) -> Self {
968 Self {
969 left: RawIter::new_ext(left_root, bit_len, reversed, signed),
970 left_peeked: None,
971 left_finished: false,
972 right: RawIter::new_ext(right_root, bit_len, reversed, signed),
973 right_peeked: None,
974 right_finished: false,
975 }
976 }
977
978 #[inline]
980 pub fn reversed(mut self) -> Self {
981 self.left.reversed = true;
982 self.right.reversed = true;
983 self
984 }
985
986 #[inline]
988 pub fn signed(mut self) -> Self {
989 self.left.signed = true;
990 self.right.signed = true;
991 self
992 }
993
994 #[inline]
996 pub fn is_reversed(&self) -> bool {
997 self.left.reversed
998 }
999
1000 #[inline]
1002 pub fn is_signed(&self) -> bool {
1003 self.left.signed
1004 }
1005
1006 #[inline]
1007 pub(crate) fn finish(&mut self, err: Error) -> Error {
1008 self.left.status = IterStatus::Broken;
1009 self.right.status = IterStatus::Broken;
1010 err
1011 }
1012
1013 fn peek<'p>(
1014 iter: &mut RawIter<'a>,
1015 finished: &mut bool,
1016 peeked: &'p mut Option<Box<(CellDataBuilder, CellSlice<'a>)>>,
1017 ) -> Result<Option<&'p (CellDataBuilder, CellSlice<'a>)>, Error> {
1018 if !*finished && peeked.is_none() {
1019 match iter.next() {
1020 Some(Ok(next)) => {
1021 *peeked = Some(Box::new(next));
1022 }
1023 Some(Err(e)) => {
1024 *finished = true;
1025 return Err(e);
1026 }
1027 None => *finished = true,
1028 }
1029 }
1030 Ok(peeked.as_deref())
1031 }
1032}
1033
1034impl<'a> Iterator for UnionRawIter<'a> {
1035 type Item = Result<
1036 (
1037 CellDataBuilder,
1038 Option<CellSlice<'a>>,
1039 Option<CellSlice<'a>>,
1040 ),
1041 Error,
1042 >;
1043
1044 fn next(&mut self) -> Option<Self::Item> {
1045 if unlikely(!self.left.status.is_valid() || !self.right.status.is_valid()) {
1046 if !self.left.status.is_unexpected_cell() && !self.right.status.is_unexpected_cell() {
1047 return None;
1048 }
1049
1050 self.left.status = IterStatus::Broken;
1051 self.right.status = IterStatus::Broken;
1052 return Some(Err(Error::UnexpectedExoticCell));
1053 }
1054
1055 let reversed = self.is_reversed();
1056 let signed = self.is_signed();
1057
1058 let left = match Self::peek(
1059 &mut self.left,
1060 &mut self.left_finished,
1061 &mut self.left_peeked,
1062 ) {
1063 Ok(res) => res,
1064 Err(e) => return Some(Err(self.finish(e))),
1065 };
1066
1067 let right = match Self::peek(
1068 &mut self.right,
1069 &mut self.right_finished,
1070 &mut self.right_peeked,
1071 ) {
1072 Ok(res) => res,
1073 Err(e) => return Some(Err(self.finish(e))),
1074 };
1075
1076 match (left, right) {
1077 (None, None) => None,
1078 (Some((left_key, left_value)), None) => {
1079 let res = Some(Ok((left_key.clone(), Some(*left_value), None)));
1080 self.left_peeked = None;
1081 res
1082 }
1083 (None, Some((right_key, right_value))) => {
1084 let res = Some(Ok((right_key.clone(), None, Some(*right_value))));
1085 self.right_peeked = None;
1086 res
1087 }
1088 (Some((left_key, left_value)), Some((right_key, right_value))) => {
1089 let cmp = {
1090 let left_key = left_key.as_data_slice();
1091 let right_key = right_key.as_data_slice();
1092
1093 let mut reversed = reversed;
1094 if signed {
1095 let left_is_neg = left_key.get_bit(0).ok().unwrap_or_default();
1096 let right_is_neg = right_key.get_bit(0).ok().unwrap_or_default();
1097 reversed ^= left_is_neg != right_is_neg;
1098 }
1099
1100 let cmp = match left_key.lex_cmp(&right_key) {
1101 Ok(cmp) => cmp,
1102 Err(e) => return Some(Err(self.finish(e))),
1103 };
1104
1105 if reversed {
1106 cmp.reverse()
1107 } else {
1108 cmp
1109 }
1110 };
1111
1112 match cmp {
1113 std::cmp::Ordering::Less => {
1114 let res = Some(Ok((left_key.clone(), Some(*left_value), None)));
1115 self.left_peeked = None;
1116 res
1117 }
1118 std::cmp::Ordering::Greater => {
1119 let res = Some(Ok((right_key.clone(), None, Some(*right_value))));
1120 self.right_peeked = None;
1121 res
1122 }
1123 std::cmp::Ordering::Equal => {
1124 let res = Some(Ok((
1125 left_key.clone(),
1126 Some(*left_value),
1127 Some(*right_value),
1128 )));
1129 self.left_peeked = None;
1130 self.right_peeked = None;
1131 res
1132 }
1133 }
1134 }
1135 }
1136 }
1137}
1138
1139#[derive(Clone)]
1148pub struct RawKeys<'a> {
1149 inner: RawIter<'a>,
1150}
1151
1152impl<'a> RawKeys<'a> {
1153 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1155 Self {
1156 inner: RawIter::new(root, bit_len),
1157 }
1158 }
1159
1160 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1163 Self {
1164 inner: RawIter::new_ext(root, bit_len, reversed, signed),
1165 }
1166 }
1167
1168 #[inline]
1170 pub fn reversed(mut self) -> Self {
1171 self.inner.reversed = true;
1172 self
1173 }
1174
1175 #[inline]
1177 pub fn signed(mut self) -> Self {
1178 self.inner.signed = true;
1179 self
1180 }
1181
1182 #[inline]
1184 pub fn is_reversed(&self) -> bool {
1185 self.inner.reversed
1186 }
1187
1188 #[inline]
1190 pub fn is_signed(&self) -> bool {
1191 self.inner.signed
1192 }
1193}
1194
1195impl Iterator for RawKeys<'_> {
1196 type Item = Result<CellDataBuilder, Error>;
1197
1198 fn next(&mut self) -> Option<Self::Item> {
1199 match self.inner.next()? {
1200 Ok((key, _)) => Some(Ok(key)),
1201 Err(e) => Some(Err(e)),
1202 }
1203 }
1204}
1205
1206#[derive(Clone)]
1213pub struct RawOwnedValues<'a> {
1214 root: &'a Option<Cell>,
1215 inner: RawValues<'a>,
1216}
1217
1218impl<'a> RawOwnedValues<'a> {
1219 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1221 Self {
1222 inner: RawValues::new(root, bit_len),
1223 root,
1224 }
1225 }
1226
1227 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1230 Self {
1231 inner: RawValues::new_ext(root, bit_len, reversed, signed),
1232 root,
1233 }
1234 }
1235
1236 #[inline]
1238 pub fn reversed(mut self) -> Self {
1239 self.inner.reversed = true;
1240 self
1241 }
1242
1243 #[inline]
1245 pub fn signed(mut self) -> Self {
1246 self.inner.signed = true;
1247 self
1248 }
1249
1250 #[inline]
1252 pub fn is_reversed(&self) -> bool {
1253 self.inner.reversed
1254 }
1255
1256 #[inline]
1258 pub fn is_signed(&self) -> bool {
1259 self.inner.signed
1260 }
1261}
1262
1263impl Iterator for RawOwnedValues<'_> {
1264 type Item = Result<CellSliceParts, Error>;
1265
1266 fn next(&mut self) -> Option<Self::Item> {
1267 Some(match self.inner.next()? {
1268 Ok(slice) => {
1269 let parent = match self.inner.segments.last() {
1270 Some(segment) => {
1271 let refs_offset = segment.data.offset_refs();
1272 debug_assert!(refs_offset > 0);
1273 match segment.data.cell().reference_cloned(refs_offset - 1) {
1274 Some(cell) => cell,
1275 None => return Some(Err(self.inner.finish(Error::CellUnderflow))),
1276 }
1277 }
1278 None => match self.root {
1279 Some(root) => root.clone(),
1280 None => {
1281 debug_assert!(false, "Non-empty iterator for empty dict");
1282 unsafe { std::hint::unreachable_unchecked() };
1283 }
1284 },
1285 };
1286 Ok((slice.range(), parent))
1287 }
1288 Err(e) => Err(e),
1289 })
1290 }
1291}
1292
1293#[derive(Clone)]
1302pub struct RawValues<'a> {
1303 segments: Vec<ValuesSegment<'a>>,
1304 status: IterStatus,
1305 reversed: bool,
1306 signed: bool,
1307}
1308
1309impl<'a> RawValues<'a> {
1310 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1312 Self::new_ext(root, bit_len, false, false)
1313 }
1314
1315 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1318 let mut segments = Vec::new();
1319 if let Some(root) = root {
1320 let Ok(data) = root.as_slice() else {
1321 return Self {
1322 segments: Vec::new(),
1323 status: IterStatus::UnexpectedCell,
1324 reversed,
1325 signed,
1326 };
1327 };
1328
1329 segments.push(ValuesSegment {
1330 data,
1331 remaining_bit_len: bit_len,
1332 });
1333 }
1334 Self {
1335 segments,
1336 status: IterStatus::Valid,
1337 reversed,
1338 signed,
1339 }
1340 }
1341
1342 #[inline]
1344 pub fn reversed(mut self) -> Self {
1345 self.reversed = true;
1346 self
1347 }
1348
1349 #[inline]
1351 pub fn signed(mut self) -> Self {
1352 self.signed = true;
1353 self
1354 }
1355
1356 #[inline]
1358 pub fn is_reversed(&self) -> bool {
1359 self.reversed
1360 }
1361
1362 #[inline]
1364 pub fn is_signed(&self) -> bool {
1365 self.signed
1366 }
1367
1368 #[inline]
1369 pub(crate) fn finish(&mut self, err: Error) -> Error {
1370 self.status = IterStatus::Broken;
1371 err
1372 }
1373}
1374
1375impl<'a> Iterator for RawValues<'a> {
1376 type Item = Result<CellSlice<'a>, Error>;
1377
1378 fn next(&mut self) -> Option<Self::Item> {
1379 if unlikely(!self.status.is_valid()) {
1380 return if self.status.is_unexpected_cell() {
1381 self.status = IterStatus::Broken;
1382 Some(Err(Error::UnexpectedExoticCell))
1383 } else {
1384 None
1385 };
1386 }
1387
1388 fn next_impl<'a>(
1389 reverse: bool,
1390 signed: bool,
1391 segments: &mut Vec<ValuesSegment<'a>>,
1392 ) -> Result<Option<CellSlice<'a>>, Error> {
1393 #[allow(clippy::never_loop)]
1394 loop {
1395 let segment = loop {
1397 let is_root = segments.len() == 1;
1398 let Some(segment) = segments.last_mut() else {
1399 return Ok(None);
1400 };
1401
1402 if segment.data.offset_bits() == 0 {
1403 break segment;
1404 }
1405
1406 let refs_offset = segment.data.offset_refs();
1407 if refs_offset < 2 {
1408 let remaining_bit_len = segment.remaining_bit_len;
1410 let next_bit = (refs_offset != 0)
1411 ^ reverse
1412 ^ (signed && is_root && segment.data.is_data_empty());
1413 let data = ok!(segment.data.cell().get_reference_as_slice(next_bit as u8));
1414 segment.data.skip_first(0, 1).ok();
1415
1416 segments.push(ValuesSegment {
1417 data,
1418 remaining_bit_len,
1419 });
1420 break unsafe { segments.last_mut().unwrap_unchecked() };
1422 } else {
1423 segments.pop();
1424 }
1425 };
1426
1427 let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
1429
1430 return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
1432 Some(0) => {
1434 let data = segment.data;
1435 segments.pop();
1437 Ok(Some(data))
1438 }
1439 Some(remaining) => {
1441 if segment.data.size_refs() < 2 {
1442 return Err(Error::CellUnderflow);
1443 }
1444 segment.remaining_bit_len = remaining - 1;
1445 continue;
1447 }
1448 None => Err(Error::CellUnderflow),
1449 };
1450 }
1451 }
1452
1453 match next_impl(self.reversed, self.signed, &mut self.segments) {
1454 Ok(res) => res.map(Ok),
1455 Err(e) => Some(Err(self.finish(e))),
1456 }
1457 }
1458}
1459
1460#[derive(Copy, Clone)]
1461struct ValuesSegment<'a> {
1462 data: CellSlice<'a>,
1463 remaining_bit_len: u16,
1464}
1465
1466#[cfg(test)]
1467mod tests {
1468
1469 use super::*;
1470 use crate::prelude::*;
1471
1472 fn build_cell<F: FnOnce(&mut CellBuilder) -> Result<(), Error>>(f: F) -> Cell {
1473 let mut builder = CellBuilder::new();
1474 f(&mut builder).unwrap();
1475 builder.build().unwrap()
1476 }
1477
1478 #[test]
1479 fn dict_set() -> anyhow::Result<()> {
1480 let mut dict = RawDict::<32>::new();
1481
1482 let key = CellBuilder::build_from(123u32)?;
1483
1484 dict.set(key.as_slice()?, ())?;
1485 {
1486 let mut values = dict.values();
1487 let value = values.next().unwrap().unwrap();
1488 assert!(value.is_data_empty() && value.is_refs_empty());
1489 assert!(values.next().is_none());
1490 }
1491
1492 dict.set(key.as_slice()?, 0xffffu16)?;
1493 {
1494 let mut values = dict.values();
1495 let mut value = values.next().unwrap()?;
1496 assert_eq!(value.load_u16(), Ok(0xffff));
1497 assert!(value.is_data_empty() && value.is_refs_empty());
1498 assert!(values.next().is_none());
1499 }
1500
1501 Ok(())
1502 }
1503
1504 #[test]
1505 #[cfg_attr(miri, ignore)] fn dict_set_complex() -> anyhow::Result<()> {
1507 let mut dict = RawDict::<32>::new();
1508 for i in 0..520 {
1509 let key = build_cell(|b| b.store_u32(i));
1510 dict.set(key.as_slice()?, true)?;
1511
1512 let mut total = 0;
1513 for (i, item) in dict.iter().enumerate() {
1514 total += 1;
1515 let (key, value) = item?;
1516 assert_eq!(key.size_bits(), 32);
1517 assert_eq!(value.size_bits(), 1);
1518 let key = key.as_data_slice().load_u32()?;
1519 assert_eq!(key, i as u32);
1520 }
1521 assert_eq!(total, i + 1);
1522 }
1523
1524 Ok(())
1525 }
1526
1527 #[test]
1528 fn dict_replace() -> anyhow::Result<()> {
1529 let mut dict = RawDict::<32>::new();
1530
1531 dict.replace(build_cell(|b| b.store_u32(123)).as_slice()?, false)
1533 .unwrap();
1534 assert!(!dict
1535 .contains_key(build_cell(|b| b.store_u32(123)).as_slice()?)
1536 .unwrap());
1537
1538 dict.set(build_cell(|b| b.store_u32(123)).as_slice()?, false)
1540 .unwrap();
1541 dict.replace(build_cell(|b| b.store_u32(123)).as_slice()?, true)
1542 .unwrap();
1543
1544 let mut value = dict
1545 .get(build_cell(|b| b.store_u32(123)).as_slice()?)
1546 .unwrap()
1547 .unwrap();
1548 assert_eq!(value.size_bits(), 1);
1549 assert_eq!(value.load_bit(), Ok(true));
1550
1551 Ok(())
1552 }
1553
1554 #[test]
1555 fn dict_add() -> anyhow::Result<()> {
1556 let mut dict = RawDict::<32>::new();
1557
1558 let key = build_cell(|b| b.store_u32(123));
1559
1560 dict.add(key.as_slice()?, false)?;
1562 let mut value = dict.get(key.as_slice()?)?.unwrap();
1563 assert_eq!(value.size_bits(), 1);
1564 assert_eq!(value.load_bit(), Ok(false));
1565
1566 dict.add(key.as_slice()?, true)?;
1568 let mut value = dict.get(key.as_slice()?)?.unwrap();
1569 assert_eq!(value.size_bits(), 1);
1570 assert_eq!(value.load_bit(), Ok(false));
1571
1572 Ok(())
1573 }
1574
1575 #[test]
1576 fn dict_split() -> anyhow::Result<()> {
1577 let mut dict = RawDict::<4>::new();
1578 for i in 0..16 {
1579 let key = build_cell(|b| b.store_small_uint(i, 4));
1580 dict.add(key.as_slice()?, i)?;
1581 }
1582
1583 let (left, right) = dict.split()?;
1584 assert!(!left.is_empty());
1585 assert!(!right.is_empty());
1586 assert_eq!(left.iter().count(), 8);
1587 assert_eq!(right.iter().count(), 8);
1588
1589 let (ll, lr) = left.split()?;
1590 assert!(!ll.is_empty());
1591 assert!(lr.is_empty());
1592 assert_eq!(ll.iter().count(), 8);
1593
1594 let (rl, rr) = right.split()?;
1595 assert!(rl.is_empty());
1596 assert!(!rr.is_empty());
1597 assert_eq!(rr.iter().count(), 8);
1598
1599 let (left, right) = RawDict::<4>::new().split()?;
1600 assert!(left.is_empty());
1601 assert!(right.is_empty());
1602
1603 Ok(())
1604 }
1605
1606 #[test]
1607 fn dict_split_by_prefix() -> anyhow::Result<()> {
1608 fn check_range(dict: &RawDict<4>, mut range: std::ops::Range<u8>) {
1609 for key in dict.keys() {
1610 let key = key.unwrap();
1611 let key = key.as_data_slice().load_small_uint(4).unwrap();
1612 assert_eq!(key, range.next().unwrap());
1613 }
1614 assert_eq!(range.next(), None);
1615 }
1616
1617 let mut dict = RawDict::<4>::new();
1618 for i in 0..16 {
1619 let key = build_cell(|b| b.store_small_uint(i, 4));
1620 dict.add(key.as_slice()?, i)?;
1621 }
1622
1623 let (left, right) = dict.split()?;
1624 check_range(&left, 0..8);
1625 check_range(&right, 8..16);
1626
1627 {
1628 let mut prefix = CellBuilder::new();
1629 prefix.store_bit_one()?;
1630 let res = dict.split_by_prefix(&prefix.as_data_slice());
1631 assert!(matches!(res, Err(Error::CellUnderflow)));
1632 }
1633
1634 let (ll, lr) = {
1635 let mut prefix = CellBuilder::new();
1636 prefix.store_bit_zero()?;
1637 left.split_by_prefix(&prefix.as_data_slice())?
1638 };
1639 check_range(&ll, 0..4);
1640 check_range(&lr, 4..8);
1641
1642 let (rl, rr) = {
1643 let mut prefix = CellBuilder::new();
1644 prefix.store_bit_one()?;
1645 right.split_by_prefix(&prefix.as_data_slice())?
1646 };
1647 check_range(&rl, 8..12);
1648 check_range(&rr, 12..16);
1649
1650 Ok(())
1651 }
1652
1653 #[test]
1654 fn dict_get_subdict() -> anyhow::Result<()> {
1655 let mut dict = RawDict::<32>::new();
1656 for i in 0u32..4 {
1657 let key = CellBuilder::build_from(i)?;
1659 println!("ADDING KEY {}", key.display_data());
1660 dict.add(key.as_slice()?, i)?;
1661 }
1662
1663 let cell = dict.root().as_ref().unwrap();
1664 let boc = Boc::encode_base64(cell);
1665
1666 println!("{}", boc);
1667
1668 let key = CellBuilder::build_from(1u16 << 8)?;
1669
1670 println!("KEY: {}", key.display_data());
1671
1672 let context = &mut SimpleContext::default();
1673
1674 let value: Cell = dict.get_subdict(key.as_slice()?, context)?.unwrap();
1675
1676 print!("{}", value.display_tree());
1677
1678 Ok(())
1679 }
1680
1681 #[test]
1682 fn dict_get() -> anyhow::Result<()> {
1683 let boc =
1684 Boc::decode_base64("te6ccgECOwEAASoAAQHAAQIBIBACAgEgAwMCASAEBAIBIAUFAgEgBgYCASAHBwIBIAgIAgEgCQkCASAoCgIBIAsZAgEgDBsCASArDQIBIA4fAgEgLQ8CASAuIQIBIBERAgEgEhICASATEwIBIBQUAgEgFRUCASAWFgIBIBcXAgEgKBgCASAaGQIBIBsbAgEgHRsCASAcHAIBIB8fAgEgKx4CASAiHwIBICAgAgEgISECASAlJQIBIC0jAgEgLiQCASAvJQIBIDMmAgFiNicCAUg4OAIBICkpAgEgKioCASArKwIBICwsAgEgLS0CASAuLgIBIC8vAgEgMzACAWI2MQIBIDcyAAnWAAAmbwIBIDQ0AgEgNTUCASA2NgIBIDc3AgEgODgCASA5OQIBIDo6AAnQAAAmbw==")?;
1685
1686 let dict = boc.parse::<RawDict<32>>()?;
1689
1690 let key = CellBuilder::build_from(u32::from_be_bytes(123u32.to_le_bytes()))?;
1691 let value = dict.get(key.as_slice()?)?.unwrap();
1692
1693 {
1694 let (range, cell) = dict.get_owned(key.as_slice()?)?.unwrap();
1695 assert_eq!(range.apply(&cell).unwrap(), value);
1696 }
1697
1698 let value = {
1699 let mut builder = CellBuilder::new();
1700 builder.store_slice(value)?;
1701 builder.build()?
1702 };
1703 println!("{}", value.display_tree());
1704
1705 Ok(())
1706 }
1707
1708 #[test]
1709 fn dict_iter() -> anyhow::Result<()> {
1710 let boc = Boc::decode_base64("te6ccgEBFAEAeAABAcABAgPOQAUCAgHUBAMACQAAAI3gAAkAAACjoAIBIA0GAgEgCgcCASAJCAAJAAAAciAACQAAAIfgAgEgDAsACQAAAFZgAAkAAABsIAIBIBEOAgEgEA8ACQAAADqgAAkAAABQYAIBIBMSAAkAAAAe4AAJAAAAv2A=")?;
1711 let dict = boc.parse::<RawDict<32>>()?;
1712
1713 let size = dict.values().count();
1714 assert_eq!(size, 10);
1715
1716 let mut rev_iter_items = dict.iter().reversed().collect::<Vec<_>>();
1717 rev_iter_items.reverse();
1718 let mut rev_iter_items = rev_iter_items.into_iter();
1719
1720 for (i, entry) in dict.iter().enumerate() {
1721 let (key, value) = entry?;
1722
1723 let (rev_key, rev_value) = rev_iter_items.next().unwrap().unwrap();
1724 assert_eq!(key, rev_key);
1725 assert_eq!(value.lex_cmp(&rev_value), Ok(std::cmp::Ordering::Equal));
1726
1727 let key = key.as_data_slice().load_u32()?;
1728 assert_eq!(key, i as u32);
1729 }
1730 assert!(rev_iter_items.next().is_none());
1731
1732 let mut last = None;
1733 for (i, entry) in dict.iter_owned().enumerate() {
1734 let (key, (range, cell)) = entry?;
1735
1736 {
1737 let mut slice = range.apply(&cell).unwrap();
1738 assert_eq!(slice.size_bits(), 32);
1739 u32::load_from(&mut slice).unwrap();
1740 }
1741
1742 let key = key.as_data_slice().load_u32()?;
1743 assert_eq!(key, i as u32);
1744 last = Some(key);
1745 }
1746 assert_eq!(last, Some(9));
1747
1748 let mut values_ref = dict.values();
1749 let mut values_owned = dict.values_owned();
1750 for (value_ref, value_owned) in (&mut values_ref).zip(&mut values_owned) {
1751 let value_ref = value_ref.unwrap();
1752 let (range, cell) = value_owned.unwrap();
1753 let value_owned = range.apply(&cell).unwrap();
1754 assert_eq!(
1755 value_ref.lex_cmp(&value_owned),
1756 Ok(std::cmp::Ordering::Equal)
1757 );
1758 }
1759 assert!(values_ref.next().is_none());
1760 assert!(values_owned.next().is_none());
1761
1762 Ok(())
1763 }
1764
1765 #[test]
1766 fn dict_iter_union() -> anyhow::Result<()> {
1767 let mut left = RawDict::<32>::new();
1768 let mut right = RawDict::<32>::new();
1769
1770 for i in -4i32..4 {
1772 let key = build_cell(|b| b.store_u32(i as _));
1773 left.set(key.as_slice()?, i)?;
1774 }
1775 for i in -2i32..6 {
1776 let key = build_cell(|b| b.store_u32(i as _));
1777 right.set(key.as_slice()?, i + 100)?;
1778 }
1779
1780 fn compare_iter_values(iter: UnionRawIter<'_>, values: &[(i32, Option<i32>, Option<i32>)]) {
1781 let mut values = values.iter();
1782
1783 for entry in iter {
1784 let (key, left_value, right_value) = entry.unwrap();
1785 let key = key.as_data_slice().load_u32().unwrap() as i32;
1786 let left_value = left_value.map(|v| v.get_u32(0).unwrap() as i32);
1787 let right_value = right_value.map(|v| v.get_u32(0).unwrap() as i32);
1788
1789 assert_eq!(values.next(), Some(&(key, left_value, right_value)));
1790 }
1791 assert_eq!(values.next(), None);
1792 }
1793
1794 compare_iter_values(left.iter_union(&right), &[
1796 (0, Some(0), Some(100)),
1797 (1, Some(1), Some(101)),
1798 (2, Some(2), Some(102)),
1799 (3, Some(3), Some(103)),
1800 (4, None, Some(104)),
1801 (5, None, Some(105)),
1802 (-4, Some(-4), None),
1803 (-3, Some(-3), None),
1804 (-2, Some(-2), Some(98)),
1805 (-1, Some(-1), Some(99)),
1806 ]);
1807
1808 compare_iter_values(left.iter_union(&right).reversed(), &[
1810 (-1, Some(-1), Some(99)),
1811 (-2, Some(-2), Some(98)),
1812 (-3, Some(-3), None),
1813 (-4, Some(-4), None),
1814 (5, None, Some(105)),
1815 (4, None, Some(104)),
1816 (3, Some(3), Some(103)),
1817 (2, Some(2), Some(102)),
1818 (1, Some(1), Some(101)),
1819 (0, Some(0), Some(100)),
1820 ]);
1821
1822 compare_iter_values(left.iter_union(&right).signed(), &[
1824 (-4, Some(-4), None),
1825 (-3, Some(-3), None),
1826 (-2, Some(-2), Some(98)),
1827 (-1, Some(-1), Some(99)),
1828 (0, Some(0), Some(100)),
1829 (1, Some(1), Some(101)),
1830 (2, Some(2), Some(102)),
1831 (3, Some(3), Some(103)),
1832 (4, None, Some(104)),
1833 (5, None, Some(105)),
1834 ]);
1835
1836 compare_iter_values(left.iter_union(&right).signed().reversed(), &[
1838 (5, None, Some(105)),
1839 (4, None, Some(104)),
1840 (3, Some(3), Some(103)),
1841 (2, Some(2), Some(102)),
1842 (1, Some(1), Some(101)),
1843 (0, Some(0), Some(100)),
1844 (-1, Some(-1), Some(99)),
1845 (-2, Some(-2), Some(98)),
1846 (-3, Some(-3), None),
1847 (-4, Some(-4), None),
1848 ]);
1849
1850 Ok(())
1851 }
1852
1853 #[derive(Debug, Default)]
1854 struct SimpleContext {
1855 used_gas: std::cell::Cell<u64>,
1856 loaded_cells: std::cell::RefCell<ahash::HashSet<HashBytes>>,
1857 empty_context: <Cell as CellFamily>::EmptyCellContext,
1858 }
1859
1860 impl SimpleContext {
1861 const BUILD_CELL_GAS: u64 = 500;
1862 const NEW_CELL_GAS: u64 = 100;
1863 const OLD_CELL_GAS: u64 = 25;
1864
1865 fn consume_gas(&self, cell: &DynCell, mode: LoadMode) {
1866 if mode.use_gas() {
1867 let consumed_gas = if self.loaded_cells.borrow_mut().insert(*cell.repr_hash()) {
1868 Self::NEW_CELL_GAS
1869 } else {
1870 Self::OLD_CELL_GAS
1871 };
1872
1873 self.used_gas.set(self.used_gas.get() + consumed_gas);
1874 }
1875 }
1876 }
1877
1878 impl CellContext for SimpleContext {
1879 #[inline]
1880 fn finalize_cell(&self, cell: CellParts<'_>) -> Result<Cell, Error> {
1881 self.used_gas
1882 .set(self.used_gas.get() + Self::BUILD_CELL_GAS);
1883 self.empty_context.finalize_cell(cell)
1884 }
1885
1886 #[inline]
1887 fn load_cell(&self, cell: Cell, mode: LoadMode) -> Result<Cell, Error> {
1888 self.consume_gas(cell.as_ref(), mode);
1889 Ok(cell)
1890 }
1891
1892 #[inline]
1893 fn load_dyn_cell<'s: 'a, 'a>(
1894 &self,
1895 cell: &'a DynCell,
1896 mode: LoadMode,
1897 ) -> Result<&'a DynCell, Error> {
1898 self.consume_gas(cell, mode);
1899 Ok(cell)
1900 }
1901 }
1902
1903 #[test]
1904 fn dict_get_gas_usage() -> anyhow::Result<()> {
1905 let mut dict = RawDict::<32>::new();
1907 for i in 0..10 {
1908 let mut key = CellBuilder::new();
1909 key.store_u32(i)?;
1910 dict.set(key.as_data_slice(), i)?;
1911 }
1912
1913 let context = &mut SimpleContext::default();
1915
1916 let mut key = CellBuilder::new();
1917 key.store_u32(5)?;
1918
1919 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1920 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5);
1921
1922 context.used_gas.set(0);
1923 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1924 assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 5);
1925
1926 context.used_gas.set(0);
1928 let mut key = CellBuilder::new();
1929 key.store_u32(9)?;
1930
1931 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1932 assert_eq!(
1933 context.used_gas.get(),
1934 SimpleContext::OLD_CELL_GAS + SimpleContext::NEW_CELL_GAS * 2
1935 );
1936
1937 context.used_gas.set(0);
1938 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1939 assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 3);
1940
1941 Ok(())
1942 }
1943
1944 #[test]
1945 fn dict_get_owned_gas_usage() -> anyhow::Result<()> {
1946 let mut dict = RawDict::<32>::new();
1948 for i in 0..10 {
1949 let mut key = CellBuilder::new();
1950 key.store_u32(i)?;
1951 dict.set(key.as_data_slice(), i)?;
1952 }
1953
1954 let context = &mut SimpleContext::default();
1956
1957 let mut key = CellBuilder::new();
1958 key.store_u32(5)?;
1959
1960 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1961 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5);
1962
1963 context.used_gas.set(0);
1964 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1965 assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 5);
1966
1967 context.used_gas.set(0);
1969 let mut key = CellBuilder::new();
1970 key.store_u32(9)?;
1971
1972 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1973 assert_eq!(
1974 context.used_gas.get(),
1975 SimpleContext::OLD_CELL_GAS + SimpleContext::NEW_CELL_GAS * 2
1976 );
1977
1978 context.used_gas.set(0);
1979 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1980 assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 3);
1981
1982 Ok(())
1983 }
1984
1985 #[test]
1986 fn dict_remove_gas_usage() -> anyhow::Result<()> {
1987 let mut dict = RawDict::<32>::new();
1988 for i in 0..10 {
1989 let mut key = CellBuilder::new();
1990 key.store_u32(i)?;
1991 dict.set(key.as_data_slice(), i)?;
1992 }
1993
1994 let mut key = CellBuilder::new();
1996 key.store_u32(10)?;
1997
1998 let context = &mut SimpleContext::default();
1999 assert!(dict.remove_ext(key.as_data_slice(), context)?.is_none());
2000
2001 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 2);
2002
2003 let target_gas = [
2005 SimpleContext::NEW_CELL_GAS * 6 + SimpleContext::BUILD_CELL_GAS * 4,
2006 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2007 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2008 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2009 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2010 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2011 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2012 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS,
2013 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS,
2014 SimpleContext::NEW_CELL_GAS,
2015 ];
2016
2017 for i in 0..10 {
2018 println!("===");
2019
2020 let context = &mut SimpleContext::default();
2021
2022 let mut key = CellBuilder::new();
2023 key.store_u32(i)?;
2024
2025 let removed = dict.remove_ext(key.as_data_slice(), context)?;
2026 assert!(removed.is_some());
2027
2028 assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2029 }
2030
2031 Ok(())
2032 }
2033
2034 #[test]
2035 fn dict_remove_bound() -> anyhow::Result<()> {
2036 let make_dict = |range: std::ops::Range<i32>| {
2037 let mut dict = RawDict::<32>::new();
2038 for i in range {
2039 let mut key = CellBuilder::new();
2040 key.store_u32(i as u32)?;
2041 dict.set(key.as_data_slice(), i)?;
2042 }
2043 Ok::<_, anyhow::Error>(dict)
2044 };
2045
2046 let check_range =
2047 |range: std::ops::Range<i32>, bound: DictBound, signed: bool, target_gas: &[u64]| {
2048 let mut dict = make_dict(range.clone())?;
2049 for &target_gas in target_gas {
2050 println!("=== {range:?} bound={bound:?} signed={signed} [non-owned]");
2051 let context = &mut SimpleContext::default();
2052 let (key, _) = dict.get_bound_ext(bound, signed, context)?.unwrap();
2053 let removed = dict.clone().remove_ext(key.as_data_slice(), context)?;
2054 assert!(removed.is_some());
2055 assert_eq!(context.used_gas.get(), target_gas);
2056
2057 println!("=== {range:?} bound={bound:?} signed={signed} [owned]");
2058 let context = &mut SimpleContext::default();
2059 let (key, _) = dict.get_bound_owned_ext(bound, signed, context)?.unwrap();
2060 let removed = dict.remove_ext(key.as_data_slice(), context)?;
2061 assert!(removed.is_some());
2062 assert_eq!(context.used_gas.get(), target_gas);
2063 }
2064
2065 Ok::<_, anyhow::Error>(())
2066 };
2067
2068 let target_gas = [
2070 SimpleContext::NEW_CELL_GAS * 6
2071 + SimpleContext::OLD_CELL_GAS * 5
2072 + SimpleContext::BUILD_CELL_GAS * 4,
2073 SimpleContext::NEW_CELL_GAS * 5
2074 + SimpleContext::OLD_CELL_GAS * 4
2075 + SimpleContext::BUILD_CELL_GAS * 3,
2076 SimpleContext::NEW_CELL_GAS * 5
2077 + SimpleContext::OLD_CELL_GAS * 4
2078 + SimpleContext::BUILD_CELL_GAS * 3,
2079 SimpleContext::NEW_CELL_GAS * 4
2080 + SimpleContext::OLD_CELL_GAS * 3
2081 + SimpleContext::BUILD_CELL_GAS * 2,
2082 SimpleContext::NEW_CELL_GAS * 5
2083 + SimpleContext::OLD_CELL_GAS * 4
2084 + SimpleContext::BUILD_CELL_GAS * 3,
2085 SimpleContext::NEW_CELL_GAS * 4
2086 + SimpleContext::OLD_CELL_GAS * 3
2087 + SimpleContext::BUILD_CELL_GAS * 2,
2088 SimpleContext::NEW_CELL_GAS * 4
2089 + SimpleContext::OLD_CELL_GAS * 3
2090 + SimpleContext::BUILD_CELL_GAS * 2,
2091 SimpleContext::NEW_CELL_GAS * 3
2092 + SimpleContext::OLD_CELL_GAS * 2
2093 + SimpleContext::BUILD_CELL_GAS,
2094 SimpleContext::NEW_CELL_GAS * 3
2095 + SimpleContext::OLD_CELL_GAS * 2
2096 + SimpleContext::BUILD_CELL_GAS,
2097 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2098 ];
2099 check_range(0..10, DictBound::Min, false, &target_gas)?;
2100
2101 let target_gas = [
2103 SimpleContext::NEW_CELL_GAS * 4
2104 + SimpleContext::OLD_CELL_GAS * 3
2105 + SimpleContext::BUILD_CELL_GAS * 2,
2106 SimpleContext::NEW_CELL_GAS * 3
2107 + SimpleContext::OLD_CELL_GAS * 2
2108 + SimpleContext::BUILD_CELL_GAS,
2109 SimpleContext::NEW_CELL_GAS * 5
2110 + SimpleContext::OLD_CELL_GAS * 4
2111 + SimpleContext::BUILD_CELL_GAS * 3,
2112 SimpleContext::NEW_CELL_GAS * 4
2113 + SimpleContext::OLD_CELL_GAS * 3
2114 + SimpleContext::BUILD_CELL_GAS * 2,
2115 SimpleContext::NEW_CELL_GAS * 4
2116 + SimpleContext::OLD_CELL_GAS * 3
2117 + SimpleContext::BUILD_CELL_GAS * 2,
2118 SimpleContext::NEW_CELL_GAS * 3
2119 + SimpleContext::OLD_CELL_GAS * 2
2120 + SimpleContext::BUILD_CELL_GAS,
2121 SimpleContext::NEW_CELL_GAS * 4
2122 + SimpleContext::OLD_CELL_GAS * 3
2123 + SimpleContext::BUILD_CELL_GAS * 2,
2124 SimpleContext::NEW_CELL_GAS * 3
2125 + SimpleContext::OLD_CELL_GAS * 2
2126 + SimpleContext::BUILD_CELL_GAS,
2127 SimpleContext::NEW_CELL_GAS * 3
2128 + SimpleContext::OLD_CELL_GAS * 2
2129 + SimpleContext::BUILD_CELL_GAS,
2130 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2131 ];
2132 check_range(0..10, DictBound::Max, false, &target_gas)?;
2133
2134 let target_gas = [
2136 SimpleContext::NEW_CELL_GAS * 4
2137 + SimpleContext::OLD_CELL_GAS * 3
2138 + SimpleContext::BUILD_CELL_GAS * 2,
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 * 5
2152 + SimpleContext::OLD_CELL_GAS * 4
2153 + SimpleContext::BUILD_CELL_GAS * 3,
2154 SimpleContext::NEW_CELL_GAS * 4
2155 + SimpleContext::OLD_CELL_GAS * 3
2156 + SimpleContext::BUILD_CELL_GAS * 2,
2157 SimpleContext::NEW_CELL_GAS * 4
2158 + SimpleContext::OLD_CELL_GAS * 3
2159 + SimpleContext::BUILD_CELL_GAS * 2,
2160 SimpleContext::NEW_CELL_GAS * 3
2161 + SimpleContext::OLD_CELL_GAS * 2
2162 + SimpleContext::BUILD_CELL_GAS,
2163 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2164 ];
2165
2166 check_range(-5..5, DictBound::Min, true, &target_gas)?;
2168 check_range(-5..5, DictBound::Max, true, &target_gas)?;
2169
2170 Ok(())
2171 }
2172
2173 #[test]
2174 fn dict_insert_gas_usage() -> anyhow::Result<()> {
2175 let target_gas = [
2176 SimpleContext::BUILD_CELL_GAS,
2177 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2178 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2179 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2180 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2181 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2182 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2183 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS * 5,
2184 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2185 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2186 ];
2187
2188 let mut dict = RawDict::<32>::new();
2190 for i in 0..10 {
2191 let context = &mut SimpleContext::default();
2192
2193 let mut key = CellBuilder::new();
2194 key.store_u32(i)?;
2195
2196 dict.set_ext(key.as_data_slice(), &i, context)?;
2197
2198 assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2199
2200 println!("===");
2201 }
2202
2203 let mut dict = None::<Cell>;
2205 for i in 0..10 {
2206 let mut key = CellBuilder::new();
2207 key.store_u32(i)?;
2208
2209 let context = &mut SimpleContext::default();
2210 let mut old_root = dict.clone();
2211 dict_insert(
2212 &mut dict,
2213 &mut key.as_data_slice(),
2214 32,
2215 &i,
2216 SetMode::Set,
2217 context,
2218 )?;
2219 assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2220
2221 println!("===");
2222
2223 let context = &mut SimpleContext::default();
2224 let expected_new_root = dict.clone();
2225 crate::dict::dict_insert_owned(
2226 &mut old_root,
2227 &mut key.as_data_slice(),
2228 32,
2229 &i,
2230 SetMode::Set,
2231 context,
2232 )?;
2233 assert_eq!(dict, expected_new_root);
2234
2235 assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2236
2237 println!("===");
2238 }
2239
2240 let mut key = CellBuilder::new();
2242 key.store_u32(5)?;
2243
2244 let context = &mut SimpleContext::default();
2245 dict_insert(
2246 &mut dict,
2247 &mut key.as_data_slice(),
2248 32,
2249 &5u32,
2250 SetMode::Add,
2251 context,
2252 )?;
2253 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5); println!("===");
2256
2257 let context = &mut SimpleContext::default();
2258 crate::dict::dict_insert_owned(
2259 &mut dict,
2260 &mut key.as_data_slice(),
2261 32,
2262 &5u32,
2263 SetMode::Add,
2264 context,
2265 )?;
2266 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5); Ok(())
2269 }
2270}