tycho_types/dict/
raw.rs

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
13/// Dictionary with fixed length keys (where `N` is a number of bits in each key).
14///
15/// # TLB scheme
16///
17/// ```text
18/// // ordinary Hashmap / HashmapE, with fixed length keys
19///
20/// hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
21///           {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X;
22///
23/// hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X;
24/// hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X)
25///            right:^(Hashmap n X) = HashmapNode (n + 1) X;
26///
27/// hml_short$0 {m:#} {n:#} len:(Unary ~n) {n <= m} s:(n * Bit) = HmLabel ~n m;
28/// hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m;
29/// hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m;
30///
31/// hme_empty$0 {n:#} {X:Type} = HashmapE n X;
32/// hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X;
33///
34/// unary_zero$0 = Unary ~0;
35/// unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);
36///
37/// bit$_ (## 1) = Bit;
38/// ```
39pub 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    /// Creates an empty dictionary.
116    pub const fn new() -> Self {
117        Self(None)
118    }
119
120    /// Builds a dictionary from a sorted collection.
121    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    /// Builds a dictionary from a sorted slice.
132    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    /// Returns `true` if the dictionary contains no elements.
146    pub const fn is_empty(&self) -> bool {
147        self.0.is_none()
148    }
149
150    /// Returns the underlying root cell of the dictionary.
151    #[inline]
152    pub const fn root(&self) -> &Option<Cell> {
153        &self.0
154    }
155
156    /// Returns the underlying root cell of the dictionary.
157    #[inline]
158    pub fn into_root(self) -> Option<Cell> {
159        self.0
160    }
161
162    /// Loads a non-empty dictionary from a root cell.
163    #[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    /// Returns a `CellSlice` of the value corresponding to the key.
175    ///
176    /// NOTE: Uses the default cell context.
177    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    /// Returns a `CellSlice` of the value corresponding to the key.
182    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    /// Computes the minimal key in dictionary that is lexicographically greater than `key`,
191    /// and returns it along with associated value as cell slice parts.
192    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    /// Get subdict of dictionary by specified key prefix
209    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    /// Computes the maximal key in dictionary that is lexicographically smaller than `key`,
218    /// and returns it along with associated value as cell slice parts.
219    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    /// Computes the minimal key in dictionary that is lexicographically greater than `key`,
236    /// and returns it along with associated value as cell slice parts.
237    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    /// Computes the maximal key in dictionary that is lexicographically smaller than `key`,
254    /// and returns it along with associated value as cell slice parts.
255    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    /// Returns cell slice parts of the value corresponding to the key.
272    ///
273    /// NOTE: Uses the default cell context.
274    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    /// Returns cell slice parts of the value corresponding to the key.
279    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    /// Returns the lowest key and a value corresponding to the key.
288    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    /// Returns the largest key and a value corresponding to the key.
299    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    /// Finds the specified dict bound and returns a key and a value corresponding to the key.
310    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    /// Finds the specified dict bound and returns a key and a value corresponding to the key.
319    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    /// Returns the lowest key and cell slice parts corresponding to the key.
329    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    /// Returns the largest key and cell slice parts corresponding to the key.
343    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    /// Finds the specified dict bound and returns a key and cell slice parts corresponding to the key.
357    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    /// Finds the specified dict bound and returns a key and cell slice parts corresponding to the key.
366    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    /// Returns `true` if the dictionary contains a value for the specified key.
376    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    /// Sets the value associated with the key in the dictionary.
381    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    /// Sets the value associated with the key in the dictionary
391    /// only if the key was already present in it.
392    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    /// Sets the value associated with key in dictionary,
402    /// but only if it is not already present.
403    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    /// Removes the value associated with key in dictionary.
413    /// Returns an optional removed value as cell slice parts.
414    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    /// Removes the specified dict bound.
423    /// Returns an optional removed key and value as cell slice parts.
424    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    /// Split dictionary into 2 dictionaries by the first key bit.
434    pub fn split(&self) -> Result<(Self, Self), Error> {
435        self.split_by_prefix_ext(&Default::default(), Cell::empty_context())
436    }
437
438    /// Split dictionary into 2 dictionaries by the first key bit.
439    pub fn split_ext(&self, context: &dyn CellContext) -> Result<(Self, Self), Error> {
440        self.split_by_prefix_ext(&Default::default(), context)
441    }
442
443    /// Split dictionary into 2 dictionaries at the prefix.
444    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    /// Split dictionary into 2 dictionaries at the prefix.
449    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    /// Gets an iterator over the entries of the dictionary, sorted by key.
464    /// The iterator element type is `Result<(CellDataBuilder, CellSlice)>`.
465    ///
466    /// If the dictionary is invalid, finishes after the first invalid element,
467    /// returning an error.
468    ///
469    /// # Performance
470    ///
471    /// In the current implementation, iterating over dictionary builds a key
472    /// for each element. Use [`values`] if you don't need keys from an iterator.
473    ///
474    /// [`values`]: RawDict::values
475    pub fn iter(&'_ self) -> RawIter<'_> {
476        RawIter::new(&self.0, N)
477    }
478
479    /// Gets an iterator over the entries of two dictionaries, sorted by key.
480    /// The iterator element type is
481    /// `Result<(CellDataBuilder, Option<CellSlice>, Option<CellSlice>)>`.
482    /// Where the first element is the key, the second is the value from the first dictionary,
483    /// and the third is the value from the second dictionary.
484    ///
485    /// If the dictionary is invalid, finishes after the first invalid element,
486    /// returning an error.
487    ///
488    /// # Performance
489    ///
490    /// In the current implementation, iterating over dictionary builds a key
491    /// for each element.
492    pub fn iter_union<'a>(&'a self, other: &'a RawDict<N>) -> UnionRawIter<'a> {
493        UnionRawIter::new(&self.0, &other.0, N)
494    }
495
496    /// Gets an iterator over the owned entries of the dictionary, sorted by key.
497    /// The iterator element type is `Result<(CellDataBuilder, CellSliceParts)>`.
498    ///
499    /// If the dictionary is invalid, finishes after the first invalid element,
500    /// returning an error.
501    ///
502    /// # Performance
503    ///
504    /// In the current implementation, iterating over dictionary builds a key
505    /// for each element. Use [`values_owned`] if you don't need keys from an iterator.
506    ///
507    /// [`values_owned`]: RawDict::values_owned
508    pub fn iter_owned(&'_ self) -> RawOwnedIter<'_> {
509        RawOwnedIter::new(&self.0, N)
510    }
511
512    /// Gets an iterator over the keys of the dictionary, in sorted order.
513    /// The iterator element type is `Result<CellDataBuilder>`.
514    ///
515    /// If the dictionary is invalid, finishes after the first invalid element,
516    /// returning an error.
517    ///
518    /// # Performance
519    ///
520    /// In the current implementation, iterating over dictionary builds a key
521    /// for each element. Use [`values`] if you don't need keys from an iterator.
522    ///
523    /// [`values`]: RawDict::values
524    pub fn keys(&'_ self) -> RawKeys<'_> {
525        RawKeys::new(&self.0, N)
526    }
527
528    /// Gets an iterator over the values of the dictionary, in order by key.
529    /// The iterator element type is `Result<CellSlice>`.
530    ///
531    /// If the dictionary is invalid, finishes after the first invalid element,
532    /// returning an error.
533    pub fn values(&'_ self) -> RawValues<'_> {
534        RawValues::new(&self.0, N)
535    }
536
537    /// Gets an iterator over the owned values of the dictionary, in order by key.
538    /// The iterator element type is `Result<CellSliceParts>`.
539    ///
540    /// If the dictionary is invalid, finishes after the first invalid element,
541    /// returning an error.
542    pub fn values_owned(&'_ self) -> RawOwnedValues<'_> {
543        RawOwnedValues::new(&self.0, N)
544    }
545
546    /// Sets the value associated with the key in the dictionary.
547    ///
548    /// Use [`set_ext`] if you need to use a custom cell context.
549    ///
550    /// [`set_ext`]: RawDict::set_ext
551    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    /// Sets the value associated with the key in the dictionary
556    /// only if the key was already present in it.
557    ///
558    /// Use [`replace_ext`] if you need to use a custom cell context.
559    ///
560    /// [`replace_ext`]: RawDict::replace_ext
561    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    /// Sets the value associated with key in dictionary,
566    /// but only if it is not already present.
567    ///
568    /// Use [`add_ext`] if you need to use a custom cell context.
569    ///
570    /// [`add_ext`]: RawDict::add_ext
571    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    /// Removes the value associated with key in dictionary.
576    /// Returns an optional removed value as cell slice parts.
577    ///
578    /// Use [`remove_ext`] if you need to use a custom cell context.
579    ///
580    /// [`remove_ext`]: RawDict::remove_ext
581    pub fn remove(&mut self, key: CellSlice<'_>) -> Result<Option<CellSliceParts>, Error> {
582        self.remove_ext(key, Cell::empty_context())
583    }
584
585    /// Removes the lowest key from the dict.
586    /// Returns an optional removed key and value as cell slice parts.
587    ///
588    /// Use [`remove_bound_ext`] if you need to use a custom context.
589    ///
590    /// [`remove_bound_ext`]: RawDict::remove_bound_ext
591    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    /// Removes the largest key from the dict.
596    /// Returns an optional removed key and value as cell slice parts.
597    ///
598    /// Use [`remove_bound_ext`] if you need to use a custom cell context.
599    ///
600    /// [`remove_bound_ext`]: RawDict::remove_bound_ext
601    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    /// Removes the specified dict bound.
606    /// Returns an optional removed key and value as cell slice parts.
607    ///
608    /// Use [`remove_bound_ext`] if you need to use a custom cell context.
609    ///
610    /// [`remove_bound_ext`]: RawDict::remove_bound_ext
611    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/// An iterator over the owned entries of a [`RawDict`].
621///
622/// This struct is created by the [`iter_owned`] method on [`RawDict`].
623/// See its documentation for more.
624///
625/// [`iter_owned`]: RawDict::iter_owned
626#[derive(Clone)]
627pub struct RawOwnedIter<'a> {
628    root: &'a Option<Cell>,
629    inner: RawIter<'a>,
630}
631
632impl<'a> RawOwnedIter<'a> {
633    /// Creates an iterator over the owned entries of a dictionary.
634    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    /// Creates an iterator over the entries of a dictionary with explicit
642    /// direction and behavior.
643    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    /// Changes the direction of the iterator to descending.
651    #[inline]
652    pub fn reversed(mut self) -> Self {
653        self.inner.reversed = true;
654        self
655    }
656
657    /// Changes the behavior of the iterator to reverse the high bit.
658    #[inline]
659    pub fn signed(mut self) -> Self {
660        self.inner.signed = true;
661        self
662    }
663
664    /// Returns whether the iterator direction was reversed.
665    #[inline]
666    pub fn is_reversed(&self) -> bool {
667        self.inner.reversed
668    }
669
670    /// Returns whether the iterator treats keys as signed integers.
671    #[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/// An iterator over the entries of a [`RawDict`] or a [`Dict`].
686///
687/// This struct is created by the [`iter`] method on [`RawDict`] or the [`raw_iter`] method on [`Dict`].
688/// See their documentation for more.
689///
690/// [`Dict`]: crate::dict::Dict
691/// [`iter`]: RawDict::iter
692/// [`raw_iter`]: crate::dict::Dict::raw_iter
693#[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    /// Creates an iterator over the entries of a dictionary.
704    pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
705        Self::new_ext(root, bit_len, false, false)
706    }
707
708    /// Creates an iterator over the entries of a dictionary with explicit
709    /// direction and behavior.
710    pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
711        let mut segments = Vec::new();
712
713        // Push root segment if any
714        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    /// Changes the direction of the iterator to descending.
742    #[inline]
743    pub fn reversed(mut self) -> Self {
744        self.reversed = true;
745        self
746    }
747
748    /// Changes the behavior of the iterator to reverse the high bit.
749    #[inline]
750    pub fn signed(mut self) -> Self {
751        self.signed = true;
752        self
753    }
754
755    /// Returns whether the iterator direction was reversed.
756    #[inline]
757    pub fn is_reversed(&self) -> bool {
758        self.reversed
759    }
760
761    /// Returns whether the iterator treats keys as signed integers.
762    #[inline]
763    pub fn is_signed(&self) -> bool {
764        self.signed
765    }
766
767    /// Advances the iterator and returns the next value as owned cell slice parts.
768    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                    // Handle root case
842                    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                        // Found the latest unprocessed slice
849                        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                        // SAFETY: we have just added a new element
865                        break unsafe { segments.last_mut().unwrap_unchecked() };
866                    } else {
867                        // Rewind prefix
868                        to_rewind += prefix.size_bits();
869                        // Pop processed segments
870                        segments.pop();
871                        // Rewind reference bit (if any)
872                        to_rewind += !segments.is_empty() as u16;
873                    }
874                };
875
876                // Read the next key part from the latest segment
877                let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
878
879                // Check remaining bits
880                return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
881                    // Return value if there are no remaining bits to read
882                    Some(0) => {
883                        // Try to store the last prefix into the result key
884                        let mut key = builder.clone();
885                        ok!(key.store_slice_data(prefix));
886
887                        let data = segment.data;
888
889                        // Pop the current segment from the stack
890                        segments.pop();
891                        ok!(builder.rewind_bits(!segments.is_empty() as u16));
892
893                        Ok(Some((key, data)))
894                    }
895                    // Append prefix to builder and proceed to the next segment
896                    Some(remaining) => {
897                        if segment.data.size_refs() < 2 {
898                            return Err(Error::CellUnderflow);
899                        }
900
901                        // Try to store the next prefix into the buffer
902                        ok!(builder.store_slice_data(prefix));
903
904                        // Update segment prefix
905                        segment.prefix = Some(prefix);
906                        segment.remaining_bit_len = remaining - 1;
907
908                        // Handle next segment
909                        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/// An iterator over the entries across two [`RawDict`] or two [`Dict`].
936///
937/// This struct is created by the [`iter_union`] method on [`RawDict`]
938/// or the [`raw_iter_union`] method on [`Dict`].
939///
940/// [`Dict`]: crate::dict::Dict
941/// [`iter_union`]: RawDict::iter_union
942/// [`raw_iter_union`]: crate::dict::Dict::raw_iter_union
943#[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    /// Creates an iterator over the entries of dictionaries.
955    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    /// Creates an iterator over the entries of dictionaries
960    ///  with explicit direction and behavior.
961    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    /// Changes the direction of the iterator to descending.
979    #[inline]
980    pub fn reversed(mut self) -> Self {
981        self.left.reversed = true;
982        self.right.reversed = true;
983        self
984    }
985
986    /// Changes the behavior of the iterator to reverse the high bit.
987    #[inline]
988    pub fn signed(mut self) -> Self {
989        self.left.signed = true;
990        self.right.signed = true;
991        self
992    }
993
994    /// Returns whether the iterator direction was reversed.
995    #[inline]
996    pub fn is_reversed(&self) -> bool {
997        self.left.reversed
998    }
999
1000    /// Returns whether the iterator treats keys as signed integers.
1001    #[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/// An iterator over the keys of a [`RawDict`] or a [`Dict`].
1136///
1137/// This struct is created by the [`keys`] method on [`RawDict`] or the [`raw_keys`] method on [`Dict`].
1138/// See their documentation for more.
1139///
1140/// [`Dict`]: crate::dict::Dict
1141/// [`keys`]: RawDict::keys
1142/// [`raw_keys`]: crate::dict::Dict::raw_keys
1143#[derive(Clone)]
1144pub struct RawKeys<'a> {
1145    inner: RawIter<'a>,
1146}
1147
1148impl<'a> RawKeys<'a> {
1149    /// Creates an iterator over the keys of a dictionary.
1150    pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1151        Self {
1152            inner: RawIter::new(root, bit_len),
1153        }
1154    }
1155
1156    /// Creates an iterator over the keys of a dictionary with explicit
1157    /// direction and behavior.
1158    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    /// Changes the direction of the iterator to descending.
1165    #[inline]
1166    pub fn reversed(mut self) -> Self {
1167        self.inner.reversed = true;
1168        self
1169    }
1170
1171    /// Changes the behavior of the iterator to reverse the high bit.
1172    #[inline]
1173    pub fn signed(mut self) -> Self {
1174        self.inner.signed = true;
1175        self
1176    }
1177
1178    /// Returns whether the iterator direction was reversed.
1179    #[inline]
1180    pub fn is_reversed(&self) -> bool {
1181        self.inner.reversed
1182    }
1183
1184    /// Returns whether the iterator treats keys as signed integers.
1185    #[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/// An iterator over the owned values of a [`RawDict`].
1203///
1204/// This struct is created by the [`values_owned`] method on [`RawDict`].
1205/// See its documentation for more.
1206///
1207/// [`values_owned`]: RawDict::values_owned
1208#[derive(Clone)]
1209pub struct RawOwnedValues<'a> {
1210    root: &'a Option<Cell>,
1211    inner: RawValues<'a>,
1212}
1213
1214impl<'a> RawOwnedValues<'a> {
1215    /// Creates an iterator over the owned entries of a dictionary.
1216    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    /// Creates an iterator over the values of a dictionary with explicit
1224    /// direction and behavior.
1225    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    /// Changes the direction of the iterator to descending.
1233    #[inline]
1234    pub fn reversed(mut self) -> Self {
1235        self.inner.reversed = true;
1236        self
1237    }
1238
1239    /// Changes the behavior of the iterator to reverse the high bit.
1240    #[inline]
1241    pub fn signed(mut self) -> Self {
1242        self.inner.signed = true;
1243        self
1244    }
1245
1246    /// Returns whether the iterator direction was reversed.
1247    #[inline]
1248    pub fn is_reversed(&self) -> bool {
1249        self.inner.reversed
1250    }
1251
1252    /// Returns whether the iterator treats keys as signed integers.
1253    #[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/// An iterator over the values of a [`RawDict`] or a [`Dict`].
1290///
1291/// This struct is created by the [`values`] method on [`RawDict`] or the [`raw_values`] method on [`Dict`].
1292/// See their documentation for more.
1293///
1294/// [`Dict`]: crate::dict::Dict
1295/// [`values`]: RawDict::values
1296/// [`raw_values`]: crate::dict::Dict::raw_values
1297#[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    /// Creates an iterator over the values of a dictionary.
1307    pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1308        Self::new_ext(root, bit_len, false, false)
1309    }
1310
1311    /// Creates an iterator over the values of a dictionary with explicit
1312    /// direction and behavior.
1313    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    /// Changes the direction of the iterator to descending.
1339    #[inline]
1340    pub fn reversed(mut self) -> Self {
1341        self.reversed = true;
1342        self
1343    }
1344
1345    /// Changes the behavior of the iterator to reverse the high bit.
1346    #[inline]
1347    pub fn signed(mut self) -> Self {
1348        self.signed = true;
1349        self
1350    }
1351
1352    /// Returns whether the iterator direction was reversed.
1353    #[inline]
1354    pub fn is_reversed(&self) -> bool {
1355        self.reversed
1356    }
1357
1358    /// Returns whether the iterator treats keys as signed integers.
1359    #[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                // Find the latest slice which has not been loaded yet
1392                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                        // Found the latest unprocessed slice
1405                        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                        // SAFETY: we have just added a new element
1417                        break unsafe { segments.last_mut().unwrap_unchecked() };
1418                    } else {
1419                        segments.pop();
1420                    }
1421                };
1422
1423                // Read the next key part from the latest segment
1424                let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
1425
1426                // Check remaining bits
1427                return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
1428                    // Return value if there are no remaining bits to read
1429                    Some(0) => {
1430                        let data = segment.data;
1431                        // Pop the current segment from the stack
1432                        segments.pop();
1433                        Ok(Some(data))
1434                    }
1435                    // Append prefix to builder and proceed to the next segment
1436                    Some(remaining) => {
1437                        if segment.data.size_refs() < 2 {
1438                            return Err(Error::CellUnderflow);
1439                        }
1440                        segment.remaining_bit_len = remaining - 1;
1441                        // Handle next segment
1442                        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)] // takes too long to execute on miri
1502    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        //
1528        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        //
1537        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        //
1559        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        //
1565        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 = i % 2;
1656            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        // println!("BOC: {}", boc.display_tree());
1686
1687        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        // Fill
1772        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        // Unsigned
1796        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        // Unsigned reversed
1810        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        // Signed
1824        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        // Signed reversed
1838        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        // Prepare dict
1907        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        // First get
1915        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        // Second get
1928        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        // Prepare dict
1948        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        // First get
1956        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        // Second get
1969        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        // Noop remove
1996        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        // Clear dict
2005        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        // Unsigned MIN
2070        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        // Unsigned MAX
2103        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        // Signed MIN and MAX
2136        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        // NOTE: same gas for balanced tree
2168        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        // RawDict
2190        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        // Compare `dict_insert` and `dict_insert_owned`
2205        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        // Check `add` as noop
2242        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); // Equivalent to simple get
2255
2256        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); // Equivalent to simple get
2268
2269        Ok(())
2270    }
2271}