mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-11 14:53:12 +00:00
feat: readonly arena
This commit is contained in:
parent
fd588beee2
commit
cc4e1d02e4
1 changed files with 63 additions and 2 deletions
|
@ -7,8 +7,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This is shared between [OpLog] and [AppState].
|
/// This is shared between [OpLog] and [AppState].
|
||||||
/// It uses a immutable data structure inside so that we have O(1) clone time.
|
/// It only takes O(1) to have a readonly view cloned.
|
||||||
/// It can make sharing data between threads easier.
|
/// It makes ownership problem easier.
|
||||||
///
|
///
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub(super) struct SharedArena {
|
pub(super) struct SharedArena {
|
||||||
|
@ -20,6 +20,15 @@ pub(super) struct SharedArena {
|
||||||
values: Vector<LoroValue>,
|
values: Vector<LoroValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) struct ReadonlyArena {
|
||||||
|
container_idx_to_id: Vector<ContainerID>,
|
||||||
|
container_id_to_idx: im::HashMap<ContainerID, ContainerIdx>,
|
||||||
|
/// The parent of each container.
|
||||||
|
parents: im::HashMap<ContainerIdx, Option<ContainerIdx>>,
|
||||||
|
bytes: BytesSlice,
|
||||||
|
values: Vector<LoroValue>,
|
||||||
|
}
|
||||||
|
|
||||||
impl SharedArena {
|
impl SharedArena {
|
||||||
pub fn register_container(&mut self, id: &ContainerID) -> ContainerIdx {
|
pub fn register_container(&mut self, id: &ContainerID) -> ContainerIdx {
|
||||||
if let Some(&idx) = self.container_id_to_idx.get(id) {
|
if let Some(&idx) = self.container_id_to_idx.get(id) {
|
||||||
|
@ -60,4 +69,56 @@ impl SharedArena {
|
||||||
|
|
||||||
(start, self.values.len())
|
(start, self.values.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_readonly(&self) -> ReadonlyArena {
|
||||||
|
ReadonlyArena {
|
||||||
|
container_idx_to_id: self.container_idx_to_id.clone(),
|
||||||
|
container_id_to_idx: self.container_id_to_idx.clone(),
|
||||||
|
parents: self.parents.clone(),
|
||||||
|
bytes: self.bytes.slice(..),
|
||||||
|
values: self.values.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_parent(&mut self, child: ContainerIdx, parent: Option<ContainerIdx>) {
|
||||||
|
self.parents.insert(child, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_parent(&self, child: ContainerIdx) -> Option<ContainerIdx> {
|
||||||
|
self.parents.get(&child).copied().flatten()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn slice_bytes(&self, range: std::ops::Range<usize>) -> &[u8] {
|
||||||
|
&self.bytes[range]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_value(&self, idx: usize) -> Option<&LoroValue> {
|
||||||
|
self.values.get(idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_value_mut(&mut self, idx: usize) -> Option<&mut LoroValue> {
|
||||||
|
self.values.get_mut(idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReadonlyArena {
|
||||||
|
pub fn id_to_idx(&self, id: &ContainerID) -> Option<ContainerIdx> {
|
||||||
|
self.container_id_to_idx.get(id).copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn idx_to_id(&self, id: ContainerIdx) -> Option<&ContainerID> {
|
||||||
|
self.container_idx_to_id.get(id.to_u32() as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn slice_bytes(&self, range: std::ops::Range<usize>) -> &[u8] {
|
||||||
|
&self.bytes[range]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_value(&self, idx: usize) -> Option<&LoroValue> {
|
||||||
|
self.values.get(idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_parent(&self, child: ContainerIdx) -> Option<ContainerIdx> {
|
||||||
|
self.parents.get(&child).copied().flatten()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue