everscale_types/dict/
raw.rs

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