loro_internal/state/
tree_state.rs

1use either::Either;
2use enum_as_inner::EnumAsInner;
3use fractional_index::FractionalIndex;
4use itertools::Itertools;
5use loro_common::{
6    ContainerID, IdFull, IdLp, LoroError, LoroResult, LoroTreeError, LoroValue, PeerID, TreeID,
7    DELETED_TREE_ROOT, ID,
8};
9use rand::SeedableRng;
10use rustc_hash::{FxHashMap, FxHashSet};
11use serde::Serialize;
12use std::collections::VecDeque;
13use std::fmt::Debug;
14use std::ops::{Deref, DerefMut};
15use std::sync::Weak;
16
17use super::{ApplyLocalOpReturn, ContainerState, DiffApplyContext};
18use crate::configure::Configure;
19use crate::container::idx::ContainerIdx;
20use crate::delta::{TreeDiff, TreeDiffItem, TreeExternalDiff};
21use crate::diff_calc::DiffMode;
22use crate::event::InternalDiff;
23use crate::op::Op;
24use crate::{
25    container::tree::tree_op::TreeOp,
26    delta::TreeInternalDiff,
27    event::{Diff, Index},
28    op::RawOp,
29};
30use crate::{DocState, LoroDocInner};
31
32#[derive(Clone, Debug, EnumAsInner)]
33pub enum TreeFractionalIndexConfigInner {
34    GenerateFractionalIndex {
35        jitter: u8,
36        rng: Box<rand::rngs::StdRng>,
37    },
38    MoveDisabled,
39}
40
41/// The state of movable tree.
42///
43/// using flat representation
44#[derive(Debug, Clone)]
45pub struct TreeState {
46    idx: ContainerIdx,
47    trees: FxHashMap<TreeID, TreeStateNode>,
48    children: TreeChildrenCache,
49    fractional_index_config: TreeFractionalIndexConfigInner,
50    peer_id: PeerID,
51}
52
53#[derive(Debug, Clone, PartialEq, Eq)]
54pub(crate) struct TreeStateNode {
55    pub parent: TreeParentId,
56    pub position: Option<FractionalIndex>,
57    pub last_move_op: IdFull,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
61pub(crate) struct NodePosition {
62    pub(crate) position: FractionalIndex,
63    // different nodes created by a peer may have the same position
64    // when we merge updates that cause cycles.
65    // for example [::fuzz::test::test_tree::same_peer_have_same_position()]
66    pub(crate) idlp: IdLp,
67}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumAsInner, Serialize)]
70pub enum TreeParentId {
71    Node(TreeID),
72    Root,
73    Deleted,
74    // We use `Unexist` as the old parent of a new node created
75    // so we can infer the retreat internal diff is `Uncreate`
76    Unexist,
77}
78
79impl From<Option<TreeID>> for TreeParentId {
80    fn from(id: Option<TreeID>) -> Self {
81        match id {
82            Some(id) => {
83                if TreeID::is_deleted_root(&id) {
84                    TreeParentId::Deleted
85                } else {
86                    TreeParentId::Node(id)
87                }
88            }
89            None => TreeParentId::Root,
90        }
91    }
92}
93
94impl From<TreeID> for TreeParentId {
95    fn from(id: TreeID) -> Self {
96        if TreeID::is_deleted_root(&id) {
97            TreeParentId::Deleted
98        } else {
99            TreeParentId::Node(id)
100        }
101    }
102}
103
104impl From<&TreeID> for TreeParentId {
105    fn from(id: &TreeID) -> Self {
106        if TreeID::is_deleted_root(id) {
107            TreeParentId::Deleted
108        } else {
109            TreeParentId::Node(*id)
110        }
111    }
112}
113
114impl TreeParentId {
115    pub fn tree_id(&self) -> Option<TreeID> {
116        match self {
117            TreeParentId::Node(id) => Some(*id),
118            TreeParentId::Root => None,
119            TreeParentId::Deleted => Some(DELETED_TREE_ROOT),
120            TreeParentId::Unexist => unreachable!(),
121        }
122    }
123}
124
125#[derive(Debug, Clone)]
126enum NodeChildren {
127    Vec(Vec<(NodePosition, TreeID)>),
128    BTree(btree::ChildTree),
129}
130
131impl Default for NodeChildren {
132    fn default() -> Self {
133        NodeChildren::Vec(vec![])
134    }
135}
136
137impl NodeChildren {
138    const MAX_SIZE_FOR_ARRAY: usize = 16;
139    fn get_index_by_child_id(&self, target: &TreeID) -> Option<usize> {
140        match self {
141            NodeChildren::Vec(v) => v.iter().position(|(_, id)| id == target),
142            NodeChildren::BTree(btree) => btree.id_to_index(target),
143        }
144    }
145
146    fn get_last_insert_index_by_position(
147        &self,
148        node_position: &NodePosition,
149    ) -> Result<usize, usize> {
150        match self {
151            NodeChildren::Vec(v) => v.binary_search_by_key(&node_position, |x| &x.0),
152            NodeChildren::BTree(btree) => btree.get_index_by_node_position(node_position),
153        }
154    }
155
156    fn get_node_position_at(&self, pos: usize) -> Option<&NodePosition> {
157        match self {
158            NodeChildren::Vec(v) => v.get(pos).map(|x| &x.0),
159            NodeChildren::BTree(btree) => btree.get_elem_at(pos).map(|x| x.pos.as_ref()),
160        }
161    }
162
163    fn get_elem_at(&self, pos: usize) -> Option<(&NodePosition, &TreeID)> {
164        match self {
165            NodeChildren::Vec(v) => v.get(pos).map(|x| (&x.0, &x.1)),
166            NodeChildren::BTree(btree) => btree.get_elem_at(pos).map(|x| (x.pos.as_ref(), &x.id)),
167        }
168    }
169
170    fn generate_fi_at(&self, pos: usize, target: &TreeID) -> FractionalIndexGenResult {
171        let mut reset_ids = vec![];
172        let mut left = None;
173        let mut next_right = None;
174        {
175            let mut right = None;
176            let children_num = self.len();
177            if children_num == 0 {
178                return FractionalIndexGenResult::Ok(FractionalIndex::default());
179            }
180
181            if pos > 0 {
182                left = self.get_node_position_at(pos - 1);
183            }
184            if pos < children_num {
185                right = self.get_elem_at(pos);
186            }
187
188            let left_fi = left.map(|x| &x.position);
189            // if left and right have the same fractional indexes, we need to scan further to
190            // find all the ids that need to be reset
191            if let Some(left_fi) = left_fi {
192                if Some(left_fi) == right.map(|x| &x.0.position) {
193                    // TODO: the min length between left and right
194                    reset_ids.push(*right.unwrap().1);
195                    for i in (pos + 1)..children_num {
196                        let this_position =
197                            self.get_node_position_at(i).map(|x| &x.position).unwrap();
198                        if this_position == left_fi {
199                            reset_ids.push(*self.get_elem_at(i).unwrap().1);
200                        } else {
201                            next_right = Some(this_position.clone());
202                            break;
203                        }
204                    }
205                }
206            }
207
208            if reset_ids.is_empty() {
209                return FractionalIndexGenResult::Ok(
210                    FractionalIndex::new(left.map(|x| &x.position), right.map(|x| &x.0.position))
211                        .unwrap(),
212                );
213            }
214        }
215        let positions = FractionalIndex::generate_n_evenly(
216            left.map(|x| &x.position),
217            next_right.as_ref(),
218            reset_ids.len() + 1,
219        )
220        .unwrap();
221        FractionalIndexGenResult::Rearrange(
222            Some(*target)
223                .into_iter()
224                .chain(reset_ids)
225                .zip(positions)
226                .collect(),
227        )
228    }
229
230    fn get_id_at(&self, pos: usize) -> Option<TreeID> {
231        match self {
232            NodeChildren::Vec(v) => v.get(pos).map(|x| x.1),
233            NodeChildren::BTree(btree) => btree.get_elem_at(pos).map(|x| x.id),
234        }
235    }
236
237    fn delete_child(&mut self, target: &TreeID) {
238        match self {
239            NodeChildren::Vec(v) => {
240                v.retain(|(_, id)| id != target);
241            }
242            NodeChildren::BTree(v) => {
243                v.delete_child(target);
244            }
245        }
246    }
247
248    fn upgrade(&mut self) {
249        match self {
250            NodeChildren::Vec(v) => {
251                let mut btree = btree::ChildTree::new();
252                for (pos, id) in v.drain(..) {
253                    btree.insert_child(pos, id);
254                }
255
256                *self = NodeChildren::BTree(btree);
257            }
258            NodeChildren::BTree(_) => unreachable!(),
259        }
260    }
261
262    fn insert_child(&mut self, pos: NodePosition, id: TreeID) {
263        match self {
264            NodeChildren::Vec(v) => {
265                if v.len() >= Self::MAX_SIZE_FOR_ARRAY {
266                    self.upgrade();
267                    return self.insert_child(pos, id);
268                }
269
270                let r = v.binary_search_by(|(target, _)| target.cmp(&pos));
271                match r {
272                    Ok(_) => unreachable!(),
273                    Err(i) => {
274                        v.insert(i, (pos, id));
275                    }
276                }
277            }
278            NodeChildren::BTree(v) => {
279                v.insert_child(pos, id);
280            }
281        }
282    }
283
284    fn push_child_in_order(&mut self, pos: NodePosition, id: TreeID) {
285        match self {
286            NodeChildren::Vec(v) => {
287                if v.len() >= Self::MAX_SIZE_FOR_ARRAY {
288                    self.upgrade();
289                    return self.push_child_in_order(pos, id);
290                }
291
292                if let Some(last) = v.last() {
293                    assert!(last.0 < pos);
294                }
295                v.push((pos, id));
296            }
297            NodeChildren::BTree(v) => {
298                v.push_child_in_order(pos, id);
299            }
300        }
301    }
302
303    fn len(&self) -> usize {
304        match self {
305            NodeChildren::Vec(v) => v.len(),
306            NodeChildren::BTree(v) => v.len(),
307        }
308    }
309
310    fn has_child(&self, node_position: &NodePosition) -> bool {
311        match self {
312            NodeChildren::Vec(v) => v
313                .binary_search_by(|(target, _)| target.cmp(node_position))
314                .is_ok(),
315            NodeChildren::BTree(v) => v.has_child(node_position),
316        }
317    }
318
319    fn iter(&self) -> impl Iterator<Item = (&NodePosition, &TreeID)> {
320        match self {
321            NodeChildren::Vec(v) => Either::Left(v.iter().map(|x| (&x.0, &x.1))),
322            NodeChildren::BTree(t) => Either::Right(t.iter()),
323        }
324    }
325}
326
327#[derive(Clone, Default)]
328struct TreeChildrenCache(FxHashMap<TreeParentId, NodeChildren>);
329
330mod btree {
331    use std::{cmp::Ordering, ops::Range, sync::Arc};
332
333    use generic_btree::{
334        rle::{CanRemove, HasLength, Mergeable, Sliceable, TryInsert},
335        BTree, BTreeTrait, Cursor, FindResult, LeafIndex, LengthFinder, Query, UseLengthFinder,
336    };
337    use loro_common::TreeID;
338    use rustc_hash::FxHashMap;
339
340    use super::NodePosition;
341
342    struct ChildTreeTrait;
343    #[derive(Debug, Clone)]
344    pub(super) struct ChildTree {
345        tree: BTree<ChildTreeTrait>,
346        id_to_leaf_index: FxHashMap<TreeID, LeafIndex>,
347    }
348
349    impl ChildTree {
350        pub(super) fn new() -> Self {
351            Self {
352                tree: BTree::new(),
353                id_to_leaf_index: FxHashMap::default(),
354            }
355        }
356
357        pub(super) fn insert_child(&mut self, pos: NodePosition, id: TreeID) {
358            let (c, _) = self.tree.insert::<KeyQuery>(
359                &pos,
360                Elem {
361                    pos: Arc::new(pos.clone()),
362                    id,
363                },
364            );
365
366            self.id_to_leaf_index.insert(id, c.leaf);
367        }
368
369        pub(super) fn push_child_in_order(&mut self, pos: NodePosition, id: TreeID) {
370            let c = self.tree.push(Elem {
371                pos: Arc::new(pos.clone()),
372                id,
373            });
374            self.id_to_leaf_index.insert(id, c.leaf);
375        }
376
377        pub(super) fn delete_child(&mut self, id: &TreeID) {
378            if let Some(leaf) = self.id_to_leaf_index.remove(id) {
379                self.tree.remove_leaf(Cursor { leaf, offset: 0 });
380            }
381        }
382
383        pub(super) fn has_child(&self, pos: &NodePosition) -> bool {
384            match self.tree.query::<KeyQuery>(pos) {
385                Some(r) => r.found,
386                None => false,
387            }
388        }
389
390        pub(super) fn iter(&self) -> impl Iterator<Item = (&NodePosition, &TreeID)> {
391            self.tree.iter().map(|x| (&*x.pos, &x.id))
392        }
393
394        pub(super) fn len(&self) -> usize {
395            self.tree.root_cache().len
396        }
397
398        pub(super) fn get_elem_at(&self, pos: usize) -> Option<&Elem> {
399            let result = self.tree.query::<LengthFinder>(&pos)?;
400            if !result.found {
401                return None;
402            }
403            self.tree.get_elem(result.leaf())
404        }
405
406        pub(super) fn id_to_index(&self, id: &TreeID) -> Option<usize> {
407            let leaf_index = self.id_to_leaf_index.get(id)?;
408            let mut ans = 0;
409            self.tree.visit_previous_caches(
410                Cursor {
411                    leaf: *leaf_index,
412                    offset: 0,
413                },
414                |prev| match prev {
415                    generic_btree::PreviousCache::NodeCache(c) => {
416                        ans += c.len;
417                    }
418                    generic_btree::PreviousCache::PrevSiblingElem(_) => {
419                        ans += 1;
420                    }
421                    generic_btree::PreviousCache::ThisElemAndOffset { .. } => {}
422                },
423            );
424
425            Some(ans)
426        }
427
428        pub(super) fn get_index_by_node_position(
429            &self,
430            node_position: &NodePosition,
431        ) -> Result<usize, usize> {
432            let Some(res) = self.tree.query::<KeyQuery>(node_position) else {
433                return Ok(0);
434            };
435            let mut ans = 0;
436            self.tree
437                .visit_previous_caches(res.cursor, |prev| match prev {
438                    generic_btree::PreviousCache::NodeCache(c) => {
439                        ans += c.len;
440                    }
441                    generic_btree::PreviousCache::PrevSiblingElem(_) => {
442                        ans += 1;
443                    }
444                    generic_btree::PreviousCache::ThisElemAndOffset { elem: _, offset } => {
445                        ans += offset;
446                    }
447                });
448            if res.found {
449                Ok(ans)
450            } else {
451                Err(ans)
452            }
453        }
454    }
455
456    #[derive(Clone, Debug)]
457    pub(super) struct Elem {
458        pub(super) pos: Arc<NodePosition>,
459        pub(super) id: TreeID,
460    }
461
462    impl Mergeable for Elem {
463        fn can_merge(&self, _rhs: &Self) -> bool {
464            false
465        }
466
467        fn merge_right(&mut self, _rhs: &Self) {
468            unreachable!()
469        }
470
471        fn merge_left(&mut self, _left: &Self) {
472            unreachable!()
473        }
474    }
475
476    impl HasLength for Elem {
477        fn rle_len(&self) -> usize {
478            1
479        }
480    }
481
482    impl Sliceable for Elem {
483        fn _slice(&self, range: std::ops::Range<usize>) -> Self {
484            assert!(range.len() == 1);
485            self.clone()
486        }
487    }
488
489    impl CanRemove for Elem {
490        fn can_remove(&self) -> bool {
491            false
492        }
493    }
494
495    impl TryInsert for Elem {
496        fn try_insert(&mut self, _pos: usize, elem: Self) -> Result<(), Self>
497        where
498            Self: Sized,
499        {
500            Err(elem)
501        }
502    }
503
504    #[derive(Clone, Debug, Default, PartialEq, Eq)]
505    struct Cache {
506        range: Option<Range<Arc<NodePosition>>>,
507        len: usize,
508    }
509
510    impl BTreeTrait for ChildTreeTrait {
511        type Elem = Elem;
512        type Cache = Cache;
513        type CacheDiff = ();
514        const USE_DIFF: bool = false;
515
516        fn calc_cache_internal(
517            cache: &mut Self::Cache,
518            caches: &[generic_btree::Child<Self>],
519        ) -> Self::CacheDiff {
520            if caches.is_empty() {
521                *cache = Default::default();
522                return;
523            }
524
525            *cache = Cache {
526                range: Some(
527                    caches[0].cache.range.as_ref().unwrap().start.clone()
528                        ..caches
529                            .last()
530                            .unwrap()
531                            .cache
532                            .range
533                            .as_ref()
534                            .unwrap()
535                            .end
536                            .clone(),
537                ),
538                len: caches.iter().map(|x| x.cache.len).sum(),
539            };
540        }
541
542        fn apply_cache_diff(_cache: &mut Self::Cache, _diff: &Self::CacheDiff) {
543            unreachable!()
544        }
545
546        fn merge_cache_diff(_diff1: &mut Self::CacheDiff, _diff2: &Self::CacheDiff) {}
547
548        fn get_elem_cache(elem: &Self::Elem) -> Self::Cache {
549            Cache {
550                range: Some(elem.pos.clone()..elem.pos.clone()),
551                len: 1,
552            }
553        }
554
555        fn new_cache_to_diff(_cache: &Self::Cache) -> Self::CacheDiff {}
556
557        fn sub_cache(_cache_lhs: &Self::Cache, _cache_rhs: &Self::Cache) -> Self::CacheDiff {}
558    }
559
560    struct KeyQuery;
561
562    impl Query<ChildTreeTrait> for KeyQuery {
563        type QueryArg = NodePosition;
564
565        #[inline(always)]
566        fn init(_target: &Self::QueryArg) -> Self {
567            KeyQuery
568        }
569
570        #[inline]
571        fn find_node(
572            &mut self,
573            target: &Self::QueryArg,
574            caches: &[generic_btree::Child<ChildTreeTrait>],
575        ) -> FindResult {
576            let result = caches.binary_search_by(|x| {
577                let range = x.cache.range.as_ref().unwrap();
578                if target < &range.start {
579                    core::cmp::Ordering::Greater
580                } else if target > &range.end {
581                    core::cmp::Ordering::Less
582                } else {
583                    core::cmp::Ordering::Equal
584                }
585            });
586
587            match result {
588                Ok(i) => FindResult::new_found(i, 0),
589                Err(i) => FindResult::new_missing(
590                    i.min(caches.len() - 1),
591                    if i == caches.len() { 1 } else { 0 },
592                ),
593            }
594        }
595
596        #[inline(always)]
597        fn confirm_elem(
598            &mut self,
599            q: &Self::QueryArg,
600            elem: &<ChildTreeTrait as BTreeTrait>::Elem,
601        ) -> (usize, bool) {
602            match q.cmp(&elem.pos) {
603                Ordering::Less => (0, false),
604                Ordering::Equal => (0, true),
605                Ordering::Greater => (1, false),
606            }
607        }
608    }
609
610    impl UseLengthFinder<ChildTreeTrait> for ChildTreeTrait {
611        fn get_len(cache: &<ChildTreeTrait as BTreeTrait>::Cache) -> usize {
612            cache.len
613        }
614    }
615}
616
617impl Debug for TreeChildrenCache {
618    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
619        writeln!(f, "TreeChildrenCache {{")?;
620        for (parent, children) in self.0.iter() {
621            writeln!(f, "  {:?}:{{", parent)?;
622            for (position, id) in children.iter() {
623                writeln!(f, "      {:?} -> {:?}", position, id)?;
624            }
625            writeln!(f, "  }}")?;
626        }
627        writeln!(f, "}}")
628    }
629}
630
631impl Deref for TreeChildrenCache {
632    type Target = FxHashMap<TreeParentId, NodeChildren>;
633
634    fn deref(&self) -> &Self::Target {
635        &self.0
636    }
637}
638
639impl DerefMut for TreeChildrenCache {
640    fn deref_mut(&mut self) -> &mut Self::Target {
641        &mut self.0
642    }
643}
644
645impl NodePosition {
646    fn new(position: FractionalIndex, idlp: IdLp) -> Self {
647        Self { position, idlp }
648    }
649}
650
651pub(crate) enum FiIfNotConfigured {
652    UseJitterZero,
653    #[allow(unused)]
654    Throw,
655    #[allow(unused)]
656    Zero,
657}
658
659impl TreeState {
660    pub fn new(idx: ContainerIdx, peer_id: PeerID) -> Self {
661        Self {
662            idx,
663            trees: FxHashMap::default(),
664            children: Default::default(),
665            fractional_index_config: TreeFractionalIndexConfigInner::GenerateFractionalIndex {
666                jitter: 0,
667                rng: Box::new(rand::rngs::StdRng::seed_from_u64(0)),
668            },
669            peer_id,
670        }
671    }
672
673    pub fn mov(
674        &mut self,
675        target: TreeID,
676        parent: TreeParentId,
677        id: IdFull,
678        position: Option<FractionalIndex>,
679        with_check: bool,
680    ) -> Result<(), LoroError> {
681        if with_check {
682            if let TreeParentId::Node(parent) = parent {
683                if !self.trees.contains_key(&parent) {
684                    return Err(LoroTreeError::TreeNodeParentNotFound(parent).into());
685                }
686            }
687            if self.is_ancestor_of(&target, &parent) {
688                return Err(LoroTreeError::CyclicMoveError.into());
689            }
690        }
691        if let Some(old_parent) = self.trees.get(&target).map(|x| x.parent) {
692            // remove old position
693            self.try_delete_position_cache(&old_parent, &target);
694        }
695
696        let entry = self.children.entry(parent).or_default();
697        let node_position = NodePosition::new(position.clone().unwrap_or_default(), id.idlp());
698        debug_assert!(!entry.has_child(&node_position));
699        entry.insert_child(node_position, target);
700
701        self.trees.insert(
702            target,
703            TreeStateNode {
704                parent,
705                position,
706                last_move_op: id,
707            },
708        );
709
710        Ok(())
711    }
712
713    fn _init_push_tree_node_in_order(
714        &mut self,
715        target: TreeID,
716        parent: TreeParentId,
717        last_move_op: IdFull,
718        position: Option<FractionalIndex>,
719    ) -> Result<(), LoroError> {
720        debug_assert!(!self.trees.contains_key(&target));
721        let entry = self.children.entry(parent).or_default();
722        let node_position =
723            NodePosition::new(position.clone().unwrap_or_default(), last_move_op.idlp());
724        debug_assert!(!entry.has_child(&node_position));
725        entry.push_child_in_order(node_position, target);
726        self.trees.insert(
727            target,
728            TreeStateNode {
729                parent,
730                position,
731                last_move_op,
732            },
733        );
734
735        Ok(())
736    }
737
738    #[inline(never)]
739    fn is_ancestor_of(&self, maybe_ancestor: &TreeID, node_id: &TreeParentId) -> bool {
740        if !self.trees.contains_key(maybe_ancestor) {
741            return false;
742        }
743        if let TreeParentId::Node(id) = node_id {
744            if id == maybe_ancestor {
745                return true;
746            }
747        }
748        match node_id {
749            TreeParentId::Node(id) => {
750                let parent = &self.trees.get(id).unwrap().parent;
751                if parent == node_id {
752                    panic!("is_ancestor_of loop")
753                }
754                self.is_ancestor_of(maybe_ancestor, parent)
755            }
756            TreeParentId::Deleted | TreeParentId::Root => false,
757            TreeParentId::Unexist => unreachable!(),
758        }
759    }
760
761    /// Get the parent of the node, if the node does not exist, return None
762    pub fn parent(&self, target: &TreeID) -> Option<TreeParentId> {
763        self.trees.get(target).map(|x| x.parent)
764    }
765
766    /// If the node is unexist, return None. If the node is deleted, return true.
767    pub(crate) fn is_node_deleted(&self, target: &TreeID) -> Option<bool> {
768        match self.trees.get(target).map(|x| x.parent)? {
769            TreeParentId::Deleted => Some(true),
770            TreeParentId::Root => Some(false),
771            TreeParentId::Node(p) => self.is_node_deleted(&p),
772            TreeParentId::Unexist => unreachable!(),
773        }
774    }
775
776    pub(crate) fn is_node_unexist(&self, target: &TreeID) -> bool {
777        !self.trees.contains_key(target)
778    }
779
780    // Get all flat tree nodes, excluding deleted nodes.
781    pub(crate) fn tree_nodes(&self) -> Vec<TreeNode> {
782        self.get_all_tree_nodes_under(TreeParentId::Root)
783    }
784
785    // Get all flat deleted nodes
786    #[allow(unused)]
787    pub(crate) fn deleted_tree_nodes(&self) -> Vec<TreeNode> {
788        self.get_all_tree_nodes_under(TreeParentId::Deleted)
789    }
790
791    // Get all flat tree nodes under the parent
792    pub(crate) fn get_all_tree_nodes_under(&self, root: TreeParentId) -> Vec<TreeNode> {
793        let mut ans = vec![];
794        let children = self.children.get(&root);
795        let mut q = children
796            .map(|x| VecDeque::from_iter(x.iter().enumerate().zip(std::iter::repeat(root))))
797            .unwrap_or_default();
798
799        while let Some(((index, (position, &target)), parent)) = q.pop_front() {
800            ans.push(TreeNode {
801                id: target,
802                parent,
803                fractional_index: position.position.clone(),
804                index,
805                last_move_op: self.trees.get(&target).map(|x| x.last_move_op).unwrap(),
806            });
807            if let Some(children) = self.children.get(&TreeParentId::Node(target)) {
808                q.extend(
809                    children
810                        .iter()
811                        .enumerate()
812                        .map(|(index, (position, this_target))| {
813                            ((index, (position, this_target)), TreeParentId::Node(target))
814                        }),
815                );
816            }
817        }
818        ans
819    }
820
821    pub(crate) fn get_all_hierarchy_nodes_under(
822        &self,
823        root: TreeParentId,
824    ) -> Vec<TreeNodeWithChildren> {
825        let mut ans = vec![];
826        let Some(children) = self.children.get(&root) else {
827            return ans;
828        };
829        for (index, (position, &target)) in children.iter().enumerate() {
830            ans.push(TreeNodeWithChildren {
831                id: target,
832                parent: root,
833                fractional_index: position.position.clone(),
834                index,
835                children: self.get_all_hierarchy_nodes_under(TreeParentId::Node(target)),
836            })
837        }
838        ans
839    }
840
841    fn bfs_all_alive_nodes_for_fast_snapshot(&self) -> Vec<TreeNode> {
842        let mut ans = vec![];
843        self._bfs_all_nodes(TreeParentId::Root, &mut ans);
844        ans
845    }
846
847    fn bfs_all_deleted_nodes_for_fast_snapshot(&self) -> Vec<TreeNode> {
848        let mut ans = vec![];
849        self._bfs_all_nodes(TreeParentId::Deleted, &mut ans);
850        ans
851    }
852
853    fn _bfs_all_nodes(&self, root: TreeParentId, ans: &mut Vec<TreeNode>) {
854        let children = self.children.get(&root);
855        if let Some(children) = children {
856            for (index, (position, target)) in children.iter().enumerate() {
857                ans.push(TreeNode {
858                    id: *target,
859                    parent: root,
860                    fractional_index: position.position.clone(),
861                    index,
862                    last_move_op: self.trees.get(target).map(|x| x.last_move_op).unwrap(),
863                });
864            }
865
866            for (_, id) in children.iter() {
867                self._bfs_all_nodes(TreeParentId::Node(*id), ans);
868            }
869        }
870    }
871
872    pub fn nodes(&self) -> Vec<TreeID> {
873        self.trees.keys().copied().collect::<Vec<_>>()
874    }
875
876    #[cfg(feature = "test_utils")]
877    pub fn max_counter(&self) -> i32 {
878        self.trees
879            .keys()
880            .filter(|&k| !self.is_node_deleted(k).unwrap())
881            .map(|k| k.counter)
882            .max()
883            .unwrap_or(0)
884    }
885
886    pub fn get_children<'a>(
887        &'a self,
888        parent: &TreeParentId,
889    ) -> Option<impl Iterator<Item = TreeID> + 'a> {
890        self.children.get(parent).map(|x| x.iter().map(|x| *x.1))
891    }
892
893    pub fn children_num(&self, parent: &TreeParentId) -> Option<usize> {
894        self.children.get(parent).map(|x| x.len())
895    }
896
897    /// Determine whether the target is the child of the node
898    ///
899    /// O(1)
900    pub fn is_parent(&self, target: &TreeID, parent: &TreeParentId) -> bool {
901        self.trees.get(target).is_some_and(|x| x.parent == *parent)
902    }
903
904    /// Delete the position cache of the node
905    pub(crate) fn try_delete_position_cache(&mut self, parent: &TreeParentId, target: &TreeID) {
906        if let Some(x) = self.children.get_mut(parent) {
907            x.delete_child(target);
908        }
909    }
910
911    pub(crate) fn generate_position_at(
912        &mut self,
913        target: &TreeID,
914        parent: &TreeParentId,
915        index: usize,
916        cfg: FiIfNotConfigured,
917    ) -> FractionalIndexGenResult {
918        match &mut self.fractional_index_config {
919            TreeFractionalIndexConfigInner::GenerateFractionalIndex { jitter, rng } => {
920                if *jitter == 0 {
921                    self.children
922                        .entry(*parent)
923                        .or_default()
924                        .generate_fi_at(index, target)
925                } else {
926                    self.children
927                        .entry(*parent)
928                        .or_default()
929                        .generate_fi_at_jitter(index, target, rng.as_mut(), *jitter)
930                }
931            }
932            TreeFractionalIndexConfigInner::MoveDisabled => match cfg {
933                FiIfNotConfigured::Throw => FractionalIndexGenResult::NotConfigured,
934                FiIfNotConfigured::UseJitterZero => self
935                    .children
936                    .entry(*parent)
937                    .or_default()
938                    .generate_fi_at(index, target),
939                FiIfNotConfigured::Zero => FractionalIndexGenResult::Ok(FractionalIndex::default()),
940            },
941        }
942    }
943
944    pub(crate) fn is_fractional_index_enabled(&self) -> bool {
945        !matches!(
946            self.fractional_index_config,
947            TreeFractionalIndexConfigInner::MoveDisabled
948        )
949    }
950
951    pub(crate) fn enable_generate_fractional_index(&mut self, jitter: u8) {
952        if let TreeFractionalIndexConfigInner::GenerateFractionalIndex {
953            jitter: old_jitter, ..
954        } = &mut self.fractional_index_config
955        {
956            *old_jitter = jitter;
957            return;
958        }
959        self.fractional_index_config = TreeFractionalIndexConfigInner::GenerateFractionalIndex {
960            jitter,
961            rng: Box::new(rand::rngs::StdRng::seed_from_u64(self.peer_id)),
962        };
963    }
964
965    pub(crate) fn disable_generate_fractional_index(&mut self) {
966        self.fractional_index_config = TreeFractionalIndexConfigInner::MoveDisabled;
967    }
968
969    pub(crate) fn get_position(&self, target: &TreeID) -> Option<FractionalIndex> {
970        self.trees.get(target).and_then(|x| x.position.clone())
971    }
972
973    pub(crate) fn get_index_by_tree_id(&self, target: &TreeID) -> Option<usize> {
974        let parent = self.parent(target)?;
975        (!parent.is_deleted())
976            .then(|| {
977                self.children
978                    .get(&parent)
979                    .and_then(|x| x.get_index_by_child_id(target))
980            })
981            .flatten()
982    }
983
984    pub(crate) fn get_index_by_position(
985        &self,
986        parent: &TreeParentId,
987        node_position: &NodePosition,
988    ) -> Option<usize> {
989        self.children.get(parent).map(|c| {
990            match c.get_last_insert_index_by_position(node_position) {
991                Ok(i) => i,
992                Err(i) => i,
993            }
994        })
995    }
996
997    pub(crate) fn get_id_by_index(&self, parent: &TreeParentId, index: usize) -> Option<TreeID> {
998        (!parent.is_deleted())
999            .then(|| self.children.get(parent).and_then(|x| x.get_id_at(index)))
1000            .flatten()
1001    }
1002
1003    /// Check the consistency between `self.trees` and `self.children`
1004    ///
1005    /// It's used for debug and test
1006    #[allow(unused)]
1007    pub(crate) fn check_tree_integrity(&self) {
1008        let mut parent_children_map: FxHashMap<TreeParentId, FxHashSet<TreeID>> =
1009            FxHashMap::default();
1010        for (id, node) in self.trees.iter() {
1011            let parent = node.parent;
1012            parent_children_map.entry(parent).or_default().insert(*id);
1013        }
1014
1015        for (parent, children) in parent_children_map.iter() {
1016            let cached_children = self.get_children(parent).expect("parent not found");
1017            let cached_children = cached_children.collect::<FxHashSet<_>>();
1018            if &cached_children != children {
1019                panic!(
1020                    "tree integrity broken: children set of node {:?} is not consistent",
1021                    parent
1022                );
1023            }
1024        }
1025    }
1026
1027    pub fn is_empty(&self) -> bool {
1028        match self.children.get(&TreeParentId::Root) {
1029            Some(c) => c.len() == 0,
1030            None => true,
1031        }
1032    }
1033
1034    pub fn get_last_move_id(&self, id: &TreeID) -> Option<ID> {
1035        self.trees.get(id).map(|x| x.last_move_op.id())
1036    }
1037}
1038
1039pub(crate) enum FractionalIndexGenResult {
1040    Ok(FractionalIndex),
1041    Rearrange(Vec<(TreeID, FractionalIndex)>),
1042    NotConfigured,
1043}
1044
1045impl ContainerState for TreeState {
1046    fn container_idx(&self) -> crate::container::idx::ContainerIdx {
1047        self.idx
1048    }
1049
1050    fn is_state_empty(&self) -> bool {
1051        self.nodes().is_empty()
1052    }
1053
1054    // How we apply the diff is coupled with the [DiffMode] we used to calculate the diff.
1055    // So be careful when you modify this function.
1056    fn apply_diff_and_convert(
1057        &mut self,
1058        diff: crate::event::InternalDiff,
1059        ctx: DiffApplyContext,
1060    ) -> Diff {
1061        let need_check = !matches!(ctx.mode, DiffMode::Checkout | DiffMode::Linear);
1062        let mut ans = vec![];
1063        if let InternalDiff::Tree(tree) = &diff {
1064            // assert never cause cycle move
1065            for diff in tree.diff.iter() {
1066                let last_move_op = diff.last_effective_move_op_id;
1067                let target = diff.target;
1068                // create associated metadata container
1069                match &diff.action {
1070                    TreeInternalDiff::Create { parent, position } => {
1071                        self.mov(target, *parent, last_move_op, Some(position.clone()), false)
1072                            .unwrap();
1073
1074                        if let TreeParentId::Node(p) = parent {
1075                            // reuse diff cache, at this time,it's "move in deleted"
1076                            if self.is_node_deleted(p).unwrap() {
1077                                continue;
1078                            }
1079                        }
1080
1081                        let index = self.get_index_by_tree_id(&target).unwrap();
1082                        ans.push(TreeDiffItem {
1083                            target,
1084                            action: TreeExternalDiff::Create {
1085                                parent: *parent,
1086                                index,
1087                                position: position.clone(),
1088                            },
1089                        });
1090                    }
1091                    TreeInternalDiff::Move { parent, position } => {
1092                        let old_parent = self.trees.get(&target).unwrap().parent;
1093                        // If this is some, the node is still alive at the moment
1094                        let old_index = self.get_index_by_tree_id(&target);
1095                        let was_alive = !self.is_node_deleted(&target).unwrap();
1096                        if need_check {
1097                            if self
1098                                .mov(target, *parent, last_move_op, Some(position.clone()), true)
1099                                .is_ok()
1100                            {
1101                                if self.is_node_deleted(&target).unwrap() {
1102                                    if was_alive {
1103                                        // delete event
1104                                        ans.push(TreeDiffItem {
1105                                            target,
1106                                            action: TreeExternalDiff::Delete {
1107                                                old_parent,
1108                                                old_index: old_index.unwrap(),
1109                                            },
1110                                        });
1111                                    }
1112                                    // Otherwise, it's a normal move inside deleted nodes, no event is needed
1113                                } else if was_alive {
1114                                    // normal move
1115                                    ans.push(TreeDiffItem {
1116                                        target,
1117                                        action: TreeExternalDiff::Move {
1118                                            parent: *parent,
1119                                            index: self.get_index_by_tree_id(&target).unwrap(),
1120                                            position: position.clone(),
1121                                            old_parent,
1122                                            old_index: old_index.unwrap(),
1123                                        },
1124                                    });
1125                                } else {
1126                                    // create event
1127                                    ans.push(TreeDiffItem {
1128                                        target,
1129                                        action: TreeExternalDiff::Create {
1130                                            parent: *parent,
1131                                            index: self.get_index_by_tree_id(&target).unwrap(),
1132                                            position: position.clone(),
1133                                        },
1134                                    });
1135                                }
1136                            }
1137                        } else {
1138                            self.mov(target, *parent, last_move_op, Some(position.clone()), false)
1139                                .unwrap();
1140
1141                            if let TreeParentId::Node(p) = parent {
1142                                // reuse diff cache, at this time,it's "move in deleted"
1143                                if self.is_node_deleted(p).unwrap() {
1144                                    continue;
1145                                }
1146                            }
1147
1148                            let index = self.get_index_by_tree_id(&target).unwrap();
1149                            match was_alive {
1150                                true => {
1151                                    ans.push(TreeDiffItem {
1152                                        target,
1153                                        action: TreeExternalDiff::Move {
1154                                            parent: *parent,
1155                                            index,
1156                                            position: position.clone(),
1157                                            old_parent,
1158                                            old_index: old_index.unwrap(),
1159                                        },
1160                                    });
1161                                }
1162                                false => {
1163                                    ans.push(TreeDiffItem {
1164                                        target,
1165                                        action: TreeExternalDiff::Create {
1166                                            parent: *parent,
1167                                            index,
1168                                            position: position.clone(),
1169                                        },
1170                                    });
1171                                }
1172                            }
1173                        };
1174                    }
1175                    TreeInternalDiff::Delete { parent, position } => {
1176                        let mut send_event = true;
1177                        if self.is_node_deleted(&target).unwrap() {
1178                            send_event = false;
1179                        }
1180                        if send_event {
1181                            ans.push(TreeDiffItem {
1182                                target,
1183                                action: TreeExternalDiff::Delete {
1184                                    old_parent: self.trees.get(&target).unwrap().parent,
1185                                    old_index: self.get_index_by_tree_id(&target).unwrap(),
1186                                },
1187                            });
1188                        }
1189                        self.mov(target, *parent, last_move_op, position.clone(), false)
1190                            .unwrap();
1191                    }
1192                    TreeInternalDiff::MoveInDelete { parent, position } => {
1193                        self.mov(target, *parent, last_move_op, position.clone(), false)
1194                            .unwrap();
1195                    }
1196                    TreeInternalDiff::UnCreate => {
1197                        // maybe the node created and moved to the parent deleted
1198                        if !self.is_node_deleted(&target).unwrap() {
1199                            ans.push(TreeDiffItem {
1200                                target,
1201                                action: TreeExternalDiff::Delete {
1202                                    old_parent: self.trees.get(&target).unwrap().parent,
1203                                    old_index: self.get_index_by_tree_id(&target).unwrap(),
1204                                },
1205                            });
1206                        }
1207                        // delete it from state
1208                        let node = self.trees.remove(&target);
1209                        if let Some(node) = node {
1210                            if !node.parent.is_deleted() {
1211                                self.children
1212                                    .get_mut(&node.parent)
1213                                    .unwrap()
1214                                    .delete_child(&target);
1215                            }
1216                        }
1217                        continue;
1218                    }
1219                };
1220            }
1221        }
1222
1223        // self.check_tree_integrity();
1224        Diff::Tree(TreeDiff { diff: ans })
1225    }
1226
1227    // How we apply the diff is coupled with the [DiffMode] we used to calculate the diff.
1228    // So be careful when you modify this function.
1229    fn apply_diff(&mut self, diff: InternalDiff, ctx: DiffApplyContext) {
1230        if let InternalDiff::Tree(tree) = &diff {
1231            let need_check = !matches!(ctx.mode, DiffMode::Checkout | DiffMode::Linear);
1232            // assert never cause cycle move
1233            for diff in tree.diff.iter() {
1234                let last_move_op = diff.last_effective_move_op_id;
1235                let target = diff.target;
1236                // create associated metadata container
1237                match &diff.action {
1238                    TreeInternalDiff::Create { parent, position }
1239                    | TreeInternalDiff::Move {
1240                        parent, position, ..
1241                    } => {
1242                        if need_check {
1243                            self.mov(target, *parent, last_move_op, Some(position.clone()), true)
1244                                .unwrap_or_default();
1245                        } else {
1246                            self.mov(target, *parent, last_move_op, Some(position.clone()), false)
1247                                .unwrap();
1248                        }
1249                    }
1250                    TreeInternalDiff::Delete { parent, position } => {
1251                        self.mov(target, *parent, last_move_op, position.clone(), false)
1252                            .unwrap();
1253                    }
1254                    TreeInternalDiff::MoveInDelete { parent, position } => {
1255                        self.mov(target, *parent, last_move_op, position.clone(), false)
1256                            .unwrap();
1257                    }
1258                    TreeInternalDiff::UnCreate => {
1259                        // delete it from state
1260                        let parent = self.trees.remove(&target);
1261                        if let Some(parent) = parent {
1262                            if !parent.parent.is_deleted() {
1263                                self.children
1264                                    .get_mut(&parent.parent)
1265                                    .unwrap()
1266                                    .delete_child(&target);
1267                            }
1268                        }
1269                        continue;
1270                    }
1271                };
1272            }
1273        }
1274        // self.check_tree_integrity();
1275    }
1276
1277    fn apply_local_op(&mut self, raw_op: &RawOp, _op: &Op) -> LoroResult<ApplyLocalOpReturn> {
1278        let mut deleted_containers = vec![];
1279        match &raw_op.content {
1280            crate::op::RawOpContent::Tree(tree) => match &**tree {
1281                TreeOp::Create {
1282                    target,
1283                    parent,
1284                    position,
1285                }
1286                | TreeOp::Move {
1287                    target,
1288                    parent,
1289                    position,
1290                } => {
1291                    let parent = TreeParentId::from(*parent);
1292                    self.mov(
1293                        *target,
1294                        parent,
1295                        raw_op.id_full(),
1296                        Some(position.clone()),
1297                        true,
1298                    )?;
1299                }
1300                TreeOp::Delete { target } => {
1301                    let parent = TreeParentId::Deleted;
1302                    deleted_containers.push(ContainerID::new_normal(
1303                        target.id(),
1304                        loro_common::ContainerType::Map,
1305                    ));
1306                    self.mov(*target, parent, raw_op.id_full(), None, true)?;
1307                }
1308            },
1309            _ => unreachable!(),
1310        }
1311        // self.check_tree_integrity();
1312        Ok(ApplyLocalOpReturn { deleted_containers })
1313    }
1314
1315    fn to_diff(&mut self, _doc: &Weak<LoroDocInner>) -> Diff {
1316        let mut diffs = vec![];
1317        let Some(roots) = self.children.get(&TreeParentId::Root) else {
1318            return Diff::Tree(TreeDiff { diff: vec![] });
1319        };
1320
1321        let mut q = VecDeque::from_iter(roots.iter());
1322        let mut index = 0;
1323        let mut parent = TreeParentId::Root;
1324        while let Some((position, node)) = q.pop_front() {
1325            let node_parent = self.trees.get(node).unwrap().parent;
1326            if node_parent != parent {
1327                index = 0;
1328                parent = node_parent;
1329            }
1330            let diff = TreeDiffItem {
1331                target: *node,
1332                action: TreeExternalDiff::Create {
1333                    parent: node_parent,
1334                    index,
1335                    position: position.position.clone(),
1336                },
1337            };
1338            index += 1;
1339            diffs.push(diff);
1340            if let Some(children) = self.children.get(&TreeParentId::Node(*node)) {
1341                // TODO: Refactor: you can include the index and parent in the q
1342                // The code will be more robust and easy to understand
1343                q.extend(children.iter());
1344            }
1345        }
1346
1347        Diff::Tree(TreeDiff { diff: diffs })
1348    }
1349
1350    fn get_value(&mut self) -> LoroValue {
1351        self.get_all_hierarchy_nodes_under(TreeParentId::Root)
1352            .into_iter()
1353            .map(|x| x.into_value())
1354            .collect::<Vec<_>>()
1355            .into()
1356    }
1357
1358    /// Get the index of the child container
1359    fn get_child_index(&self, id: &ContainerID) -> Option<Index> {
1360        let id = id.as_normal().unwrap();
1361        let tree_id = TreeID {
1362            peer: *id.0,
1363            counter: *id.1,
1364        };
1365        if !self.trees.contains_key(&tree_id) || self.is_node_deleted(&tree_id).unwrap() {
1366            None
1367        } else {
1368            Some(Index::Node(tree_id))
1369        }
1370    }
1371
1372    fn contains_child(&self, id: &ContainerID) -> bool {
1373        let id = id.as_normal().unwrap();
1374        let tree_id = TreeID {
1375            peer: *id.0,
1376            counter: *id.1,
1377        };
1378        self.trees.contains_key(&tree_id) && !self.is_node_deleted(&tree_id).unwrap()
1379    }
1380
1381    fn get_child_containers(&self) -> Vec<ContainerID> {
1382        self.trees
1383            .keys()
1384            .map(|n| n.associated_meta_container())
1385            .collect_vec()
1386    }
1387
1388    fn fork(&self, _config: &Configure) -> Self {
1389        self.clone()
1390    }
1391}
1392
1393// convert map container to LoroValue
1394#[allow(clippy::ptr_arg)]
1395pub(crate) fn get_meta_value(nodes: &mut Vec<LoroValue>, state: &mut DocState) {
1396    for node in nodes.iter_mut() {
1397        let map = node.as_map_mut().unwrap().make_mut();
1398        let meta = map.get_mut("meta").unwrap();
1399        let id = meta.as_container().unwrap();
1400        *meta = state.get_container_deep_value(state.arena.register_container(id));
1401        let children = map.get_mut("children").unwrap().as_list_mut().unwrap();
1402        get_meta_value(children.make_mut(), state);
1403    }
1404}
1405
1406#[derive(Debug, Clone)]
1407pub struct TreeNode {
1408    pub id: TreeID,
1409    pub parent: TreeParentId,
1410    pub fractional_index: FractionalIndex,
1411    pub index: usize,
1412    pub last_move_op: IdFull,
1413}
1414
1415#[derive(Debug, Clone)]
1416pub struct TreeNodeWithChildren {
1417    pub id: TreeID,
1418    pub parent: TreeParentId,
1419    pub fractional_index: FractionalIndex,
1420    pub index: usize,
1421    pub children: Vec<TreeNodeWithChildren>,
1422}
1423
1424impl TreeNodeWithChildren {
1425    fn into_value(self) -> LoroValue {
1426        let mut t = FxHashMap::default();
1427        t.insert("id".to_string(), self.id.to_string().into());
1428        let p = self
1429            .parent
1430            .tree_id()
1431            .map(|p| p.to_string().into())
1432            .unwrap_or(LoroValue::Null);
1433        t.insert("parent".to_string(), p);
1434        t.insert(
1435            "meta".to_string(),
1436            self.id.associated_meta_container().into(),
1437        );
1438        t.insert("index".to_string(), (self.index as i64).into());
1439        t.insert(
1440            "fractional_index".to_string(),
1441            self.fractional_index.to_string().into(),
1442        );
1443        t.insert(
1444            "children".to_string(),
1445            self.children
1446                .into_iter()
1447                .map(|x| x.into_value())
1448                .collect::<Vec<_>>()
1449                .into(),
1450        );
1451        t.into()
1452    }
1453}
1454
1455mod jitter {
1456    use super::{FractionalIndexGenResult, NodeChildren};
1457    use fractional_index::FractionalIndex;
1458    use loro_common::TreeID;
1459    use rand::Rng;
1460
1461    impl NodeChildren {
1462        pub(super) fn generate_fi_at_jitter(
1463            &self,
1464            pos: usize,
1465            target: &TreeID,
1466            rng: &mut impl Rng,
1467            jitter: u8,
1468        ) -> FractionalIndexGenResult {
1469            let mut reset_ids = vec![];
1470            let mut left = None;
1471            let mut next_right = None;
1472            {
1473                let mut right = None;
1474                let children_num = self.len();
1475                if children_num == 0 {
1476                    return FractionalIndexGenResult::Ok(FractionalIndex::jitter_default(
1477                        rng, jitter,
1478                    ));
1479                }
1480
1481                if pos > 0 {
1482                    left = self.get_node_position_at(pos - 1);
1483                }
1484                if pos < children_num {
1485                    right = self.get_elem_at(pos);
1486                }
1487
1488                let left_fi = left.map(|x| &x.position);
1489                // if left and right have the same fractional indexes, we need to scan further to
1490                // find all the ids that need to be reset
1491                if let Some(left_fi) = left_fi {
1492                    if Some(left_fi) == right.map(|x| &x.0.position) {
1493                        // TODO: the min length between left and right
1494                        reset_ids.push(*right.unwrap().1);
1495                        for i in (pos + 1)..children_num {
1496                            let this_position = &self.get_node_position_at(i).unwrap().position;
1497                            if this_position == left_fi {
1498                                reset_ids.push(*self.get_elem_at(i).unwrap().1);
1499                            } else {
1500                                next_right = Some(this_position.clone());
1501                                break;
1502                            }
1503                        }
1504                    }
1505                }
1506
1507                if reset_ids.is_empty() {
1508                    return FractionalIndexGenResult::Ok(
1509                        FractionalIndex::new_jitter(
1510                            left.map(|x| &x.position),
1511                            right.map(|x| &x.0.position),
1512                            rng,
1513                            jitter,
1514                        )
1515                        .unwrap(),
1516                    );
1517                }
1518            }
1519            let positions = FractionalIndex::generate_n_evenly_jitter(
1520                left.map(|x| &x.position),
1521                next_right.as_ref(),
1522                reset_ids.len() + 1,
1523                rng,
1524                jitter,
1525            )
1526            .unwrap();
1527            FractionalIndexGenResult::Rearrange(
1528                Some(*target)
1529                    .into_iter()
1530                    .chain(reset_ids)
1531                    .zip(positions)
1532                    .collect(),
1533            )
1534        }
1535    }
1536}
1537
1538mod snapshot {
1539    use std::{borrow::Cow, collections::BTreeSet, io::Read};
1540
1541    use fractional_index::FractionalIndex;
1542    use itertools::Itertools;
1543    use loro_common::{IdFull, Lamport, PeerID, TreeID};
1544    use rustc_hash::FxHashMap;
1545
1546    use serde_columnar::columnar;
1547
1548    use crate::{
1549        encoding::{arena::PositionArena, value_register::ValueRegister},
1550        state::FastStateSnapshot,
1551    };
1552
1553    use super::{TreeNode, TreeParentId, TreeState};
1554    #[columnar(vec, ser, de, iterable)]
1555    #[derive(Debug, Clone)]
1556    struct EncodedTreeNodeId {
1557        #[columnar(strategy = "DeltaRle")]
1558        peer_idx: usize,
1559        #[columnar(strategy = "DeltaRle")]
1560        counter: i32,
1561    }
1562
1563    #[columnar(vec, ser, de, iterable)]
1564    #[derive(Debug, Clone)]
1565    struct EncodedTreeNode {
1566        /// If this field is 0, it means none, its parent is root
1567        /// If this field is 1, its parent is the deleted root
1568        #[columnar(strategy = "DeltaRle")]
1569        parent_idx_plus_two: usize,
1570        #[columnar(strategy = "DeltaRle")]
1571        last_set_peer_idx: usize,
1572        #[columnar(strategy = "DeltaRle")]
1573        last_set_counter: i32,
1574        #[columnar(strategy = "DeltaRle")]
1575        last_set_lamport_sub_counter: i32,
1576        fractional_index_idx: usize,
1577    }
1578
1579    #[columnar(ser, de)]
1580    struct EncodedTree<'a> {
1581        #[columnar(class = "vec", iter = "EncodedTreeNodeId")]
1582        node_ids: Vec<EncodedTreeNodeId>,
1583        #[columnar(class = "vec", iter = "EncodedTreeNode")]
1584        nodes: Vec<EncodedTreeNode>,
1585        #[columnar(borrow)]
1586        fractional_indexes: Cow<'a, [u8]>,
1587        #[columnar(borrow)]
1588        reserved_has_effect_bool_rle: Cow<'a, [u8]>,
1589    }
1590
1591    fn encode(
1592        state: &TreeState,
1593        input: Vec<TreeNode>,
1594        deleted_nodes: Vec<TreeNode>,
1595    ) -> (ValueRegister<PeerID>, EncodedTree<'_>) {
1596        let mut peers: ValueRegister<PeerID> = ValueRegister::new();
1597        let mut position_set = BTreeSet::default();
1598        let mut nodes = Vec::with_capacity(input.len());
1599        let mut node_ids = Vec::with_capacity(input.len());
1600        let mut position_register = ValueRegister::new();
1601        let mut id_to_idx = FxHashMap::default();
1602        for node in input.iter().chain(deleted_nodes.iter()) {
1603            position_set.insert(node.fractional_index.clone());
1604            let idx = node_ids.len();
1605            node_ids.push(EncodedTreeNodeId {
1606                peer_idx: peers.register(&node.id.peer),
1607                counter: node.id.counter,
1608            });
1609            id_to_idx.insert(node.id, idx);
1610        }
1611
1612        for p in position_set {
1613            position_register.register(&p);
1614        }
1615
1616        for node in input {
1617            let n = state.trees.get(&node.id).unwrap();
1618            let last_set_id = n.last_move_op;
1619            nodes.push(EncodedTreeNode {
1620                parent_idx_plus_two: match node.parent {
1621                    TreeParentId::Deleted => 1,
1622                    TreeParentId::Root => 0,
1623                    TreeParentId::Node(id) => id_to_idx.get(&id).unwrap() + 2,
1624                    TreeParentId::Unexist => unreachable!(),
1625                },
1626                last_set_peer_idx: peers.register(&last_set_id.peer),
1627                last_set_counter: last_set_id.counter,
1628                last_set_lamport_sub_counter: last_set_id.lamport as i32 - last_set_id.counter,
1629                fractional_index_idx: position_register.register(&node.fractional_index),
1630            })
1631        }
1632
1633        for node in deleted_nodes {
1634            let n = state.trees.get(&node.id).unwrap();
1635            let last_set_id = n.last_move_op;
1636            nodes.push(EncodedTreeNode {
1637                parent_idx_plus_two: match node.parent {
1638                    TreeParentId::Deleted => 1,
1639                    TreeParentId::Root => 0,
1640                    TreeParentId::Node(id) => id_to_idx.get(&id).unwrap() + 2,
1641                    TreeParentId::Unexist => unreachable!(),
1642                },
1643                last_set_peer_idx: peers.register(&last_set_id.peer),
1644                last_set_counter: last_set_id.counter,
1645                last_set_lamport_sub_counter: last_set_id.lamport as i32 - last_set_id.counter,
1646                fractional_index_idx: position_register.register(&node.fractional_index),
1647            })
1648        }
1649
1650        let position_vec = position_register.unwrap_vec();
1651        let positions = PositionArena::from_positions(position_vec.iter().map(|p| p.as_bytes()));
1652        (
1653            peers,
1654            EncodedTree {
1655                node_ids,
1656                nodes,
1657                fractional_indexes: positions.encode().into(),
1658                reserved_has_effect_bool_rle: vec![].into(),
1659            },
1660        )
1661    }
1662
1663    impl FastStateSnapshot for TreeState {
1664        /// Encodes the TreeState into a compact binary format for efficient serialization.
1665        ///
1666        /// The encoding schema:
1667        /// 1. Encodes all nodes using a breadth-first search traversal, ensuring a consistent order.
1668        /// 2. Uses a ValueRegister to deduplicate and index PeerIDs and TreeIDs, reducing redundancy.
1669        ///    - PeerIDs are stored once and referenced by index.
1670        ///    - TreeIDs are decomposed into peer index and counter for compact representation.
1671        /// 3. Encodes fractional indexes using a PositionArena for space efficiency
1672        /// 4. Utilizes delta encoding and run-length encoding for further size reduction:
1673        ///    - Delta encoding stores differences between consecutive values.
1674        ///    - Run-length encoding compresses sequences of repeated values.
1675        /// 5. Stores parent relationships using indices, with special values for root and deleted nodes.
1676        /// 6. Encodes last move operation details (peer_idx, counter[Delta], lamport clock[Delta]) for each node.
1677        fn encode_snapshot_fast<W: std::io::prelude::Write>(&mut self, mut w: W) {
1678            let all_alive_nodes = self.bfs_all_alive_nodes_for_fast_snapshot();
1679            let all_deleted_nodes = self.bfs_all_deleted_nodes_for_fast_snapshot();
1680            let (peers, encoded) = encode(self, all_alive_nodes, all_deleted_nodes);
1681            let peers = peers.unwrap_vec();
1682            leb128::write::unsigned(&mut w, peers.len() as u64).unwrap();
1683            for peer in peers {
1684                w.write_all(&peer.to_le_bytes()).unwrap();
1685            }
1686
1687            let vec = serde_columnar::to_vec(&encoded).unwrap();
1688            w.write_all(&vec).unwrap();
1689        }
1690
1691        fn decode_value(_: &[u8]) -> loro_common::LoroResult<(loro_common::LoroValue, &[u8])> {
1692            unreachable!()
1693        }
1694
1695        fn decode_snapshot_fast(
1696            idx: crate::container::idx::ContainerIdx,
1697            (_, mut bytes): (loro_common::LoroValue, &[u8]),
1698            ctx: crate::state::ContainerCreationContext,
1699        ) -> loro_common::LoroResult<Self>
1700        where
1701            Self: Sized,
1702        {
1703            let peer_num = leb128::read::unsigned(&mut bytes).unwrap() as usize;
1704            let mut peers = Vec::with_capacity(peer_num);
1705            for _ in 0..peer_num {
1706                let mut buf = [0u8; 8];
1707                bytes.read_exact(&mut buf).unwrap();
1708                peers.push(PeerID::from_le_bytes(buf));
1709            }
1710
1711            let mut tree = TreeState::new(idx, ctx.peer);
1712            let encoded: EncodedTree = serde_columnar::from_bytes(bytes)?;
1713            let fractional_indexes = PositionArena::decode(&encoded.fractional_indexes).unwrap();
1714            let fractional_indexes = fractional_indexes.parse_to_positions();
1715            let node_ids = encoded
1716                .node_ids
1717                .iter()
1718                .map(|x| TreeID::new(peers[x.peer_idx], x.counter))
1719                .collect_vec();
1720            for (node_id, node) in node_ids.iter().zip(encoded.nodes.into_iter()) {
1721                // PERF: we don't need to mov the deleted node, instead we can cache them
1722                // If the parent is TreeParentId::Deleted, then all the nodes afterwards are deleted
1723                tree._init_push_tree_node_in_order(
1724                    *node_id,
1725                    match node.parent_idx_plus_two {
1726                        0 => TreeParentId::Root,
1727                        1 => TreeParentId::Deleted,
1728                        n => {
1729                            let id = node_ids[n - 2];
1730                            TreeParentId::from(Some(id))
1731                        }
1732                    },
1733                    IdFull::new(
1734                        peers[node.last_set_peer_idx],
1735                        node.last_set_counter,
1736                        (node.last_set_lamport_sub_counter + node.last_set_counter) as Lamport,
1737                    ),
1738                    Some(FractionalIndex::from_bytes(
1739                        fractional_indexes[node.fractional_index_idx].clone(),
1740                    )),
1741                )
1742                .unwrap();
1743            }
1744
1745            Ok(tree)
1746        }
1747    }
1748}