@@ -14,8 +14,8 @@ use crate::{
1414 LoroValue ,
1515} ;
1616use append_only_bytes:: BytesSlice ;
17- use rustc_hash:: FxHashMap ;
1817use loro_common:: PeerID ;
18+ use rustc_hash:: FxHashMap ;
1919use std:: fmt;
2020use std:: {
2121 num:: NonZeroU16 ,
@@ -111,10 +111,11 @@ impl ArenaGuards<'_> {
111111 if let Some ( d) = get_depth (
112112 p,
113113 & mut self . depth ,
114- & self . parents ,
114+ & mut self . parents ,
115115 & self . parent_resolver ,
116116 & mut self . container_idx_to_id ,
117117 & mut self . container_id_to_idx ,
118+ & mut self . root_c_idx ,
118119 ) {
119120 self . depth [ child. to_index ( ) as usize ] = NonZeroU16 :: new ( d. get ( ) + 1 ) ;
120121 } else {
@@ -263,23 +264,26 @@ impl SharedArena {
263264
264265 #[ inline]
265266 pub fn set_parent ( & self , child : ContainerIdx , parent : Option < ContainerIdx > ) {
266- let parents = & mut self . inner . parents . lock ( ) . unwrap ( ) ;
267+ let mut parents = self . inner . parents . lock ( ) . unwrap ( ) ;
267268 parents. insert ( child, parent) ;
268269 let mut depth = self . inner . depth . lock ( ) . unwrap ( ) ;
270+ let mut root_c_idx = self . inner . root_c_idx . lock ( ) . unwrap ( ) ;
269271
270272 match parent {
271273 Some ( p) => {
272274 // Acquire the two maps as mutable guards so we can lazily register
273275 // unknown parents while computing depth.
274276 let mut idx_to_id_guard = self . inner . container_idx_to_id . lock ( ) . unwrap ( ) ;
275277 let mut id_to_idx_guard = self . inner . container_id_to_idx . lock ( ) . unwrap ( ) ;
278+ let parent_resolver_guard = self . inner . parent_resolver . lock ( ) . unwrap ( ) ;
276279 if let Some ( d) = get_depth (
277280 p,
278281 & mut depth,
279- parents,
280- & self . inner . parent_resolver . lock ( ) . unwrap ( ) ,
282+ & mut parents,
283+ & parent_resolver_guard ,
281284 & mut idx_to_id_guard,
282285 & mut id_to_idx_guard,
286+ & mut root_c_idx,
283287 ) {
284288 depth[ child. to_index ( ) as usize ] = NonZeroU16 :: new ( d. get ( ) + 1 ) ;
285289 } else {
@@ -564,21 +568,21 @@ impl SharedArena {
564568
565569 // TODO: this can return a u16 directly now, since the depths are always valid
566570 pub ( crate ) fn get_depth ( & self , container : ContainerIdx ) -> Option < NonZeroU16 > {
567- {
568- let mut depth_guard = self . inner . depth . lock ( ) . unwrap ( ) ;
569- let parents_guard = self . inner . parents . lock ( ) . unwrap ( ) ;
570- let resolver_guard = self . inner . parent_resolver . lock ( ) . unwrap ( ) ;
571- let mut idx_to_id_guard = self . inner . container_idx_to_id . lock ( ) . unwrap ( ) ;
572- let mut id_to_idx_guard = self . inner . container_id_to_idx . lock ( ) . unwrap ( ) ;
573- get_depth (
574- container,
575- & mut depth_guard,
576- & parents_guard,
577- & resolver_guard,
578- & mut idx_to_id_guard,
579- & mut id_to_idx_guard,
580- )
581- }
571+ let mut depth_guard = self . inner . depth . lock ( ) . unwrap ( ) ;
572+ let mut parents_guard = self . inner . parents . lock ( ) . unwrap ( ) ;
573+ let mut root_c_idx_guard = self . inner . root_c_idx . lock ( ) . unwrap ( ) ;
574+ let resolver_guard = self . inner . parent_resolver . lock ( ) . unwrap ( ) ;
575+ let mut idx_to_id_guard = self . inner . container_idx_to_id . lock ( ) . unwrap ( ) ;
576+ let mut id_to_idx_guard = self . inner . container_id_to_idx . lock ( ) . unwrap ( ) ;
577+ get_depth (
578+ container,
579+ & mut depth_guard,
580+ & mut parents_guard,
581+ & resolver_guard,
582+ & mut idx_to_id_guard,
583+ & mut id_to_idx_guard,
584+ & mut root_c_idx_guard ,
585+ )
582586 }
583587
584588 pub ( crate ) fn iter_value_slice (
@@ -662,10 +666,11 @@ fn _slice_str(range: Range<usize>, s: &mut StrArena) -> String {
662666fn get_depth (
663667 target : ContainerIdx ,
664668 depth : & mut Vec < Option < NonZeroU16 > > ,
665- parents : & FxHashMap < ContainerIdx , Option < ContainerIdx > > ,
669+ parents : & mut FxHashMap < ContainerIdx , Option < ContainerIdx > > ,
666670 parent_resolver : & Option < Arc < ParentResolver > > ,
667671 idx_to_id : & mut Vec < ContainerID > ,
668672 id_to_idx : & mut FxHashMap < ContainerID , ContainerIdx > ,
673+ root_c_idx : & mut Vec < ContainerIdx > ,
669674) -> Option < NonZeroU16 > {
670675 let mut d = depth[ target. to_index ( ) as usize ] ;
671676 if d. is_some ( ) {
@@ -680,6 +685,8 @@ fn get_depth(
680685 None
681686 } else if let Some ( parent_resolver) = parent_resolver. as_ref ( ) {
682687 let parent_id = parent_resolver ( id. clone ( ) ) ?;
688+ let parent_is_root = parent_id. is_root ( ) ;
689+ let mut parent_was_new = false ;
683690 // If the parent is not registered yet, register it lazily instead of unwrapping.
684691 let parent_idx = if let Some ( idx) = id_to_idx. get ( & parent_id) . copied ( ) {
685692 idx
@@ -690,13 +697,27 @@ fn get_depth(
690697 ContainerIdx :: from_index_and_type ( new_index as u32 , parent_id. container_type ( ) ) ;
691698 id_to_idx. insert ( parent_id. clone ( ) , new_idx) ;
692699 // Keep depth vector in sync with containers list.
693- if parent_id . is_root ( ) {
700+ if parent_is_root {
694701 depth. push ( NonZeroU16 :: new ( 1 ) ) ;
695702 } else {
696703 depth. push ( None ) ;
697704 }
705+ parent_was_new = true ;
698706 new_idx
699707 } ;
708+
709+ if parent_is_root {
710+ if parent_was_new {
711+ parents. insert ( parent_idx, None ) ;
712+ root_c_idx. push ( parent_idx) ;
713+ } else {
714+ parents. entry ( parent_idx) . or_insert ( None ) ;
715+ }
716+ if depth[ parent_idx. to_index ( ) as usize ] . is_none ( ) {
717+ depth[ parent_idx. to_index ( ) as usize ] = NonZeroU16 :: new ( 1 ) ;
718+ }
719+ }
720+
700721 Some ( parent_idx)
701722 } else {
702723 return None ;
@@ -706,7 +727,17 @@ fn get_depth(
706727 match parent {
707728 Some ( p) => {
708729 d = NonZeroU16 :: new (
709- get_depth ( p, depth, parents, parent_resolver, idx_to_id, id_to_idx) ?. get ( ) + 1 ,
730+ get_depth (
731+ p,
732+ depth,
733+ parents,
734+ parent_resolver,
735+ idx_to_id,
736+ id_to_idx,
737+ root_c_idx,
738+ ) ?
739+ . get ( )
740+ + 1 ,
710741 ) ;
711742 depth[ target. to_index ( ) as usize ] = d;
712743 }
0 commit comments