1use std::collections::BTreeMap;
2
3use super::{
4 DictBound, DictOwnedEntry, SetMode, StoreDictKey, build_dict_from_sorted_iter, dict_find_bound,
5 dict_find_bound_owned, dict_find_owned, dict_get, dict_get_owned, dict_get_subdict,
6 dict_insert, dict_load_from_root, dict_remove_bound_owned, dict_remove_owned,
7 dict_split_by_prefix, read_label,
8};
9use crate::cell::*;
10use crate::error::Error;
11use crate::util::{IterStatus, unlikely};
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 { cmp.reverse() } else { cmp }
1106 };
1107
1108 match cmp {
1109 std::cmp::Ordering::Less => {
1110 let res = Some(Ok((left_key.clone(), Some(*left_value), None)));
1111 self.left_peeked = None;
1112 res
1113 }
1114 std::cmp::Ordering::Greater => {
1115 let res = Some(Ok((right_key.clone(), None, Some(*right_value))));
1116 self.right_peeked = None;
1117 res
1118 }
1119 std::cmp::Ordering::Equal => {
1120 let res = Some(Ok((
1121 left_key.clone(),
1122 Some(*left_value),
1123 Some(*right_value),
1124 )));
1125 self.left_peeked = None;
1126 self.right_peeked = None;
1127 res
1128 }
1129 }
1130 }
1131 }
1132 }
1133}
1134
1135#[derive(Clone)]
1144pub struct RawKeys<'a> {
1145 inner: RawIter<'a>,
1146}
1147
1148impl<'a> RawKeys<'a> {
1149 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1151 Self {
1152 inner: RawIter::new(root, bit_len),
1153 }
1154 }
1155
1156 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1159 Self {
1160 inner: RawIter::new_ext(root, bit_len, reversed, signed),
1161 }
1162 }
1163
1164 #[inline]
1166 pub fn reversed(mut self) -> Self {
1167 self.inner.reversed = true;
1168 self
1169 }
1170
1171 #[inline]
1173 pub fn signed(mut self) -> Self {
1174 self.inner.signed = true;
1175 self
1176 }
1177
1178 #[inline]
1180 pub fn is_reversed(&self) -> bool {
1181 self.inner.reversed
1182 }
1183
1184 #[inline]
1186 pub fn is_signed(&self) -> bool {
1187 self.inner.signed
1188 }
1189}
1190
1191impl Iterator for RawKeys<'_> {
1192 type Item = Result<CellDataBuilder, Error>;
1193
1194 fn next(&mut self) -> Option<Self::Item> {
1195 match self.inner.next()? {
1196 Ok((key, _)) => Some(Ok(key)),
1197 Err(e) => Some(Err(e)),
1198 }
1199 }
1200}
1201
1202#[derive(Clone)]
1209pub struct RawOwnedValues<'a> {
1210 root: &'a Option<Cell>,
1211 inner: RawValues<'a>,
1212}
1213
1214impl<'a> RawOwnedValues<'a> {
1215 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1217 Self {
1218 inner: RawValues::new(root, bit_len),
1219 root,
1220 }
1221 }
1222
1223 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1226 Self {
1227 inner: RawValues::new_ext(root, bit_len, reversed, signed),
1228 root,
1229 }
1230 }
1231
1232 #[inline]
1234 pub fn reversed(mut self) -> Self {
1235 self.inner.reversed = true;
1236 self
1237 }
1238
1239 #[inline]
1241 pub fn signed(mut self) -> Self {
1242 self.inner.signed = true;
1243 self
1244 }
1245
1246 #[inline]
1248 pub fn is_reversed(&self) -> bool {
1249 self.inner.reversed
1250 }
1251
1252 #[inline]
1254 pub fn is_signed(&self) -> bool {
1255 self.inner.signed
1256 }
1257}
1258
1259impl Iterator for RawOwnedValues<'_> {
1260 type Item = Result<CellSliceParts, Error>;
1261
1262 fn next(&mut self) -> Option<Self::Item> {
1263 Some(match self.inner.next()? {
1264 Ok(slice) => {
1265 let parent = match self.inner.segments.last() {
1266 Some(segment) => {
1267 let refs_offset = segment.data.offset_refs();
1268 debug_assert!(refs_offset > 0);
1269 match segment.data.cell().reference_cloned(refs_offset - 1) {
1270 Some(cell) => cell,
1271 None => return Some(Err(self.inner.finish(Error::CellUnderflow))),
1272 }
1273 }
1274 None => match self.root {
1275 Some(root) => root.clone(),
1276 None => {
1277 debug_assert!(false, "Non-empty iterator for empty dict");
1278 unsafe { std::hint::unreachable_unchecked() };
1279 }
1280 },
1281 };
1282 Ok((slice.range(), parent))
1283 }
1284 Err(e) => Err(e),
1285 })
1286 }
1287}
1288
1289#[derive(Clone)]
1298pub struct RawValues<'a> {
1299 segments: Vec<ValuesSegment<'a>>,
1300 status: IterStatus,
1301 reversed: bool,
1302 signed: bool,
1303}
1304
1305impl<'a> RawValues<'a> {
1306 pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1308 Self::new_ext(root, bit_len, false, false)
1309 }
1310
1311 pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1314 let mut segments = Vec::new();
1315 if let Some(root) = root {
1316 let Ok(data) = root.as_slice() else {
1317 return Self {
1318 segments: Vec::new(),
1319 status: IterStatus::UnexpectedCell,
1320 reversed,
1321 signed,
1322 };
1323 };
1324
1325 segments.push(ValuesSegment {
1326 data,
1327 remaining_bit_len: bit_len,
1328 });
1329 }
1330 Self {
1331 segments,
1332 status: IterStatus::Valid,
1333 reversed,
1334 signed,
1335 }
1336 }
1337
1338 #[inline]
1340 pub fn reversed(mut self) -> Self {
1341 self.reversed = true;
1342 self
1343 }
1344
1345 #[inline]
1347 pub fn signed(mut self) -> Self {
1348 self.signed = true;
1349 self
1350 }
1351
1352 #[inline]
1354 pub fn is_reversed(&self) -> bool {
1355 self.reversed
1356 }
1357
1358 #[inline]
1360 pub fn is_signed(&self) -> bool {
1361 self.signed
1362 }
1363
1364 #[inline]
1365 pub(crate) fn finish(&mut self, err: Error) -> Error {
1366 self.status = IterStatus::Broken;
1367 err
1368 }
1369}
1370
1371impl<'a> Iterator for RawValues<'a> {
1372 type Item = Result<CellSlice<'a>, Error>;
1373
1374 fn next(&mut self) -> Option<Self::Item> {
1375 if unlikely(!self.status.is_valid()) {
1376 return if self.status.is_unexpected_cell() {
1377 self.status = IterStatus::Broken;
1378 Some(Err(Error::UnexpectedExoticCell))
1379 } else {
1380 None
1381 };
1382 }
1383
1384 fn next_impl<'a>(
1385 reverse: bool,
1386 signed: bool,
1387 segments: &mut Vec<ValuesSegment<'a>>,
1388 ) -> Result<Option<CellSlice<'a>>, Error> {
1389 #[allow(clippy::never_loop)]
1390 loop {
1391 let segment = loop {
1393 let is_root = segments.len() == 1;
1394 let Some(segment) = segments.last_mut() else {
1395 return Ok(None);
1396 };
1397
1398 if segment.data.offset_bits() == 0 {
1399 break segment;
1400 }
1401
1402 let refs_offset = segment.data.offset_refs();
1403 if refs_offset < 2 {
1404 let remaining_bit_len = segment.remaining_bit_len;
1406 let next_bit = (refs_offset != 0)
1407 ^ reverse
1408 ^ (signed && is_root && segment.data.is_data_empty());
1409 let data = ok!(segment.data.cell().get_reference_as_slice(next_bit as u8));
1410 segment.data.skip_first(0, 1).ok();
1411
1412 segments.push(ValuesSegment {
1413 data,
1414 remaining_bit_len,
1415 });
1416 break unsafe { segments.last_mut().unwrap_unchecked() };
1418 } else {
1419 segments.pop();
1420 }
1421 };
1422
1423 let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
1425
1426 return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
1428 Some(0) => {
1430 let data = segment.data;
1431 segments.pop();
1433 Ok(Some(data))
1434 }
1435 Some(remaining) => {
1437 if segment.data.size_refs() < 2 {
1438 return Err(Error::CellUnderflow);
1439 }
1440 segment.remaining_bit_len = remaining - 1;
1441 continue;
1443 }
1444 None => Err(Error::CellUnderflow),
1445 };
1446 }
1447 }
1448
1449 match next_impl(self.reversed, self.signed, &mut self.segments) {
1450 Ok(res) => res.map(Ok),
1451 Err(e) => Some(Err(self.finish(e))),
1452 }
1453 }
1454}
1455
1456#[derive(Copy, Clone)]
1457struct ValuesSegment<'a> {
1458 data: CellSlice<'a>,
1459 remaining_bit_len: u16,
1460}
1461
1462#[cfg(test)]
1463mod tests {
1464
1465 use super::*;
1466 use crate::prelude::*;
1467
1468 fn build_cell<F: FnOnce(&mut CellBuilder) -> Result<(), Error>>(f: F) -> Cell {
1469 let mut builder = CellBuilder::new();
1470 f(&mut builder).unwrap();
1471 builder.build().unwrap()
1472 }
1473
1474 #[test]
1475 fn dict_set() -> anyhow::Result<()> {
1476 let mut dict = RawDict::<32>::new();
1477
1478 let key = CellBuilder::build_from(123u32)?;
1479
1480 dict.set(key.as_slice()?, ())?;
1481 {
1482 let mut values = dict.values();
1483 let value = values.next().unwrap().unwrap();
1484 assert!(value.is_data_empty() && value.is_refs_empty());
1485 assert!(values.next().is_none());
1486 }
1487
1488 dict.set(key.as_slice()?, 0xffffu16)?;
1489 {
1490 let mut values = dict.values();
1491 let mut value = values.next().unwrap()?;
1492 assert_eq!(value.load_u16(), Ok(0xffff));
1493 assert!(value.is_data_empty() && value.is_refs_empty());
1494 assert!(values.next().is_none());
1495 }
1496
1497 Ok(())
1498 }
1499
1500 #[test]
1501 #[cfg_attr(miri, ignore)] fn dict_set_complex() -> anyhow::Result<()> {
1503 let mut dict = RawDict::<32>::new();
1504 for i in 0..520 {
1505 let key = build_cell(|b| b.store_u32(i));
1506 dict.set(key.as_slice()?, true)?;
1507
1508 let mut total = 0;
1509 for (i, item) in dict.iter().enumerate() {
1510 total += 1;
1511 let (key, value) = item?;
1512 assert_eq!(key.size_bits(), 32);
1513 assert_eq!(value.size_bits(), 1);
1514 let key = key.as_data_slice().load_u32()?;
1515 assert_eq!(key, i as u32);
1516 }
1517 assert_eq!(total, i + 1);
1518 }
1519
1520 Ok(())
1521 }
1522
1523 #[test]
1524 fn dict_replace() -> anyhow::Result<()> {
1525 let mut dict = RawDict::<32>::new();
1526
1527 dict.replace(build_cell(|b| b.store_u32(123)).as_slice()?, false)
1529 .unwrap();
1530 assert!(
1531 !dict
1532 .contains_key(build_cell(|b| b.store_u32(123)).as_slice()?)
1533 .unwrap()
1534 );
1535
1536 dict.set(build_cell(|b| b.store_u32(123)).as_slice()?, false)
1538 .unwrap();
1539 dict.replace(build_cell(|b| b.store_u32(123)).as_slice()?, true)
1540 .unwrap();
1541
1542 let mut value = dict
1543 .get(build_cell(|b| b.store_u32(123)).as_slice()?)
1544 .unwrap()
1545 .unwrap();
1546 assert_eq!(value.size_bits(), 1);
1547 assert_eq!(value.load_bit(), Ok(true));
1548
1549 Ok(())
1550 }
1551
1552 #[test]
1553 fn dict_add() -> anyhow::Result<()> {
1554 let mut dict = RawDict::<32>::new();
1555
1556 let key = build_cell(|b| b.store_u32(123));
1557
1558 dict.add(key.as_slice()?, false)?;
1560 let mut value = dict.get(key.as_slice()?)?.unwrap();
1561 assert_eq!(value.size_bits(), 1);
1562 assert_eq!(value.load_bit(), Ok(false));
1563
1564 dict.add(key.as_slice()?, true)?;
1566 let mut value = dict.get(key.as_slice()?)?.unwrap();
1567 assert_eq!(value.size_bits(), 1);
1568 assert_eq!(value.load_bit(), Ok(false));
1569
1570 Ok(())
1571 }
1572
1573 #[test]
1574 fn dict_split() -> anyhow::Result<()> {
1575 let mut dict = RawDict::<4>::new();
1576 for i in 0..16 {
1577 let key = build_cell(|b| b.store_small_uint(i, 4));
1578 dict.add(key.as_slice()?, i)?;
1579 }
1580
1581 let (left, right) = dict.split()?;
1582 assert!(!left.is_empty());
1583 assert!(!right.is_empty());
1584 assert_eq!(left.iter().count(), 8);
1585 assert_eq!(right.iter().count(), 8);
1586
1587 let (ll, lr) = left.split()?;
1588 assert!(!ll.is_empty());
1589 assert!(lr.is_empty());
1590 assert_eq!(ll.iter().count(), 8);
1591
1592 let (rl, rr) = right.split()?;
1593 assert!(rl.is_empty());
1594 assert!(!rr.is_empty());
1595 assert_eq!(rr.iter().count(), 8);
1596
1597 let (left, right) = RawDict::<4>::new().split()?;
1598 assert!(left.is_empty());
1599 assert!(right.is_empty());
1600
1601 Ok(())
1602 }
1603
1604 #[test]
1605 fn dict_split_by_prefix() -> anyhow::Result<()> {
1606 fn check_range(dict: &RawDict<4>, mut range: std::ops::Range<u8>) {
1607 for key in dict.keys() {
1608 let key = key.unwrap();
1609 let key = key.as_data_slice().load_small_uint(4).unwrap();
1610 assert_eq!(key, range.next().unwrap());
1611 }
1612 assert_eq!(range.next(), None);
1613 }
1614
1615 let mut dict = RawDict::<4>::new();
1616 for i in 0..16 {
1617 let key = build_cell(|b| b.store_small_uint(i, 4));
1618 dict.add(key.as_slice()?, i)?;
1619 }
1620
1621 let (left, right) = dict.split()?;
1622 check_range(&left, 0..8);
1623 check_range(&right, 8..16);
1624
1625 {
1626 let mut prefix = CellBuilder::new();
1627 prefix.store_bit_one()?;
1628 let res = dict.split_by_prefix(&prefix.as_data_slice());
1629 assert!(matches!(res, Err(Error::CellUnderflow)));
1630 }
1631
1632 let (ll, lr) = {
1633 let mut prefix = CellBuilder::new();
1634 prefix.store_bit_zero()?;
1635 left.split_by_prefix(&prefix.as_data_slice())?
1636 };
1637 check_range(&ll, 0..4);
1638 check_range(&lr, 4..8);
1639
1640 let (rl, rr) = {
1641 let mut prefix = CellBuilder::new();
1642 prefix.store_bit_one()?;
1643 right.split_by_prefix(&prefix.as_data_slice())?
1644 };
1645 check_range(&rl, 8..12);
1646 check_range(&rr, 12..16);
1647
1648 Ok(())
1649 }
1650
1651 #[test]
1652 fn dict_get_subdict() -> anyhow::Result<()> {
1653 let mut dict = RawDict::<32>::new();
1654 for i in 0u32..4 {
1655 let key = CellBuilder::build_from(i)?;
1657 println!("ADDING KEY {}", key.display_data());
1658 dict.add(key.as_slice()?, i)?;
1659 }
1660
1661 let cell = dict.root().as_ref().unwrap();
1662 let boc = Boc::encode_base64(cell);
1663
1664 println!("{boc}");
1665
1666 let key = CellBuilder::build_from(1u16 << 8)?;
1667
1668 println!("KEY: {}", key.display_data());
1669
1670 let context = &mut SimpleContext::default();
1671
1672 let value: Cell = dict.get_subdict(key.as_slice()?, context)?.unwrap();
1673
1674 print!("{}", value.display_tree());
1675
1676 Ok(())
1677 }
1678
1679 #[test]
1680 fn dict_get() -> anyhow::Result<()> {
1681 let boc = Boc::decode_base64(
1682 "te6ccgECOwEAASoAAQHAAQIBIBACAgEgAwMCASAEBAIBIAUFAgEgBgYCASAHBwIBIAgIAgEgCQkCASAoCgIBIAsZAgEgDBsCASArDQIBIA4fAgEgLQ8CASAuIQIBIBERAgEgEhICASATEwIBIBQUAgEgFRUCASAWFgIBIBcXAgEgKBgCASAaGQIBIBsbAgEgHRsCASAcHAIBIB8fAgEgKx4CASAiHwIBICAgAgEgISECASAlJQIBIC0jAgEgLiQCASAvJQIBIDMmAgFiNicCAUg4OAIBICkpAgEgKioCASArKwIBICwsAgEgLS0CASAuLgIBIC8vAgEgMzACAWI2MQIBIDcyAAnWAAAmbwIBIDQ0AgEgNTUCASA2NgIBIDc3AgEgODgCASA5OQIBIDo6AAnQAAAmbw==",
1683 )?;
1684
1685 let dict = boc.parse::<RawDict<32>>()?;
1688
1689 let key = CellBuilder::build_from(u32::from_be_bytes(123u32.to_le_bytes()))?;
1690 let value = dict.get(key.as_slice()?)?.unwrap();
1691
1692 {
1693 let (range, cell) = dict.get_owned(key.as_slice()?)?.unwrap();
1694 assert_eq!(range.apply(&cell).unwrap(), value);
1695 }
1696
1697 let value = {
1698 let mut builder = CellBuilder::new();
1699 builder.store_slice(value)?;
1700 builder.build()?
1701 };
1702 println!("{}", value.display_tree());
1703
1704 Ok(())
1705 }
1706
1707 #[test]
1708 fn dict_iter() -> anyhow::Result<()> {
1709 let boc = Boc::decode_base64(
1710 "te6ccgEBFAEAeAABAcABAgPOQAUCAgHUBAMACQAAAI3gAAkAAACjoAIBIA0GAgEgCgcCASAJCAAJAAAAciAACQAAAIfgAgEgDAsACQAAAFZgAAkAAABsIAIBIBEOAgEgEA8ACQAAADqgAAkAAABQYAIBIBMSAAkAAAAe4AAJAAAAv2A=",
1711 )?;
1712 let dict = boc.parse::<RawDict<32>>()?;
1713
1714 let size = dict.values().count();
1715 assert_eq!(size, 10);
1716
1717 let mut rev_iter_items = dict.iter().reversed().collect::<Vec<_>>();
1718 rev_iter_items.reverse();
1719 let mut rev_iter_items = rev_iter_items.into_iter();
1720
1721 for (i, entry) in dict.iter().enumerate() {
1722 let (key, value) = entry?;
1723
1724 let (rev_key, rev_value) = rev_iter_items.next().unwrap().unwrap();
1725 assert_eq!(key, rev_key);
1726 assert_eq!(value.lex_cmp(&rev_value), Ok(std::cmp::Ordering::Equal));
1727
1728 let key = key.as_data_slice().load_u32()?;
1729 assert_eq!(key, i as u32);
1730 }
1731 assert!(rev_iter_items.next().is_none());
1732
1733 let mut last = None;
1734 for (i, entry) in dict.iter_owned().enumerate() {
1735 let (key, (range, cell)) = entry?;
1736
1737 {
1738 let mut slice = range.apply(&cell).unwrap();
1739 assert_eq!(slice.size_bits(), 32);
1740 u32::load_from(&mut slice).unwrap();
1741 }
1742
1743 let key = key.as_data_slice().load_u32()?;
1744 assert_eq!(key, i as u32);
1745 last = Some(key);
1746 }
1747 assert_eq!(last, Some(9));
1748
1749 let mut values_ref = dict.values();
1750 let mut values_owned = dict.values_owned();
1751 for (value_ref, value_owned) in (&mut values_ref).zip(&mut values_owned) {
1752 let value_ref = value_ref.unwrap();
1753 let (range, cell) = value_owned.unwrap();
1754 let value_owned = range.apply(&cell).unwrap();
1755 assert_eq!(
1756 value_ref.lex_cmp(&value_owned),
1757 Ok(std::cmp::Ordering::Equal)
1758 );
1759 }
1760 assert!(values_ref.next().is_none());
1761 assert!(values_owned.next().is_none());
1762
1763 Ok(())
1764 }
1765
1766 #[test]
1767 fn dict_iter_union() -> anyhow::Result<()> {
1768 let mut left = RawDict::<32>::new();
1769 let mut right = RawDict::<32>::new();
1770
1771 for i in -4i32..4 {
1773 let key = build_cell(|b| b.store_u32(i as _));
1774 left.set(key.as_slice()?, i)?;
1775 }
1776 for i in -2i32..6 {
1777 let key = build_cell(|b| b.store_u32(i as _));
1778 right.set(key.as_slice()?, i + 100)?;
1779 }
1780
1781 fn compare_iter_values(iter: UnionRawIter<'_>, values: &[(i32, Option<i32>, Option<i32>)]) {
1782 let mut values = values.iter();
1783
1784 for entry in iter {
1785 let (key, left_value, right_value) = entry.unwrap();
1786 let key = key.as_data_slice().load_u32().unwrap() as i32;
1787 let left_value = left_value.map(|v| v.get_u32(0).unwrap() as i32);
1788 let right_value = right_value.map(|v| v.get_u32(0).unwrap() as i32);
1789
1790 assert_eq!(values.next(), Some(&(key, left_value, right_value)));
1791 }
1792 assert_eq!(values.next(), None);
1793 }
1794
1795 compare_iter_values(left.iter_union(&right), &[
1797 (0, Some(0), Some(100)),
1798 (1, Some(1), Some(101)),
1799 (2, Some(2), Some(102)),
1800 (3, Some(3), Some(103)),
1801 (4, None, Some(104)),
1802 (5, None, Some(105)),
1803 (-4, Some(-4), None),
1804 (-3, Some(-3), None),
1805 (-2, Some(-2), Some(98)),
1806 (-1, Some(-1), Some(99)),
1807 ]);
1808
1809 compare_iter_values(left.iter_union(&right).reversed(), &[
1811 (-1, Some(-1), Some(99)),
1812 (-2, Some(-2), Some(98)),
1813 (-3, Some(-3), None),
1814 (-4, Some(-4), None),
1815 (5, None, Some(105)),
1816 (4, None, Some(104)),
1817 (3, Some(3), Some(103)),
1818 (2, Some(2), Some(102)),
1819 (1, Some(1), Some(101)),
1820 (0, Some(0), Some(100)),
1821 ]);
1822
1823 compare_iter_values(left.iter_union(&right).signed(), &[
1825 (-4, Some(-4), None),
1826 (-3, Some(-3), None),
1827 (-2, Some(-2), Some(98)),
1828 (-1, Some(-1), Some(99)),
1829 (0, Some(0), Some(100)),
1830 (1, Some(1), Some(101)),
1831 (2, Some(2), Some(102)),
1832 (3, Some(3), Some(103)),
1833 (4, None, Some(104)),
1834 (5, None, Some(105)),
1835 ]);
1836
1837 compare_iter_values(left.iter_union(&right).signed().reversed(), &[
1839 (5, None, Some(105)),
1840 (4, None, Some(104)),
1841 (3, Some(3), Some(103)),
1842 (2, Some(2), Some(102)),
1843 (1, Some(1), Some(101)),
1844 (0, Some(0), Some(100)),
1845 (-1, Some(-1), Some(99)),
1846 (-2, Some(-2), Some(98)),
1847 (-3, Some(-3), None),
1848 (-4, Some(-4), None),
1849 ]);
1850
1851 Ok(())
1852 }
1853
1854 #[derive(Debug, Default)]
1855 struct SimpleContext {
1856 used_gas: std::cell::Cell<u64>,
1857 loaded_cells: std::cell::RefCell<ahash::HashSet<HashBytes>>,
1858 empty_context: <Cell as CellFamily>::EmptyCellContext,
1859 }
1860
1861 impl SimpleContext {
1862 const BUILD_CELL_GAS: u64 = 500;
1863 const NEW_CELL_GAS: u64 = 100;
1864 const OLD_CELL_GAS: u64 = 25;
1865
1866 fn consume_gas(&self, cell: &DynCell, mode: LoadMode) {
1867 if mode.use_gas() {
1868 let consumed_gas = if self.loaded_cells.borrow_mut().insert(*cell.repr_hash()) {
1869 Self::NEW_CELL_GAS
1870 } else {
1871 Self::OLD_CELL_GAS
1872 };
1873
1874 self.used_gas.set(self.used_gas.get() + consumed_gas);
1875 }
1876 }
1877 }
1878
1879 impl CellContext for SimpleContext {
1880 #[inline]
1881 fn finalize_cell(&self, cell: CellParts<'_>) -> Result<Cell, Error> {
1882 self.used_gas
1883 .set(self.used_gas.get() + Self::BUILD_CELL_GAS);
1884 self.empty_context.finalize_cell(cell)
1885 }
1886
1887 #[inline]
1888 fn load_cell(&self, cell: Cell, mode: LoadMode) -> Result<Cell, Error> {
1889 self.consume_gas(cell.as_ref(), mode);
1890 Ok(cell)
1891 }
1892
1893 #[inline]
1894 fn load_dyn_cell<'s: 'a, 'a>(
1895 &self,
1896 cell: &'a DynCell,
1897 mode: LoadMode,
1898 ) -> Result<&'a DynCell, Error> {
1899 self.consume_gas(cell, mode);
1900 Ok(cell)
1901 }
1902 }
1903
1904 #[test]
1905 fn dict_get_gas_usage() -> anyhow::Result<()> {
1906 let mut dict = RawDict::<32>::new();
1908 for i in 0..10 {
1909 let mut key = CellBuilder::new();
1910 key.store_u32(i)?;
1911 dict.set(key.as_data_slice(), i)?;
1912 }
1913
1914 let context = &mut SimpleContext::default();
1916
1917 let mut key = CellBuilder::new();
1918 key.store_u32(5)?;
1919
1920 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1921 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5);
1922
1923 context.used_gas.set(0);
1924 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1925 assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 5);
1926
1927 context.used_gas.set(0);
1929 let mut key = CellBuilder::new();
1930 key.store_u32(9)?;
1931
1932 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1933 assert_eq!(
1934 context.used_gas.get(),
1935 SimpleContext::OLD_CELL_GAS + SimpleContext::NEW_CELL_GAS * 2
1936 );
1937
1938 context.used_gas.set(0);
1939 dict.get_ext(key.as_data_slice(), context)?.unwrap();
1940 assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 3);
1941
1942 Ok(())
1943 }
1944
1945 #[test]
1946 fn dict_get_owned_gas_usage() -> anyhow::Result<()> {
1947 let mut dict = RawDict::<32>::new();
1949 for i in 0..10 {
1950 let mut key = CellBuilder::new();
1951 key.store_u32(i)?;
1952 dict.set(key.as_data_slice(), i)?;
1953 }
1954
1955 let context = &mut SimpleContext::default();
1957
1958 let mut key = CellBuilder::new();
1959 key.store_u32(5)?;
1960
1961 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1962 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5);
1963
1964 context.used_gas.set(0);
1965 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1966 assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 5);
1967
1968 context.used_gas.set(0);
1970 let mut key = CellBuilder::new();
1971 key.store_u32(9)?;
1972
1973 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1974 assert_eq!(
1975 context.used_gas.get(),
1976 SimpleContext::OLD_CELL_GAS + SimpleContext::NEW_CELL_GAS * 2
1977 );
1978
1979 context.used_gas.set(0);
1980 dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1981 assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 3);
1982
1983 Ok(())
1984 }
1985
1986 #[test]
1987 fn dict_remove_gas_usage() -> anyhow::Result<()> {
1988 let mut dict = RawDict::<32>::new();
1989 for i in 0..10 {
1990 let mut key = CellBuilder::new();
1991 key.store_u32(i)?;
1992 dict.set(key.as_data_slice(), i)?;
1993 }
1994
1995 let mut key = CellBuilder::new();
1997 key.store_u32(10)?;
1998
1999 let context = &mut SimpleContext::default();
2000 assert!(dict.remove_ext(key.as_data_slice(), context)?.is_none());
2001
2002 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 2);
2003
2004 let target_gas = [
2006 SimpleContext::NEW_CELL_GAS * 6 + SimpleContext::BUILD_CELL_GAS * 4,
2007 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2008 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2009 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2010 SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2011 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2012 SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2013 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS,
2014 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS,
2015 SimpleContext::NEW_CELL_GAS,
2016 ];
2017
2018 for i in 0..10 {
2019 println!("===");
2020
2021 let context = &mut SimpleContext::default();
2022
2023 let mut key = CellBuilder::new();
2024 key.store_u32(i)?;
2025
2026 let removed = dict.remove_ext(key.as_data_slice(), context)?;
2027 assert!(removed.is_some());
2028
2029 assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2030 }
2031
2032 Ok(())
2033 }
2034
2035 #[test]
2036 fn dict_remove_bound() -> anyhow::Result<()> {
2037 let make_dict = |range: std::ops::Range<i32>| {
2038 let mut dict = RawDict::<32>::new();
2039 for i in range {
2040 let mut key = CellBuilder::new();
2041 key.store_u32(i as u32)?;
2042 dict.set(key.as_data_slice(), i)?;
2043 }
2044 Ok::<_, anyhow::Error>(dict)
2045 };
2046
2047 let check_range =
2048 |range: std::ops::Range<i32>, bound: DictBound, signed: bool, target_gas: &[u64]| {
2049 let mut dict = make_dict(range.clone())?;
2050 for &target_gas in target_gas {
2051 println!("=== {range:?} bound={bound:?} signed={signed} [non-owned]");
2052 let context = &mut SimpleContext::default();
2053 let (key, _) = dict.get_bound_ext(bound, signed, context)?.unwrap();
2054 let removed = dict.clone().remove_ext(key.as_data_slice(), context)?;
2055 assert!(removed.is_some());
2056 assert_eq!(context.used_gas.get(), target_gas);
2057
2058 println!("=== {range:?} bound={bound:?} signed={signed} [owned]");
2059 let context = &mut SimpleContext::default();
2060 let (key, _) = dict.get_bound_owned_ext(bound, signed, context)?.unwrap();
2061 let removed = dict.remove_ext(key.as_data_slice(), context)?;
2062 assert!(removed.is_some());
2063 assert_eq!(context.used_gas.get(), target_gas);
2064 }
2065
2066 Ok::<_, anyhow::Error>(())
2067 };
2068
2069 let target_gas = [
2071 SimpleContext::NEW_CELL_GAS * 6
2072 + SimpleContext::OLD_CELL_GAS * 5
2073 + SimpleContext::BUILD_CELL_GAS * 4,
2074 SimpleContext::NEW_CELL_GAS * 5
2075 + SimpleContext::OLD_CELL_GAS * 4
2076 + SimpleContext::BUILD_CELL_GAS * 3,
2077 SimpleContext::NEW_CELL_GAS * 5
2078 + SimpleContext::OLD_CELL_GAS * 4
2079 + SimpleContext::BUILD_CELL_GAS * 3,
2080 SimpleContext::NEW_CELL_GAS * 4
2081 + SimpleContext::OLD_CELL_GAS * 3
2082 + SimpleContext::BUILD_CELL_GAS * 2,
2083 SimpleContext::NEW_CELL_GAS * 5
2084 + SimpleContext::OLD_CELL_GAS * 4
2085 + SimpleContext::BUILD_CELL_GAS * 3,
2086 SimpleContext::NEW_CELL_GAS * 4
2087 + SimpleContext::OLD_CELL_GAS * 3
2088 + SimpleContext::BUILD_CELL_GAS * 2,
2089 SimpleContext::NEW_CELL_GAS * 4
2090 + SimpleContext::OLD_CELL_GAS * 3
2091 + SimpleContext::BUILD_CELL_GAS * 2,
2092 SimpleContext::NEW_CELL_GAS * 3
2093 + SimpleContext::OLD_CELL_GAS * 2
2094 + SimpleContext::BUILD_CELL_GAS,
2095 SimpleContext::NEW_CELL_GAS * 3
2096 + SimpleContext::OLD_CELL_GAS * 2
2097 + SimpleContext::BUILD_CELL_GAS,
2098 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2099 ];
2100 check_range(0..10, DictBound::Min, false, &target_gas)?;
2101
2102 let target_gas = [
2104 SimpleContext::NEW_CELL_GAS * 4
2105 + SimpleContext::OLD_CELL_GAS * 3
2106 + SimpleContext::BUILD_CELL_GAS * 2,
2107 SimpleContext::NEW_CELL_GAS * 3
2108 + SimpleContext::OLD_CELL_GAS * 2
2109 + SimpleContext::BUILD_CELL_GAS,
2110 SimpleContext::NEW_CELL_GAS * 5
2111 + SimpleContext::OLD_CELL_GAS * 4
2112 + SimpleContext::BUILD_CELL_GAS * 3,
2113 SimpleContext::NEW_CELL_GAS * 4
2114 + SimpleContext::OLD_CELL_GAS * 3
2115 + SimpleContext::BUILD_CELL_GAS * 2,
2116 SimpleContext::NEW_CELL_GAS * 4
2117 + SimpleContext::OLD_CELL_GAS * 3
2118 + SimpleContext::BUILD_CELL_GAS * 2,
2119 SimpleContext::NEW_CELL_GAS * 3
2120 + SimpleContext::OLD_CELL_GAS * 2
2121 + SimpleContext::BUILD_CELL_GAS,
2122 SimpleContext::NEW_CELL_GAS * 4
2123 + SimpleContext::OLD_CELL_GAS * 3
2124 + SimpleContext::BUILD_CELL_GAS * 2,
2125 SimpleContext::NEW_CELL_GAS * 3
2126 + SimpleContext::OLD_CELL_GAS * 2
2127 + SimpleContext::BUILD_CELL_GAS,
2128 SimpleContext::NEW_CELL_GAS * 3
2129 + SimpleContext::OLD_CELL_GAS * 2
2130 + SimpleContext::BUILD_CELL_GAS,
2131 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2132 ];
2133 check_range(0..10, DictBound::Max, false, &target_gas)?;
2134
2135 let target_gas = [
2137 SimpleContext::NEW_CELL_GAS * 4
2138 + SimpleContext::OLD_CELL_GAS * 3
2139 + SimpleContext::BUILD_CELL_GAS * 2,
2140 SimpleContext::NEW_CELL_GAS * 5
2141 + SimpleContext::OLD_CELL_GAS * 4
2142 + SimpleContext::BUILD_CELL_GAS * 3,
2143 SimpleContext::NEW_CELL_GAS * 4
2144 + SimpleContext::OLD_CELL_GAS * 3
2145 + SimpleContext::BUILD_CELL_GAS * 2,
2146 SimpleContext::NEW_CELL_GAS * 4
2147 + SimpleContext::OLD_CELL_GAS * 3
2148 + SimpleContext::BUILD_CELL_GAS * 2,
2149 SimpleContext::NEW_CELL_GAS * 3
2150 + SimpleContext::OLD_CELL_GAS * 2
2151 + SimpleContext::BUILD_CELL_GAS,
2152 SimpleContext::NEW_CELL_GAS * 5
2153 + SimpleContext::OLD_CELL_GAS * 4
2154 + SimpleContext::BUILD_CELL_GAS * 3,
2155 SimpleContext::NEW_CELL_GAS * 4
2156 + SimpleContext::OLD_CELL_GAS * 3
2157 + SimpleContext::BUILD_CELL_GAS * 2,
2158 SimpleContext::NEW_CELL_GAS * 4
2159 + SimpleContext::OLD_CELL_GAS * 3
2160 + SimpleContext::BUILD_CELL_GAS * 2,
2161 SimpleContext::NEW_CELL_GAS * 3
2162 + SimpleContext::OLD_CELL_GAS * 2
2163 + SimpleContext::BUILD_CELL_GAS,
2164 SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2165 ];
2166
2167 check_range(-5..5, DictBound::Min, true, &target_gas)?;
2169 check_range(-5..5, DictBound::Max, true, &target_gas)?;
2170
2171 Ok(())
2172 }
2173
2174 #[test]
2175 fn dict_insert_gas_usage() -> anyhow::Result<()> {
2176 let target_gas = [
2177 SimpleContext::BUILD_CELL_GAS,
2178 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2179 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2180 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2181 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2182 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2183 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2184 SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS * 5,
2185 SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2186 SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2187 ];
2188
2189 let mut dict = RawDict::<32>::new();
2191 for i in 0..10 {
2192 let context = &mut SimpleContext::default();
2193
2194 let mut key = CellBuilder::new();
2195 key.store_u32(i)?;
2196
2197 dict.set_ext(key.as_data_slice(), &i, context)?;
2198
2199 assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2200
2201 println!("===");
2202 }
2203
2204 let mut dict = None::<Cell>;
2206 for i in 0..10 {
2207 let mut key = CellBuilder::new();
2208 key.store_u32(i)?;
2209
2210 let context = &mut SimpleContext::default();
2211 let mut old_root = dict.clone();
2212 dict_insert(
2213 &mut dict,
2214 &mut key.as_data_slice(),
2215 32,
2216 &i,
2217 SetMode::Set,
2218 context,
2219 )?;
2220 assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2221
2222 println!("===");
2223
2224 let context = &mut SimpleContext::default();
2225 let expected_new_root = dict.clone();
2226 crate::dict::dict_insert_owned(
2227 &mut old_root,
2228 &mut key.as_data_slice(),
2229 32,
2230 &i,
2231 SetMode::Set,
2232 context,
2233 )?;
2234 assert_eq!(dict, expected_new_root);
2235
2236 assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2237
2238 println!("===");
2239 }
2240
2241 let mut key = CellBuilder::new();
2243 key.store_u32(5)?;
2244
2245 let context = &mut SimpleContext::default();
2246 dict_insert(
2247 &mut dict,
2248 &mut key.as_data_slice(),
2249 32,
2250 &5u32,
2251 SetMode::Add,
2252 context,
2253 )?;
2254 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5); println!("===");
2257
2258 let context = &mut SimpleContext::default();
2259 crate::dict::dict_insert_owned(
2260 &mut dict,
2261 &mut key.as_data_slice(),
2262 32,
2263 &5u32,
2264 SetMode::Add,
2265 context,
2266 )?;
2267 assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5); Ok(())
2270 }
2271}