1mod str_arena;
2use self::str_arena::StrArena;
3use crate::sync::{Mutex, MutexGuard};
4use crate::{
5 change::Lamport,
6 container::{
7 idx::ContainerIdx,
8 list::list_op::{InnerListOp, ListOp},
9 map::MapSet,
10 ContainerID,
11 },
12 id::Counter,
13 op::{InnerContent, ListSlice, Op, RawOp, RawOpContent, SliceRange},
14 LoroValue,
15};
16use append_only_bytes::BytesSlice;
17use rustc_hash::FxHashMap;
18use loro_common::PeerID;
19use std::fmt;
20use std::{
21 num::NonZeroU16,
22 ops::{Range, RangeBounds},
23 sync::Arc,
24};
25
26pub(crate) struct LoadAllFlag;
27type ParentResolver = dyn Fn(ContainerID) -> Option<ContainerID> + Send + Sync + 'static;
28
29#[derive(Default)]
30struct InnerSharedArena {
31 container_idx_to_id: Mutex<Vec<ContainerID>>,
34 depth: Mutex<Vec<Option<NonZeroU16>>>,
36 container_id_to_idx: Mutex<FxHashMap<ContainerID, ContainerIdx>>,
37 parents: Mutex<FxHashMap<ContainerIdx, Option<ContainerIdx>>>,
39 values: Mutex<Vec<LoroValue>>,
40 root_c_idx: Mutex<Vec<ContainerIdx>>,
41 str: Arc<Mutex<StrArena>>,
42 parent_resolver: Mutex<Option<Arc<ParentResolver>>>,
45}
46
47impl fmt::Debug for InnerSharedArena {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 f.debug_struct("InnerSharedArena")
50 .field("container_idx_to_id", &"<Mutex<_>>")
51 .field("depth", &"<Mutex<_>>")
52 .field("container_id_to_idx", &"<Mutex<_>>")
53 .field("parents", &"<Mutex<_>>")
54 .field("values", &"<Mutex<_>>")
55 .field("root_c_idx", &"<Mutex<_>>")
56 .field("str", &"<Arc<Mutex<_>>>")
57 .field("parent_resolver", &"<Mutex<Option<...>>>")
58 .finish()
59 }
60}
61
62#[derive(Debug, Clone)]
65pub struct SharedArena {
66 inner: Arc<InnerSharedArena>,
67}
68
69#[derive(Debug)]
70pub struct StrAllocResult {
71 pub start: usize,
73 pub end: usize,
75}
76
77pub(crate) struct ArenaGuards<'a> {
78 container_id_to_idx: MutexGuard<'a, FxHashMap<ContainerID, ContainerIdx>>,
79 container_idx_to_id: MutexGuard<'a, Vec<ContainerID>>,
80 depth: MutexGuard<'a, Vec<Option<NonZeroU16>>>,
81 parents: MutexGuard<'a, FxHashMap<ContainerIdx, Option<ContainerIdx>>>,
82 root_c_idx: MutexGuard<'a, Vec<ContainerIdx>>,
83 parent_resolver: MutexGuard<'a, Option<Arc<ParentResolver>>>,
84}
85
86impl ArenaGuards<'_> {
87 pub fn register_container(&mut self, id: &ContainerID) -> ContainerIdx {
88 if let Some(&idx) = self.container_id_to_idx.get(id) {
89 return idx;
90 }
91
92 let idx = self.container_idx_to_id.len();
93 self.container_idx_to_id.push(id.clone());
94 let idx = ContainerIdx::from_index_and_type(idx as u32, id.container_type());
95 self.container_id_to_idx.insert(id.clone(), idx);
96 if id.is_root() {
97 self.root_c_idx.push(idx);
98 self.parents.insert(idx, None);
99 self.depth.push(NonZeroU16::new(1));
100 } else {
101 self.depth.push(None);
102 }
103 idx
104 }
105
106 pub fn set_parent(&mut self, child: ContainerIdx, parent: Option<ContainerIdx>) {
107 self.parents.insert(child, parent);
108
109 match parent {
110 Some(p) => {
111 if let Some(d) = get_depth(
112 p,
113 &mut self.depth,
114 &self.parents,
115 &self.parent_resolver,
116 &mut self.container_idx_to_id,
117 &mut self.container_id_to_idx,
118 ) {
119 self.depth[child.to_index() as usize] = NonZeroU16::new(d.get() + 1);
120 } else {
121 self.depth[child.to_index() as usize] = None;
122 }
123 }
124 None => {
125 self.depth[child.to_index() as usize] = NonZeroU16::new(1);
126 }
127 }
128 }
129}
130
131impl SharedArena {
132 #[allow(clippy::new_without_default)]
133 pub fn new() -> Self {
134 Self {
135 inner: Arc::new(InnerSharedArena::default()),
136 }
137 }
138
139 pub fn fork(&self) -> Self {
140 Self {
141 inner: Arc::new(InnerSharedArena {
142 container_idx_to_id: Mutex::new(
143 self.inner.container_idx_to_id.lock().unwrap().clone(),
144 ),
145 depth: Mutex::new(self.inner.depth.lock().unwrap().clone()),
146 container_id_to_idx: Mutex::new(
147 self.inner.container_id_to_idx.lock().unwrap().clone(),
148 ),
149 parents: Mutex::new(self.inner.parents.lock().unwrap().clone()),
150 values: Mutex::new(self.inner.values.lock().unwrap().clone()),
151 root_c_idx: Mutex::new(self.inner.root_c_idx.lock().unwrap().clone()),
152 str: self.inner.str.clone(),
153 parent_resolver: Mutex::new(self.inner.parent_resolver.lock().unwrap().clone()),
154 }),
155 }
156 }
157
158 pub(crate) fn with_guards(&self, f: impl FnOnce(&mut ArenaGuards)) {
159 let mut guards = self.get_arena_guards();
160 f(&mut guards);
161 }
162
163 fn get_arena_guards(&self) -> ArenaGuards<'_> {
164 ArenaGuards {
165 container_id_to_idx: self.inner.container_id_to_idx.lock().unwrap(),
166 container_idx_to_id: self.inner.container_idx_to_id.lock().unwrap(),
167 depth: self.inner.depth.lock().unwrap(),
168 parents: self.inner.parents.lock().unwrap(),
169 root_c_idx: self.inner.root_c_idx.lock().unwrap(),
170 parent_resolver: self.inner.parent_resolver.lock().unwrap(),
171 }
172 }
173
174 pub fn register_container(&self, id: &ContainerID) -> ContainerIdx {
175 let mut container_id_to_idx = self.inner.container_id_to_idx.lock().unwrap();
176 if let Some(&idx) = container_id_to_idx.get(id) {
177 return idx;
178 }
179
180 let mut container_idx_to_id = self.inner.container_idx_to_id.lock().unwrap();
181 let idx = container_idx_to_id.len();
182 container_idx_to_id.push(id.clone());
183 let idx = ContainerIdx::from_index_and_type(idx as u32, id.container_type());
184 container_id_to_idx.insert(id.clone(), idx);
185 if id.is_root() {
186 self.inner.root_c_idx.lock().unwrap().push(idx);
187 self.inner.parents.lock().unwrap().insert(idx, None);
188 self.inner.depth.lock().unwrap().push(NonZeroU16::new(1));
189 } else {
190 self.inner.depth.lock().unwrap().push(None);
191 }
192 idx
193 }
194
195 pub fn get_container_id(&self, idx: ContainerIdx) -> Option<ContainerID> {
196 let lock = self.inner.container_idx_to_id.lock().unwrap();
197 lock.get(idx.to_index() as usize).cloned()
198 }
199
200 pub fn id_to_idx(&self, id: &ContainerID) -> Option<ContainerIdx> {
210 self.inner
211 .container_id_to_idx
212 .lock()
213 .unwrap()
214 .get(id)
215 .copied()
216 }
217
218 #[inline]
219 pub fn idx_to_id(&self, id: ContainerIdx) -> Option<ContainerID> {
220 let lock = self.inner.container_idx_to_id.lock().unwrap();
221 lock.get(id.to_index() as usize).cloned()
222 }
223
224 #[inline]
225 pub fn with_idx_to_id<R>(&self, f: impl FnOnce(&Vec<ContainerID>) -> R) -> R {
226 let lock = self.inner.container_idx_to_id.lock().unwrap();
227 f(&lock)
228 }
229
230 pub fn alloc_str(&self, str: &str) -> StrAllocResult {
231 let mut text_lock = self.inner.str.lock().unwrap();
232 _alloc_str(&mut text_lock, str)
233 }
234
235 pub fn alloc_str_with_slice(&self, str: &str) -> (BytesSlice, StrAllocResult) {
237 let mut text_lock = self.inner.str.lock().unwrap();
238 _alloc_str_with_slice(&mut text_lock, str)
239 }
240
241 pub fn alloc_str_fast(&self, bytes: &[u8]) {
243 let mut text_lock = self.inner.str.lock().unwrap();
244 text_lock.alloc(std::str::from_utf8(bytes).unwrap());
245 }
246
247 #[inline]
248 pub fn utf16_len(&self) -> usize {
249 self.inner.str.lock().unwrap().len_utf16()
250 }
251
252 #[inline]
253 pub fn alloc_value(&self, value: LoroValue) -> usize {
254 let mut values_lock = self.inner.values.lock().unwrap();
255 _alloc_value(&mut values_lock, value)
256 }
257
258 #[inline]
259 pub fn alloc_values(&self, values: impl Iterator<Item = LoroValue>) -> std::ops::Range<usize> {
260 let mut values_lock = self.inner.values.lock().unwrap();
261 _alloc_values(&mut values_lock, values)
262 }
263
264 #[inline]
265 pub fn set_parent(&self, child: ContainerIdx, parent: Option<ContainerIdx>) {
266 let parents = &mut self.inner.parents.lock().unwrap();
267 parents.insert(child, parent);
268 let mut depth = self.inner.depth.lock().unwrap();
269
270 match parent {
271 Some(p) => {
272 let mut idx_to_id_guard = self.inner.container_idx_to_id.lock().unwrap();
275 let mut id_to_idx_guard = self.inner.container_id_to_idx.lock().unwrap();
276 if let Some(d) = get_depth(
277 p,
278 &mut depth,
279 parents,
280 &self.inner.parent_resolver.lock().unwrap(),
281 &mut idx_to_id_guard,
282 &mut id_to_idx_guard,
283 ) {
284 depth[child.to_index() as usize] = NonZeroU16::new(d.get() + 1);
285 } else {
286 depth[child.to_index() as usize] = None;
287 }
288 }
289 None => {
290 depth[child.to_index() as usize] = NonZeroU16::new(1);
291 }
292 }
293 }
294
295 pub fn log_hierarchy(&self) {
296 if cfg!(debug_assertions) {
297 for (c, p) in self.inner.parents.lock().unwrap().iter() {
298 tracing::info!(
299 "container {:?} {:?} {:?}",
300 c,
301 self.get_container_id(*c),
302 p.map(|x| self.get_container_id(x))
303 );
304 }
305 }
306 }
307
308 pub fn log_all_containers(&self) {
309 self.inner
310 .container_id_to_idx
311 .lock()
312 .unwrap()
313 .iter()
314 .for_each(|(id, idx)| {
315 tracing::info!("container {:?} {:?}", id, idx);
316 });
317 self.inner
318 .container_idx_to_id
319 .lock()
320 .unwrap()
321 .iter()
322 .enumerate()
323 .for_each(|(i, id)| {
324 tracing::info!("container {} {:?}", i, id);
325 });
326 }
327
328 pub fn get_parent(&self, child: ContainerIdx) -> Option<ContainerIdx> {
329 if self.get_container_id(child).unwrap().is_root() {
330 return None;
333 }
334
335 if let Some(p) = self.inner.parents.lock().unwrap().get(&child).copied() {
337 return p;
338 }
339
340 let resolver = self.inner.parent_resolver.lock().unwrap().clone();
342 if let Some(resolver) = resolver {
343 let child_id = self.get_container_id(child).unwrap();
344 if let Some(parent_id) = resolver(child_id.clone()) {
345 let parent_idx = self.register_container(&parent_id);
346 self.set_parent(child, Some(parent_idx));
347 return Some(parent_idx);
348 }
349 }
350
351 panic!("InternalError: Parent is not registered")
352 }
353
354 pub fn with_ancestors(&self, container: ContainerIdx, mut f: impl FnMut(ContainerIdx, bool)) {
358 let mut container = Some(container);
359 let mut is_first = true;
360 while let Some(c) = container {
361 f(c, is_first);
362 is_first = false;
363 container = self.get_parent(c)
364 }
365 }
366
367 #[inline]
368 pub fn slice_by_unicode(&self, range: impl RangeBounds<usize>) -> BytesSlice {
369 self.inner.str.lock().unwrap().slice_by_unicode(range)
370 }
371
372 #[inline]
373 pub fn slice_by_utf8(&self, range: impl RangeBounds<usize>) -> BytesSlice {
374 self.inner.str.lock().unwrap().slice_bytes(range)
375 }
376
377 #[inline]
378 pub fn slice_str_by_unicode_range(&self, range: Range<usize>) -> String {
379 let mut s = self.inner.str.lock().unwrap();
380 let s: &mut StrArena = &mut s;
381 let mut ans = String::with_capacity(range.len());
382 ans.push_str(s.slice_str_by_unicode(range));
383 ans
384 }
385
386 #[inline]
387 pub fn with_text_slice(&self, range: Range<usize>, mut f: impl FnMut(&str)) {
388 f(self.inner.str.lock().unwrap().slice_str_by_unicode(range))
389 }
390
391 #[inline]
392 pub fn get_value(&self, idx: usize) -> Option<LoroValue> {
393 self.inner.values.lock().unwrap().get(idx).cloned()
394 }
395
396 #[inline]
397 pub fn get_values(&self, range: Range<usize>) -> Vec<LoroValue> {
398 (self.inner.values.lock().unwrap()[range]).to_vec()
399 }
400
401 pub fn convert_single_op(
402 &self,
403 container: &ContainerID,
404 peer: PeerID,
405 counter: Counter,
406 lamport: Lamport,
407 content: RawOpContent,
408 ) -> Op {
409 let container = self.register_container(container);
410 self.inner_convert_op(content, peer, counter, lamport, container)
411 }
412
413 pub fn can_import_snapshot(&self) -> bool {
414 self.inner.str.lock().unwrap().is_empty() && self.inner.values.lock().unwrap().is_empty()
415 }
416
417 fn inner_convert_op(
418 &self,
419 content: RawOpContent<'_>,
420 _peer: PeerID,
421 counter: i32,
422 _lamport: Lamport,
423 container: ContainerIdx,
424 ) -> Op {
425 match content {
426 crate::op::RawOpContent::Map(MapSet { key, value }) => Op {
427 counter,
428 container,
429 content: crate::op::InnerContent::Map(MapSet { key, value }),
430 },
431 crate::op::RawOpContent::List(list) => match list {
432 ListOp::Insert { slice, pos } => match slice {
433 ListSlice::RawData(values) => {
434 let range = self.alloc_values(values.iter().cloned());
435 Op {
436 counter,
437 container,
438 content: crate::op::InnerContent::List(InnerListOp::Insert {
439 slice: SliceRange::from(range.start as u32..range.end as u32),
440 pos,
441 }),
442 }
443 }
444 ListSlice::RawStr { str, unicode_len } => {
445 let (slice, info) = self.alloc_str_with_slice(&str);
446 Op {
447 counter,
448 container,
449 content: crate::op::InnerContent::List(InnerListOp::InsertText {
450 slice,
451 unicode_start: info.start as u32,
452 unicode_len: unicode_len as u32,
453 pos: pos as u32,
454 }),
455 }
456 }
457 },
458 ListOp::Delete(span) => Op {
459 counter,
460 container,
461 content: crate::op::InnerContent::List(InnerListOp::Delete(span)),
462 },
463 ListOp::StyleStart {
464 start,
465 end,
466 info,
467 key,
468 value,
469 } => Op {
470 counter,
471 container,
472 content: InnerContent::List(InnerListOp::StyleStart {
473 start,
474 end,
475 key,
476 info,
477 value,
478 }),
479 },
480 ListOp::StyleEnd => Op {
481 counter,
482 container,
483 content: InnerContent::List(InnerListOp::StyleEnd),
484 },
485 ListOp::Move {
486 from,
487 to,
488 elem_id: from_id,
489 } => Op {
490 counter,
491 container,
492 content: InnerContent::List(InnerListOp::Move {
493 from,
494 to,
495 elem_id: from_id,
496 }),
497 },
498 ListOp::Set { elem_id, value } => Op {
499 counter,
500 container,
501 content: InnerContent::List(InnerListOp::Set { elem_id, value }),
502 },
503 },
504 crate::op::RawOpContent::Tree(tree) => Op {
505 counter,
506 container,
507 content: crate::op::InnerContent::Tree(tree.clone()),
508 },
509 #[cfg(feature = "counter")]
510 crate::op::RawOpContent::Counter(c) => Op {
511 counter,
512 container,
513 content: crate::op::InnerContent::Future(crate::op::FutureInnerContent::Counter(c)),
514 },
515 crate::op::RawOpContent::Unknown { prop, value } => Op {
516 counter,
517 container,
518 content: crate::op::InnerContent::Future(crate::op::FutureInnerContent::Unknown {
519 prop,
520 value: Box::new(value),
521 }),
522 },
523 }
524 }
525
526 #[inline]
527 pub fn convert_raw_op(&self, op: &RawOp) -> Op {
528 self.inner_convert_op(
529 op.content.clone(),
530 op.id.peer,
531 op.id.counter,
532 op.lamport,
533 op.container,
534 )
535 }
536
537 #[inline]
538 pub fn export_containers(&self) -> Vec<ContainerID> {
539 self.inner.container_idx_to_id.lock().unwrap().clone()
540 }
541
542 pub fn export_parents(&self) -> Vec<Option<ContainerIdx>> {
543 let parents = self.inner.parents.lock().unwrap();
544 let containers = self.inner.container_idx_to_id.lock().unwrap();
545 containers
546 .iter()
547 .enumerate()
548 .map(|(x, id)| {
549 let idx = ContainerIdx::from_index_and_type(x as u32, id.container_type());
550 let parent_idx = parents.get(&idx)?;
551 *parent_idx
552 })
553 .collect()
554 }
555
556 #[inline]
561 pub(crate) fn root_containers(&self, _f: LoadAllFlag) -> Vec<ContainerIdx> {
562 self.inner.root_c_idx.lock().unwrap().clone()
563 }
564
565 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 }
582 }
583
584 pub(crate) fn iter_value_slice(
585 &self,
586 range: Range<usize>,
587 ) -> impl Iterator<Item = LoroValue> + '_ {
588 let values = self.inner.values.lock().unwrap();
589 range
590 .into_iter()
591 .map(move |i| values.get(i).unwrap().clone())
592 }
593
594 pub(crate) fn get_root_container_idx_by_key(
595 &self,
596 root_index: &loro_common::InternalString,
597 ) -> Option<ContainerIdx> {
598 let inner = self.inner.container_id_to_idx.lock().unwrap();
599 for t in loro_common::ContainerType::ALL_TYPES.iter() {
600 let cid = ContainerID::Root {
601 name: root_index.clone(),
602 container_type: *t,
603 };
604 if let Some(idx) = inner.get(&cid) {
605 return Some(*idx);
606 }
607 }
608 None
609 }
610
611 #[allow(unused)]
612 pub(crate) fn log_all_values(&self) {
613 let values = self.inner.values.lock().unwrap();
614 for (i, v) in values.iter().enumerate() {
615 loro_common::debug!("value {} {:?}", i, v);
616 }
617 }
618}
619
620fn _alloc_str_with_slice(
621 text_lock: &mut MutexGuard<'_, StrArena>,
622 str: &str,
623) -> (BytesSlice, StrAllocResult) {
624 let start = text_lock.len_bytes();
625 let ans = _alloc_str(text_lock, str);
626 (text_lock.slice_bytes(start..), ans)
627}
628
629fn _alloc_values(
630 values_lock: &mut MutexGuard<'_, Vec<LoroValue>>,
631 values: impl Iterator<Item = LoroValue>,
632) -> Range<usize> {
633 values_lock.reserve(values.size_hint().0);
634 let start = values_lock.len();
635 for value in values {
636 values_lock.push(value);
637 }
638
639 start..values_lock.len()
640}
641
642fn _alloc_value(values_lock: &mut MutexGuard<'_, Vec<LoroValue>>, value: LoroValue) -> usize {
643 values_lock.push(value);
644 values_lock.len() - 1
645}
646
647fn _alloc_str(text_lock: &mut MutexGuard<'_, StrArena>, str: &str) -> StrAllocResult {
648 let start = text_lock.len_unicode();
649 text_lock.alloc(str);
650 StrAllocResult {
651 start,
652 end: text_lock.len_unicode(),
653 }
654}
655
656fn _slice_str(range: Range<usize>, s: &mut StrArena) -> String {
657 let mut ans = String::with_capacity(range.len());
658 ans.push_str(s.slice_str_by_unicode(range));
659 ans
660}
661
662fn get_depth(
663 target: ContainerIdx,
664 depth: &mut Vec<Option<NonZeroU16>>,
665 parents: &FxHashMap<ContainerIdx, Option<ContainerIdx>>,
666 parent_resolver: &Option<Arc<ParentResolver>>,
667 idx_to_id: &mut Vec<ContainerID>,
668 id_to_idx: &mut FxHashMap<ContainerID, ContainerIdx>,
669) -> Option<NonZeroU16> {
670 let mut d = depth[target.to_index() as usize];
671 if d.is_some() {
672 return d;
673 }
674
675 let parent: Option<ContainerIdx> = if let Some(p) = parents.get(&target) {
676 *p
677 } else {
678 let id = idx_to_id.get(target.to_index() as usize).unwrap();
679 if id.is_root() {
680 None
681 } else if let Some(parent_resolver) = parent_resolver.as_ref() {
682 let parent_id = parent_resolver(id.clone())?;
683 let parent_idx = if let Some(idx) = id_to_idx.get(&parent_id).copied() {
685 idx
686 } else {
687 let new_index = idx_to_id.len();
688 idx_to_id.push(parent_id.clone());
689 let new_idx =
690 ContainerIdx::from_index_and_type(new_index as u32, parent_id.container_type());
691 id_to_idx.insert(parent_id.clone(), new_idx);
692 if parent_id.is_root() {
694 depth.push(NonZeroU16::new(1));
695 } else {
696 depth.push(None);
697 }
698 new_idx
699 };
700 Some(parent_idx)
701 } else {
702 return None;
703 }
704 };
705
706 match parent {
707 Some(p) => {
708 d = NonZeroU16::new(
709 get_depth(p, depth, parents, parent_resolver, idx_to_id, id_to_idx)?.get() + 1,
710 );
711 depth[target.to_index() as usize] = d;
712 }
713 None => {
714 depth[target.to_index() as usize] = NonZeroU16::new(1);
715 d = NonZeroU16::new(1);
716 }
717 }
718
719 d
720}
721
722impl SharedArena {
723 pub fn set_parent_resolver<F>(&self, resolver: Option<F>)
729 where
730 F: Fn(ContainerID) -> Option<ContainerID> + Send + Sync + 'static,
731 {
732 let mut slot = self.inner.parent_resolver.lock().unwrap();
733 *slot = resolver.map(|f| Arc::new(f) as Arc<ParentResolver>);
734 }
735}