Skip to main content

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) -> LoroResult<()> {
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                        }
1248                    }
1249                    TreeInternalDiff::Delete { parent, position } => {
1250                        self.mov(target, *parent, last_move_op, position.clone(), false)?;
1251                    }
1252                    TreeInternalDiff::MoveInDelete { parent, position } => {
1253                        self.mov(target, *parent, last_move_op, position.clone(), false)?;
1254                    }
1255                    TreeInternalDiff::UnCreate => {
1256                        // delete it from state
1257                        let parent = self.trees.remove(&target);
1258                        if let Some(parent) = parent {
1259                            if !parent.parent.is_deleted() {
1260                                self.children
1261                                    .get_mut(&parent.parent)
1262                                    .unwrap()
1263                                    .delete_child(&target);
1264                            }
1265                        }
1266                        continue;
1267                    }
1268                };
1269            }
1270        }
1271        // self.check_tree_integrity();
1272        Ok(())
1273    }
1274
1275    fn apply_local_op(&mut self, raw_op: &RawOp, _op: &Op) -> LoroResult<ApplyLocalOpReturn> {
1276        let mut deleted_containers = vec![];
1277        match &raw_op.content {
1278            crate::op::RawOpContent::Tree(tree) => match &**tree {
1279                TreeOp::Create {
1280                    target,
1281                    parent,
1282                    position,
1283                }
1284                | TreeOp::Move {
1285                    target,
1286                    parent,
1287                    position,
1288                } => {
1289                    let parent = TreeParentId::from(*parent);
1290                    self.mov(
1291                        *target,
1292                        parent,
1293                        raw_op.id_full(),
1294                        Some(position.clone()),
1295                        true,
1296                    )?;
1297                }
1298                TreeOp::Delete { target } => {
1299                    let parent = TreeParentId::Deleted;
1300                    deleted_containers.push(ContainerID::new_normal(
1301                        target.id(),
1302                        loro_common::ContainerType::Map,
1303                    ));
1304                    self.mov(*target, parent, raw_op.id_full(), None, true)?;
1305                }
1306            },
1307            _ => unreachable!(),
1308        }
1309        // self.check_tree_integrity();
1310        Ok(ApplyLocalOpReturn { deleted_containers })
1311    }
1312
1313    fn to_diff(&mut self, _doc: &Weak<LoroDocInner>) -> Diff {
1314        let mut diffs = vec![];
1315        let Some(roots) = self.children.get(&TreeParentId::Root) else {
1316            return Diff::Tree(TreeDiff { diff: vec![] });
1317        };
1318
1319        let mut q = VecDeque::from_iter(roots.iter());
1320        let mut index = 0;
1321        let mut parent = TreeParentId::Root;
1322        while let Some((position, node)) = q.pop_front() {
1323            let node_parent = self.trees.get(node).unwrap().parent;
1324            if node_parent != parent {
1325                index = 0;
1326                parent = node_parent;
1327            }
1328            let diff = TreeDiffItem {
1329                target: *node,
1330                action: TreeExternalDiff::Create {
1331                    parent: node_parent,
1332                    index,
1333                    position: position.position.clone(),
1334                },
1335            };
1336            index += 1;
1337            diffs.push(diff);
1338            if let Some(children) = self.children.get(&TreeParentId::Node(*node)) {
1339                // TODO: Refactor: you can include the index and parent in the q
1340                // The code will be more robust and easy to understand
1341                q.extend(children.iter());
1342            }
1343        }
1344
1345        Diff::Tree(TreeDiff { diff: diffs })
1346    }
1347
1348    fn get_value(&mut self) -> LoroValue {
1349        self.get_all_hierarchy_nodes_under(TreeParentId::Root)
1350            .into_iter()
1351            .map(|x| x.into_value())
1352            .collect::<Vec<_>>()
1353            .into()
1354    }
1355
1356    /// Get the index of the child container
1357    fn get_child_index(&self, id: &ContainerID) -> Option<Index> {
1358        let id = id.as_normal().unwrap();
1359        let tree_id = TreeID {
1360            peer: *id.0,
1361            counter: *id.1,
1362        };
1363        if !self.trees.contains_key(&tree_id) || self.is_node_deleted(&tree_id).unwrap() {
1364            None
1365        } else {
1366            Some(Index::Node(tree_id))
1367        }
1368    }
1369
1370    fn contains_child(&self, id: &ContainerID) -> bool {
1371        let id = id.as_normal().unwrap();
1372        let tree_id = TreeID {
1373            peer: *id.0,
1374            counter: *id.1,
1375        };
1376        self.trees.contains_key(&tree_id) && !self.is_node_deleted(&tree_id).unwrap()
1377    }
1378
1379    fn get_child_containers(&self) -> Vec<ContainerID> {
1380        self.trees
1381            .keys()
1382            .map(|n| n.associated_meta_container())
1383            .collect_vec()
1384    }
1385
1386    fn fork(&self, _config: &Configure) -> Self {
1387        self.clone()
1388    }
1389}
1390
1391// convert map container to LoroValue
1392#[allow(clippy::ptr_arg)]
1393pub(crate) fn get_meta_value(nodes: &mut Vec<LoroValue>, state: &mut DocState) {
1394    for node in nodes.iter_mut() {
1395        let map = node.as_map_mut().unwrap().make_mut();
1396        let meta = map.get_mut("meta").unwrap();
1397        let id = meta.as_container().unwrap();
1398        *meta = state.get_container_deep_value(state.arena.register_container(id));
1399        let children = map.get_mut("children").unwrap().as_list_mut().unwrap();
1400        get_meta_value(children.make_mut(), state);
1401    }
1402}
1403
1404#[derive(Debug, Clone)]
1405pub struct TreeNode {
1406    pub id: TreeID,
1407    pub parent: TreeParentId,
1408    pub fractional_index: FractionalIndex,
1409    pub index: usize,
1410    pub last_move_op: IdFull,
1411}
1412
1413#[derive(Debug, Clone)]
1414pub struct TreeNodeWithChildren {
1415    pub id: TreeID,
1416    pub parent: TreeParentId,
1417    pub fractional_index: FractionalIndex,
1418    pub index: usize,
1419    pub children: Vec<TreeNodeWithChildren>,
1420}
1421
1422impl TreeNodeWithChildren {
1423    fn into_value(self) -> LoroValue {
1424        let mut t = FxHashMap::default();
1425        t.insert("id".to_string(), self.id.to_string().into());
1426        let p = self
1427            .parent
1428            .tree_id()
1429            .map(|p| p.to_string().into())
1430            .unwrap_or(LoroValue::Null);
1431        t.insert("parent".to_string(), p);
1432        t.insert(
1433            "meta".to_string(),
1434            self.id.associated_meta_container().into(),
1435        );
1436        t.insert("index".to_string(), (self.index as i64).into());
1437        t.insert(
1438            "fractional_index".to_string(),
1439            self.fractional_index.to_string().into(),
1440        );
1441        t.insert(
1442            "children".to_string(),
1443            self.children
1444                .into_iter()
1445                .map(|x| x.into_value())
1446                .collect::<Vec<_>>()
1447                .into(),
1448        );
1449        t.into()
1450    }
1451}
1452
1453mod jitter {
1454    use super::{FractionalIndexGenResult, NodeChildren};
1455    use fractional_index::FractionalIndex;
1456    use loro_common::TreeID;
1457    use rand::Rng;
1458
1459    impl NodeChildren {
1460        pub(super) fn generate_fi_at_jitter(
1461            &self,
1462            pos: usize,
1463            target: &TreeID,
1464            rng: &mut impl Rng,
1465            jitter: u8,
1466        ) -> FractionalIndexGenResult {
1467            let mut reset_ids = vec![];
1468            let mut left = None;
1469            let mut next_right = None;
1470            {
1471                let mut right = None;
1472                let children_num = self.len();
1473                if children_num == 0 {
1474                    return FractionalIndexGenResult::Ok(FractionalIndex::jitter_default(
1475                        rng, jitter,
1476                    ));
1477                }
1478
1479                if pos > 0 {
1480                    left = self.get_node_position_at(pos - 1);
1481                }
1482                if pos < children_num {
1483                    right = self.get_elem_at(pos);
1484                }
1485
1486                let left_fi = left.map(|x| &x.position);
1487                // if left and right have the same fractional indexes, we need to scan further to
1488                // find all the ids that need to be reset
1489                if let Some(left_fi) = left_fi {
1490                    if Some(left_fi) == right.map(|x| &x.0.position) {
1491                        // TODO: the min length between left and right
1492                        reset_ids.push(*right.unwrap().1);
1493                        for i in (pos + 1)..children_num {
1494                            let this_position = &self.get_node_position_at(i).unwrap().position;
1495                            if this_position == left_fi {
1496                                reset_ids.push(*self.get_elem_at(i).unwrap().1);
1497                            } else {
1498                                next_right = Some(this_position.clone());
1499                                break;
1500                            }
1501                        }
1502                    }
1503                }
1504
1505                if reset_ids.is_empty() {
1506                    return FractionalIndexGenResult::Ok(
1507                        FractionalIndex::new_jitter(
1508                            left.map(|x| &x.position),
1509                            right.map(|x| &x.0.position),
1510                            rng,
1511                            jitter,
1512                        )
1513                        .unwrap(),
1514                    );
1515                }
1516            }
1517            let positions = FractionalIndex::generate_n_evenly_jitter(
1518                left.map(|x| &x.position),
1519                next_right.as_ref(),
1520                reset_ids.len() + 1,
1521                rng,
1522                jitter,
1523            )
1524            .unwrap();
1525            FractionalIndexGenResult::Rearrange(
1526                Some(*target)
1527                    .into_iter()
1528                    .chain(reset_ids)
1529                    .zip(positions)
1530                    .collect(),
1531            )
1532        }
1533    }
1534}
1535
1536mod snapshot {
1537    use std::{borrow::Cow, collections::BTreeSet, io::Read};
1538
1539    use fractional_index::FractionalIndex;
1540    use itertools::Itertools;
1541    use loro_common::{IdFull, Lamport, PeerID, TreeID};
1542    use rustc_hash::FxHashMap;
1543
1544    use serde_columnar::columnar;
1545
1546    use crate::{
1547        encoding::{arena::PositionArena, value_register::ValueRegister},
1548        state::FastStateSnapshot,
1549    };
1550
1551    use super::{TreeNode, TreeParentId, TreeState};
1552    #[columnar(vec, ser, de, iterable)]
1553    #[derive(Debug, Clone)]
1554    struct EncodedTreeNodeId {
1555        #[columnar(strategy = "DeltaRle")]
1556        peer_idx: usize,
1557        #[columnar(strategy = "DeltaRle")]
1558        counter: i32,
1559    }
1560
1561    #[columnar(vec, ser, de, iterable)]
1562    #[derive(Debug, Clone)]
1563    struct EncodedTreeNode {
1564        /// If this field is 0, it means none, its parent is root
1565        /// If this field is 1, its parent is the deleted root
1566        #[columnar(strategy = "DeltaRle")]
1567        parent_idx_plus_two: usize,
1568        #[columnar(strategy = "DeltaRle")]
1569        last_set_peer_idx: usize,
1570        #[columnar(strategy = "DeltaRle")]
1571        last_set_counter: i32,
1572        #[columnar(strategy = "DeltaRle")]
1573        last_set_lamport_sub_counter: i32,
1574        fractional_index_idx: usize,
1575    }
1576
1577    #[columnar(ser, de)]
1578    struct EncodedTree<'a> {
1579        #[columnar(class = "vec", iter = "EncodedTreeNodeId")]
1580        node_ids: Vec<EncodedTreeNodeId>,
1581        #[columnar(class = "vec", iter = "EncodedTreeNode")]
1582        nodes: Vec<EncodedTreeNode>,
1583        #[columnar(borrow)]
1584        fractional_indexes: Cow<'a, [u8]>,
1585        #[columnar(borrow)]
1586        reserved_has_effect_bool_rle: Cow<'a, [u8]>,
1587    }
1588
1589    fn encode(
1590        state: &TreeState,
1591        input: Vec<TreeNode>,
1592        deleted_nodes: Vec<TreeNode>,
1593    ) -> (ValueRegister<PeerID>, EncodedTree<'_>) {
1594        let mut peers: ValueRegister<PeerID> = ValueRegister::new();
1595        let mut position_set = BTreeSet::default();
1596        let mut nodes = Vec::with_capacity(input.len());
1597        let mut node_ids = Vec::with_capacity(input.len());
1598        let mut position_register = ValueRegister::new();
1599        let mut id_to_idx = FxHashMap::default();
1600        for node in input.iter().chain(deleted_nodes.iter()) {
1601            position_set.insert(node.fractional_index.clone());
1602            let idx = node_ids.len();
1603            node_ids.push(EncodedTreeNodeId {
1604                peer_idx: peers.register(&node.id.peer),
1605                counter: node.id.counter,
1606            });
1607            id_to_idx.insert(node.id, idx);
1608        }
1609
1610        for p in position_set {
1611            position_register.register(&p);
1612        }
1613
1614        for node in input {
1615            let n = state.trees.get(&node.id).unwrap();
1616            let last_set_id = n.last_move_op;
1617            nodes.push(EncodedTreeNode {
1618                parent_idx_plus_two: match node.parent {
1619                    TreeParentId::Deleted => 1,
1620                    TreeParentId::Root => 0,
1621                    TreeParentId::Node(id) => id_to_idx.get(&id).unwrap() + 2,
1622                    TreeParentId::Unexist => unreachable!(),
1623                },
1624                last_set_peer_idx: peers.register(&last_set_id.peer),
1625                last_set_counter: last_set_id.counter,
1626                last_set_lamport_sub_counter: last_set_id.lamport as i32 - last_set_id.counter,
1627                fractional_index_idx: position_register.register(&node.fractional_index),
1628            })
1629        }
1630
1631        for node in deleted_nodes {
1632            let n = state.trees.get(&node.id).unwrap();
1633            let last_set_id = n.last_move_op;
1634            nodes.push(EncodedTreeNode {
1635                parent_idx_plus_two: match node.parent {
1636                    TreeParentId::Deleted => 1,
1637                    TreeParentId::Root => 0,
1638                    TreeParentId::Node(id) => id_to_idx.get(&id).unwrap() + 2,
1639                    TreeParentId::Unexist => unreachable!(),
1640                },
1641                last_set_peer_idx: peers.register(&last_set_id.peer),
1642                last_set_counter: last_set_id.counter,
1643                last_set_lamport_sub_counter: last_set_id.lamport as i32 - last_set_id.counter,
1644                fractional_index_idx: position_register.register(&node.fractional_index),
1645            })
1646        }
1647
1648        let position_vec = position_register.unwrap_vec();
1649        let positions = PositionArena::from_positions(position_vec.iter().map(|p| p.as_bytes()));
1650        (
1651            peers,
1652            EncodedTree {
1653                node_ids,
1654                nodes,
1655                fractional_indexes: positions.encode().into(),
1656                reserved_has_effect_bool_rle: vec![].into(),
1657            },
1658        )
1659    }
1660
1661    impl FastStateSnapshot for TreeState {
1662        /// Encodes the TreeState into a compact binary format for efficient serialization.
1663        ///
1664        /// The encoding schema:
1665        /// 1. Encodes all nodes using a breadth-first search traversal, ensuring a consistent order.
1666        /// 2. Uses a ValueRegister to deduplicate and index PeerIDs and TreeIDs, reducing redundancy.
1667        ///    - PeerIDs are stored once and referenced by index.
1668        ///    - TreeIDs are decomposed into peer index and counter for compact representation.
1669        /// 3. Encodes fractional indexes using a PositionArena for space efficiency
1670        /// 4. Utilizes delta encoding and run-length encoding for further size reduction:
1671        ///    - Delta encoding stores differences between consecutive values.
1672        ///    - Run-length encoding compresses sequences of repeated values.
1673        /// 5. Stores parent relationships using indices, with special values for root and deleted nodes.
1674        /// 6. Encodes last move operation details (peer_idx, counter[Delta], lamport clock[Delta]) for each node.
1675        fn encode_snapshot_fast<W: std::io::prelude::Write>(&mut self, mut w: W) {
1676            let all_alive_nodes = self.bfs_all_alive_nodes_for_fast_snapshot();
1677            let all_deleted_nodes = self.bfs_all_deleted_nodes_for_fast_snapshot();
1678            let (peers, encoded) = encode(self, all_alive_nodes, all_deleted_nodes);
1679            let peers = peers.unwrap_vec();
1680            leb128::write::unsigned(&mut w, peers.len() as u64).unwrap();
1681            for peer in peers {
1682                w.write_all(&peer.to_le_bytes()).unwrap();
1683            }
1684
1685            let vec = serde_columnar::to_vec(&encoded).unwrap();
1686            w.write_all(&vec).unwrap();
1687        }
1688
1689        fn decode_value(_: &[u8]) -> loro_common::LoroResult<(loro_common::LoroValue, &[u8])> {
1690            unreachable!()
1691        }
1692
1693        fn decode_snapshot_fast(
1694            idx: crate::container::idx::ContainerIdx,
1695            (_, mut bytes): (loro_common::LoroValue, &[u8]),
1696            ctx: crate::state::ContainerCreationContext,
1697        ) -> loro_common::LoroResult<Self>
1698        where
1699            Self: Sized,
1700        {
1701            let peer_num = leb128::read::unsigned(&mut bytes).unwrap() as usize;
1702            let mut peers = Vec::with_capacity(peer_num);
1703            for _ in 0..peer_num {
1704                let mut buf = [0u8; 8];
1705                bytes.read_exact(&mut buf).unwrap();
1706                peers.push(PeerID::from_le_bytes(buf));
1707            }
1708
1709            let mut tree = TreeState::new(idx, ctx.peer);
1710            let encoded: EncodedTree = serde_columnar::from_bytes(bytes)?;
1711            let fractional_indexes = PositionArena::decode(&encoded.fractional_indexes).unwrap();
1712            let fractional_indexes = fractional_indexes.parse_to_positions();
1713            let node_ids = encoded
1714                .node_ids
1715                .iter()
1716                .map(|x| TreeID::new(peers[x.peer_idx], x.counter))
1717                .collect_vec();
1718            for (node_id, node) in node_ids.iter().zip(encoded.nodes.into_iter()) {
1719                // PERF: we don't need to mov the deleted node, instead we can cache them
1720                // If the parent is TreeParentId::Deleted, then all the nodes afterwards are deleted
1721                tree._init_push_tree_node_in_order(
1722                    *node_id,
1723                    match node.parent_idx_plus_two {
1724                        0 => TreeParentId::Root,
1725                        1 => TreeParentId::Deleted,
1726                        n => {
1727                            let id = node_ids[n - 2];
1728                            TreeParentId::from(Some(id))
1729                        }
1730                    },
1731                    IdFull::new(
1732                        peers[node.last_set_peer_idx],
1733                        node.last_set_counter,
1734                        (node.last_set_lamport_sub_counter + node.last_set_counter) as Lamport,
1735                    ),
1736                    Some(FractionalIndex::from_bytes(
1737                        fractional_indexes[node.fractional_index_idx].clone(),
1738                    )),
1739                )
1740                .unwrap();
1741            }
1742
1743            Ok(tree)
1744        }
1745    }
1746}