1use std::ops::ControlFlow;
4
5pub use self::aug::*;
6pub use self::ops::*;
7pub use self::raw::*;
8pub use self::typed::*;
9
10use crate::cell::*;
11use crate::error::Error;
12
13mod aug;
14mod raw;
15mod typed;
16
17mod ops {
18 pub use self::build::{build_aug_dict_from_sorted_iter, build_dict_from_sorted_iter};
19 pub use self::find::{
20 aug_dict_find_by_extra, dict_find_bound, dict_find_bound_owned, dict_find_owned,
21 };
22 pub use self::get::{dict_get, dict_get_owned, dict_get_subdict};
23 pub use self::insert::{aug_dict_insert, dict_insert, dict_insert_owned};
24 pub use self::remove::{aug_dict_remove_owned, dict_remove_bound_owned, dict_remove_owned};
25 pub use self::split_merge::{dict_merge, dict_split_by_prefix};
26
27 mod build;
28 mod find;
29 mod get;
30 mod insert;
31 mod remove;
32 mod split_merge;
33}
34
35pub trait DictKey: Sized {
37 const BITS: u16;
39
40 fn from_raw_data(raw_data: &[u8; 128]) -> Option<Self>;
42}
43
44macro_rules! impl_dict_key {
45 ($($ty:ty => $bits:literal => |$raw_data:ident| $expr:expr),*,) => {
46 $(impl DictKey for $ty {
47 const BITS: u16 = $bits;
48
49 #[inline]
50 fn from_raw_data($raw_data: &[u8; 128]) -> Option<Self> {
51 Some($expr)
52 }
53 })*
54 };
55}
56
57impl_dict_key! {
58 bool => 1 => |d| d[0] & 0x80 != 0,
59 u8 => 8 => |d| d[0],
60 i8 => 8 => |d| d[0] as i8,
61 u16 => 16 => |d| u16::from_be_bytes([d[0], d[1]]),
62 i16 => 16 => |d| i16::from_be_bytes([d[0], d[1]]),
63 u32 => 32 => |d| u32::from_be_bytes(d[..4].try_into().unwrap()),
64 i32 => 32 => |d| i32::from_be_bytes(d[..4].try_into().unwrap()),
65 u64 => 64 => |d| u64::from_be_bytes(d[..8].try_into().unwrap()),
66 i64 => 64 => |d| i64::from_be_bytes(d[..8].try_into().unwrap()),
67 u128 => 128 => |d| u128::from_be_bytes(d[..16].try_into().unwrap()),
68 i128 => 128 => |d| i128::from_be_bytes(d[..16].try_into().unwrap()),
69 [u8; 16] => 128 => |d| d[..16].try_into().unwrap(),
70 [u8; 20] => 160 => |d| d[..20].try_into().unwrap(),
71 [u8; 32] => 256 => |d| d[..32].try_into().unwrap(),
72 HashBytes => 256 => |d| HashBytes(d[..32].try_into().unwrap()),
73 (u64, u32) => 96 => |d| {
74 (u64::from_be_bytes(d[..8].try_into().unwrap()), u32::from_be_bytes(d[8..12].try_into().unwrap()))
75 },
76}
77
78pub trait SearchByExtra<A> {
80 fn on_leaf(&mut self, leaf_extra: &A) -> bool {
82 _ = leaf_extra;
83 true
84 }
85
86 fn on_edge(&mut self, left_extra: &A, right_extra: &A) -> ControlFlow<(), Branch>;
88}
89
90impl<A, T: SearchByExtra<A>> SearchByExtra<A> for &mut T {
91 #[inline]
92 fn on_leaf(&mut self, leaf_extra: &A) -> bool {
93 T::on_leaf(self, leaf_extra)
94 }
95
96 #[inline]
97 fn on_edge(&mut self, left_extra: &A, right_extra: &A) -> ControlFlow<(), Branch> {
98 T::on_edge(self, left_extra, right_extra)
99 }
100}
101
102impl<A> SearchByExtra<A> for Branch {
103 #[inline]
104 fn on_edge(&mut self, _: &A, _: &A) -> ControlFlow<(), Branch> {
105 ControlFlow::Continue(*self)
106 }
107}
108
109impl<A: Ord> SearchByExtra<A> for std::cmp::Ordering {
110 #[inline]
111 fn on_edge(&mut self, left_extra: &A, right_extra: &A) -> ControlFlow<(), Branch> {
112 ControlFlow::Continue(if *self == left_extra.cmp(right_extra) {
113 Branch::Left
114 } else {
115 Branch::Right
116 })
117 }
118}
119
120#[derive(Debug, Clone, Copy, Eq, PartialEq)]
122#[repr(u8)]
123pub enum SetMode {
124 Set = 0b11,
126 Replace = 0b01,
129 Add = 0b10,
132}
133
134impl SetMode {
135 #[inline]
137 pub const fn can_replace(self) -> bool {
138 self as u8 & 0b01 != 0
139 }
140
141 #[inline]
143 pub const fn can_add(self) -> bool {
144 self as u8 & 0b10 != 0
145 }
146}
147
148pub type AugDictFn =
156 fn(&mut CellSlice, &mut CellSlice, &mut CellBuilder, &mut dyn CellContext) -> Result<(), Error>;
157
158fn make_leaf(
160 key: &CellSlice,
161 key_bit_len: u16,
162 value: &dyn Store,
163 context: &mut dyn CellContext,
164) -> Result<Cell, Error> {
165 let mut builder = CellBuilder::new();
166 ok!(write_label(key, key_bit_len, &mut builder));
167 ok!(value.store_into(&mut builder, context));
168 builder.build_ext(context)
169}
170
171fn make_leaf_with_extra(
173 key: &CellSlice,
174 key_bit_len: u16,
175 extra: &dyn Store,
176 value: &dyn Store,
177 context: &mut dyn CellContext,
178) -> Result<Cell, Error> {
179 let mut builder = CellBuilder::new();
180 ok!(write_label(key, key_bit_len, &mut builder));
181 ok!(extra.store_into(&mut builder, context));
182 ok!(value.store_into(&mut builder, context));
183 builder.build_ext(context)
184}
185
186fn split_edge(
188 data: &CellSlice,
189 prefix: &mut CellSlice,
190 lcp: &CellSlice,
191 key: &mut CellSlice,
192 value: &dyn Store,
193 context: &mut dyn CellContext,
194) -> Result<Cell, Error> {
195 let prev_key_bit_len = key.size_bits();
197 ok!(key.skip_first(lcp.size_bits() + 1, 0));
198
199 prefix.skip_first(lcp.size_bits(), 0).ok();
201 let old_to_right = ok!(prefix.load_bit());
202
203 let mut left = ok!(make_leaf(prefix, key.size_bits(), data, context));
205 let mut right = ok!(make_leaf(key, key.size_bits(), value, context));
207
208 if old_to_right {
210 std::mem::swap(&mut left, &mut right);
211 }
212
213 let mut builder = CellBuilder::new();
215 ok!(write_label(lcp, prev_key_bit_len, &mut builder));
216 ok!(builder.store_reference(left));
217 ok!(builder.store_reference(right));
218 builder.build_ext(context)
219}
220
221#[allow(clippy::too_many_arguments)]
222fn split_aug_edge(
223 data: &mut CellSlice,
224 prefix: &mut CellSlice,
225 lcp: &CellSlice,
226 key: &mut CellSlice,
227 extra: &dyn Store,
228 value: &dyn Store,
229 comparator: AugDictFn,
230 context: &mut dyn CellContext,
231) -> Result<Cell, Error> {
232 let prev_key_bit_len = key.size_bits();
234 ok!(key.skip_first(lcp.size_bits() + 1, 0));
235
236 prefix.skip_first(lcp.size_bits(), 0).ok();
238 let old_to_right = ok!(prefix.load_bit());
239
240 let mut left = ok!(make_leaf(prefix, key.size_bits(), data, context));
242 let mut right = ok!(make_leaf_with_extra(
244 key,
245 key.size_bits(),
246 extra,
247 value,
248 context
249 ));
250 if old_to_right {
252 std::mem::swap(&mut left, &mut right);
253 }
254
255 let left_slice = &mut ok!(left.as_slice());
256 let right_slice = &mut ok!(right.as_slice());
257 ok!(read_label(left_slice, key.size_bits()));
258 ok!(read_label(right_slice, key.size_bits()));
259
260 let mut builder = CellBuilder::new();
262 ok!(write_label(lcp, prev_key_bit_len, &mut builder));
263 ok!(builder.store_reference(left.clone()));
264 ok!(builder.store_reference(right.clone()));
265 ok!(comparator(left_slice, right_slice, &mut builder, context));
266 builder.build_ext(context)
267}
268
269pub type DictOwnedEntry = (CellBuilder, CellSliceParts);
271
272#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
274pub enum DictBound {
275 Min,
277 Max,
279}
280
281impl DictBound {
282 fn update_direction(
283 self,
284 prefix: &CellSlice<'_>,
285 signed: bool,
286 direction: &mut Option<Branch>,
287 ) -> Branch {
288 match direction {
289 None => {
291 let mut branch = *direction.insert(self.into_branch());
292 if signed && prefix.is_data_empty() {
294 branch = branch.reversed();
295 }
296 branch
297 }
298 Some(direction) => *direction,
300 }
301 }
302
303 fn into_branch(self) -> Branch {
304 match self {
305 Self::Min => Branch::Left,
306 Self::Max => Branch::Right,
307 }
308 }
309}
310
311pub fn dict_load_from_root(
313 slice: &mut CellSlice<'_>,
314 key_bit_len: u16,
315 context: &mut dyn CellContext,
316) -> Result<Cell, Error> {
317 let mut root = *slice;
318
319 let label = ok!(read_label(slice, key_bit_len));
320 if label.size_bits() != key_bit_len {
321 ok!(slice.skip_first(0, 2));
322 let root_bits = root.size_bits() - slice.size_bits();
323 let root_refs = root.size_refs() - slice.size_refs();
324 root = root.get_prefix(root_bits, root_refs)
325 } else {
326 slice.load_remaining();
327 }
328
329 let mut builder = CellBuilder::new();
330 ok!(builder.store_slice(root));
331 builder.build_ext(context)
332}
333
334fn rebuild_dict_from_stack(
335 mut segments: Vec<Segment<'_>>,
336 mut leaf: Cell,
337 context: &mut dyn CellContext,
338) -> Result<Cell, Error> {
339 while let Some(last) = segments.pop() {
341 let (left, right) = match last.next_branch {
343 Branch::Left => match last.data.reference_cloned(1) {
344 Some(cell) => (leaf, cell),
345 None => return Err(Error::CellUnderflow),
346 },
347 Branch::Right => match last.data.reference_cloned(0) {
348 Some(cell) => (cell, leaf),
349 None => return Err(Error::CellUnderflow),
350 },
351 };
352
353 let mut builder = CellBuilder::new();
354 ok!(builder.store_cell_data(last.data));
355 ok!(builder.store_reference(left));
356 ok!(builder.store_reference(right));
357 leaf = ok!(builder.build_ext(context));
358 }
359
360 Ok(leaf)
361}
362
363fn rebuild_aug_dict_from_stack(
364 mut segments: Vec<Segment<'_>>,
365 mut leaf: Cell,
366 comparator: AugDictFn,
367 context: &mut dyn CellContext,
368) -> Result<Cell, Error> {
369 while let Some(last) = segments.pop() {
371 let (left, right) = match last.next_branch {
373 Branch::Left => match last.data.reference_cloned(1) {
374 Some(cell) => (leaf, cell),
375 None => return Err(Error::CellUnderflow),
376 },
377 Branch::Right => match last.data.reference_cloned(0) {
378 Some(cell) => (cell, leaf),
379 None => return Err(Error::CellUnderflow),
380 },
381 };
382
383 let last_data_slice = ok!(last.data.as_slice());
384 let last_label = ok!(read_label(&mut last_data_slice.clone(), last.key_bit_len));
385
386 let child_key_bit_len = last.key_bit_len - last_label.size_bits() - 1;
387
388 let left_slice = &mut left.as_slice()?;
389 let right_slice = &mut right.as_slice()?;
390 ok!(read_label(left_slice, child_key_bit_len));
391 ok!(read_label(right_slice, child_key_bit_len));
392
393 let mut builder = CellBuilder::new();
394 ok!(write_label(&last_label, last.key_bit_len, &mut builder));
395 ok!(builder.store_reference(left.clone()));
396 ok!(builder.store_reference(right.clone()));
397 ok!(comparator(left_slice, right_slice, &mut builder, context));
398 leaf = ok!(builder.build_ext(context));
399 }
400
401 Ok(leaf)
402}
403
404#[derive(Clone, Copy)]
405struct Segment<'a> {
406 data: &'a DynCell,
407 next_branch: Branch,
408 key_bit_len: u16,
409}
410
411impl Segment<'_> {
412 fn rebuild_as_removed(
414 self,
415 key: &CellSlice<'_>,
416 prev_key_bit_len: u16,
417 context: &mut dyn CellContext,
418 ) -> Result<(Cell, Cell), Error> {
419 let index = self.next_branch as u8;
420
421 let Some(value) = self.data.reference_cloned(index) else {
423 return Err(Error::CellUnderflow);
424 };
425 let value = ok!(context.load_cell(value, LoadMode::Resolve));
428
429 let pfx = {
431 let mut parent = unsafe { self.data.as_slice_unchecked() };
433 ok!(read_label(&mut parent, prev_key_bit_len))
434 };
435
436 let mut opposite = match self.data.reference(1 - index) {
438 Some(cell) => ok!(context
440 .load_dyn_cell(cell, LoadMode::Full)
441 .and_then(CellSlice::new)),
442 None => return Err(Error::CellUnderflow),
443 };
444 let rem = ok!(read_label(&mut opposite, key.size_bits()));
445
446 let mut builder = CellBuilder::new();
448 ok!(write_label_parts(
449 &pfx,
450 index == 0,
451 &rem,
452 prev_key_bit_len,
453 &mut builder
454 ));
455 ok!(builder.store_slice(opposite));
456 let leaf = ok!(builder.build_ext(context));
457
458 Ok((leaf, value))
459 }
460}
461
462fn write_label(key: &CellSlice, key_bit_len: u16, label: &mut CellBuilder) -> Result<(), Error> {
463 if key_bit_len == 0 || key.is_data_empty() {
464 return write_hml_empty(label);
465 }
466
467 let bits_for_len = (16 - key_bit_len.leading_zeros()) as u16;
468
469 let remaining_bits = key.size_bits();
470
471 let hml_short_len = 2 + 2 * remaining_bits;
472 let hml_long_len = 2 + bits_for_len + remaining_bits;
473 let hml_same_len = 3 + bits_for_len;
474
475 if hml_same_len < hml_long_len && hml_same_len < hml_short_len {
476 if let Some(bit) = key.test_uniform() {
477 ok!(write_hml_same(bit, remaining_bits, bits_for_len, label));
478 return Ok(());
479 }
480 }
481
482 if hml_short_len <= MAX_BIT_LEN && hml_short_len <= hml_long_len {
483 ok!(write_hml_short_tag(remaining_bits, label));
484 } else if hml_long_len <= MAX_BIT_LEN {
485 ok!(write_hml_long_tag(remaining_bits, bits_for_len, label));
486 } else {
487 return Err(Error::InvalidData);
488 }
489
490 ok!(label.store_slice_data(key));
491 Ok(())
492}
493
494fn write_label_parts(
495 pfx: &CellSlice,
496 bit: bool,
497 rem: &CellSlice,
498 key_bit_len: u16,
499 label: &mut CellBuilder,
500) -> Result<(), Error> {
501 if key_bit_len == 0 {
502 return write_hml_empty(label);
503 }
504
505 let bits_for_len = (16 - key_bit_len.leading_zeros()) as u16;
506
507 let remaining_bits = pfx.size_bits() + 1 + rem.size_bits();
508
509 let hml_short_len = 2 + 2 * remaining_bits;
510 let hml_long_len = 2 + bits_for_len + remaining_bits;
511 let hml_same_len = 3 + bits_for_len;
512
513 if hml_same_len < hml_long_len
514 && hml_same_len < hml_short_len
515 && (pfx.is_data_empty() || matches!(pfx.test_uniform(), Some(p) if p == bit))
516 && (rem.is_data_empty() || matches!(rem.test_uniform(), Some(r) if r == bit))
517 {
518 return write_hml_same(bit, remaining_bits, bits_for_len, label);
519 }
520
521 if hml_short_len <= MAX_BIT_LEN && hml_short_len <= hml_long_len {
522 ok!(write_hml_short_tag(remaining_bits, label));
523 } else if hml_long_len <= MAX_BIT_LEN {
524 ok!(write_hml_long_tag(remaining_bits, bits_for_len, label));
525 } else {
526 return Err(Error::InvalidData);
527 }
528 ok!(label.store_slice_data(pfx));
529 ok!(label.store_bit(bit));
530 label.store_slice_data(rem)
531}
532
533fn read_label<'a>(label: &mut CellSlice<'a>, key_bit_len: u16) -> Result<CellSlice<'a>, Error> {
534 let bits_for_len = (16 - key_bit_len.leading_zeros()) as u16;
535
536 if bits_for_len == 0 && label.is_data_empty() {
537 Ok(label.get_prefix(0, 0))
538 } else if !ok!(label.load_bit()) {
539 read_hml_short(label)
540 } else if !ok!(label.load_bit()) {
541 read_hml_long(label, bits_for_len)
542 } else {
543 read_hml_same(label, bits_for_len)
544 }
545}
546
547fn write_hml_empty(label: &mut CellBuilder) -> Result<(), Error> {
548 label.store_zeros(2)
549}
550
551fn write_hml_short_tag(len: u16, label: &mut CellBuilder) -> Result<(), Error> {
552 ok!(label.store_bit_zero());
553
554 for _ in 0..len / 32 {
555 ok!(label.store_u32(u32::MAX));
556 }
557
558 let rem = len % 32;
559 if rem != 0 {
560 ok!(label.store_uint(u64::MAX, rem));
561 }
562 label.store_bit_zero()
563}
564
565fn read_hml_short<'a>(label: &mut CellSlice<'a>) -> Result<CellSlice<'a>, Error> {
566 let mut len = 0;
567 while ok!(label.load_bit()) {
568 len += 1;
569 }
570 let result = *label;
571 ok!(label.skip_first(len, 0));
572 Ok(result.get_prefix(len, 0))
573}
574
575fn write_hml_long_tag(len: u16, bits_for_len: u16, label: &mut CellBuilder) -> Result<(), Error> {
576 ok!(label.store_bit_one());
577 ok!(label.store_bit_zero());
578 label.store_uint(len as u64, bits_for_len)
579}
580
581fn read_hml_long<'a>(label: &mut CellSlice<'a>, bits_for_len: u16) -> Result<CellSlice<'a>, Error> {
582 let len = ok!(label.load_uint(bits_for_len)) as u16;
583 let result = *label;
584 ok!(label.skip_first(len, 0));
585 Ok(result.get_prefix(len, 0))
586}
587
588fn write_hml_same(
589 bit: bool,
590 len: u16,
591 bits_for_len: u16,
592 label: &mut CellBuilder,
593) -> Result<(), Error> {
594 ok!(label.store_small_uint(0b110 | bit as u8, 3));
595 label.store_uint(len as u64, bits_for_len)
596}
597
598fn read_hml_same<'a>(label: &mut CellSlice<'a>, bits_for_len: u16) -> Result<CellSlice<'a>, Error> {
599 let cell = match ok!(label.load_bit()) {
600 false => Cell::all_zeros_ref(),
601 true => Cell::all_ones_ref(),
602 };
603 let len = ok!(label.load_uint(bits_for_len)) as u16;
604
605 let slice = unsafe { cell.as_slice_unchecked() };
607 Ok(slice.get_prefix(len, 0))
608}
609
610#[derive(Debug, Clone, Copy, Eq, PartialEq)]
612pub enum Branch {
613 Left = 0,
615 Right = 1,
617}
618
619impl Branch {
620 pub fn into_bit(self) -> bool {
622 self == Self::Right
623 }
624
625 pub fn reversed(self) -> Self {
627 match self {
628 Self::Left => Self::Right,
629 Self::Right => Self::Left,
630 }
631 }
632}
633
634impl From<bool> for Branch {
635 fn from(value: bool) -> Self {
636 if value {
637 Self::Right
638 } else {
639 Self::Left
640 }
641 }
642}
643
644#[cfg(test)]
645mod tests {
646 use super::*;
647
648 fn build_cell<F: FnOnce(&mut CellBuilder) -> Result<(), Error>>(f: F) -> Cell {
649 let mut builder = CellBuilder::new();
650 f(&mut builder).unwrap();
651 builder.build().unwrap()
652 }
653
654 #[test]
655 fn labels() -> anyhow::Result<()> {
656 let key_bit_len = 6;
657
658 let key = {
660 let mut builder = CellBuilder::new();
661 builder.store_zeros(5)?;
662 builder.store_bit_one()?;
663 builder.build()?
664 };
665
666 let label = {
668 let mut builder = CellBuilder::new();
669 write_label(&key.as_slice()?, key_bit_len, &mut builder)?;
670 builder.build().unwrap()
671 };
672
673 let parsed_key = read_label(&mut label.as_slice()?, key_bit_len)?;
675 let parsed_key = {
676 let mut builder = CellBuilder::new();
677 builder.store_slice(parsed_key)?;
678 builder.build()?
679 };
680
681 assert_eq!(key.as_ref(), parsed_key.as_ref());
683
684 let label = CellBuilder::from_raw_data(&[0xcc, 0x40], 9)
685 .unwrap()
686 .build()
687 .unwrap();
688 let prefix = read_label(&mut label.as_slice()?, 32).unwrap();
689
690 println!("{}", build_cell(|b| b.store_slice(prefix)).display_tree());
691 assert_eq!(prefix.test_uniform(), Some(false));
692
693 Ok(())
694 }
695
696 #[test]
697 fn build_from_array() {
698 for entries in [
699 &[(0u32, 1u32), (1, 2), (2, 4), (2, 3), (3, 4), (4, 5)][..],
700 &[
701 (534837844, 3117028142),
702 (1421713188, 3155891450),
703 (1526242096, 2789399854),
704 (1971086295, 1228713494),
705 (4258889371, 3256452222),
706 ],
707 ] {
708 let result = build_dict_from_sorted_iter(
709 entries.iter().copied(),
710 32,
711 &mut Cell::empty_context(),
712 )
713 .unwrap();
714
715 let mut dict = Dict::<u32, u32>::new();
716 for (k, v) in entries {
717 dict.add(k, v).unwrap();
718 }
719
720 println!("{}", result.as_ref().unwrap().display_tree());
721 println!(
722 "BOC: {}",
723 crate::boc::BocRepr::encode_base64(&result).unwrap()
724 );
725
726 assert_eq!(result, dict.root);
727 }
728 }
729
730 #[test]
731 fn build_from_any_array() {
732 for _ in 0..100 {
733 let n = 1 + rand::random::<usize>() % 1000;
734 let mut entries = (0..n)
735 .map(|_| (rand::random::<u32>(), rand::random::<u32>()))
736 .collect::<Vec<_>>();
737 entries.sort_by_key(|(k, _)| *k);
738
739 let built_from_dict = build_dict_from_sorted_iter(
740 entries.iter().copied(),
741 32,
742 &mut Cell::empty_context(),
743 )
744 .unwrap();
745
746 let mut dict = Dict::<u32, u32>::new();
747 for (k, v) in entries {
748 dict.add(k, v).unwrap();
749 }
750
751 assert_eq!(built_from_dict, dict.root);
754 }
755 }
756}