mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-08 21:47:41 +00:00
feat: hierarchy children & parent
This commit is contained in:
parent
13becdb3f3
commit
e402850440
4 changed files with 73 additions and 8 deletions
|
@ -684,12 +684,9 @@ impl List {
|
||||||
self.with_container(|list| list.iter().enumerate().for_each(f))
|
self.with_container(|list| list.iter().enumerate().for_each(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn map<F: FnMut(&LoroValue) -> R, R>(
|
pub fn map<F: FnMut((usize, &LoroValue)) -> R, R>(&self, f: F) -> Vec<R> {
|
||||||
// &self,
|
self.with_container(|list| list.iter().enumerate().map(f).collect())
|
||||||
// f: F,
|
}
|
||||||
// ) -> Map<impl Iterator<Item = &LoroValue>, F> {
|
|
||||||
// self.with_container(|list| list.iter().map(f))
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
|
@ -735,7 +732,7 @@ impl ContainerWrapper for List {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::LoroCore;
|
use crate::{LoroCore, LoroValue, PrelimContainer};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_get() {
|
fn test_list_get() {
|
||||||
|
@ -787,4 +784,16 @@ mod test {
|
||||||
assert_eq!(format!("\"{c}\""), v.to_json())
|
assert_eq!(format!("\"{c}\""), v.to_json())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn map() {
|
||||||
|
let mut loro = LoroCore::default();
|
||||||
|
let mut list = loro.get_list("list");
|
||||||
|
list.insert(&loro, 0, "a").unwrap();
|
||||||
|
list.insert(&loro, 1, "b").unwrap();
|
||||||
|
list.insert(&loro, 2, "c").unwrap();
|
||||||
|
// list.insert(&loro, 3, PrelimContainer::from("hello".to_string()))
|
||||||
|
// .unwrap();
|
||||||
|
assert_eq!(list.map(|(_, v)| v.to_json()),vec!["\"a\"", "\"b\"", "\"c\""]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ pub enum LoroError {
|
||||||
LockError,
|
LockError,
|
||||||
#[error("LoroValue::Unresolved cannot be converted to PrelimValue")]
|
#[error("LoroValue::Unresolved cannot be converted to PrelimValue")]
|
||||||
PrelimError,
|
PrelimError,
|
||||||
|
#[error("Cannot find ({0}) ")]
|
||||||
|
NotFoundError(Box<str>),
|
||||||
// #[error("the data for key `{0}` is not available")]
|
// #[error("the data for key `{0}` is not available")]
|
||||||
// Redaction(String),
|
// Redaction(String),
|
||||||
// #[error("invalid header (expected {expected:?}, found {found:?})")]
|
// #[error("invalid header (expected {expected:?}, found {found:?})")]
|
||||||
|
|
|
@ -8,6 +8,7 @@ use fxhash::{FxHashMap, FxHashSet};
|
||||||
use crate::{
|
use crate::{
|
||||||
container::{registry::ContainerRegistry, ContainerID},
|
container::{registry::ContainerRegistry, ContainerID},
|
||||||
event::{Event, EventDispatch, Index, Observer, Path, PathAndTarget, RawEvent, SubscriptionID},
|
event::{Event, EventDispatch, Index, Observer, Path, PathAndTarget, RawEvent, SubscriptionID},
|
||||||
|
LoroError,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// [`Hierarchy`] stores the hierarchical relationship between containers
|
/// [`Hierarchy`] stores the hierarchical relationship between containers
|
||||||
|
@ -78,6 +79,20 @@ impl Hierarchy {
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn children(&self, id: &ContainerID) -> Result<FxHashSet<ContainerID>, LoroError> {
|
||||||
|
self.nodes
|
||||||
|
.get(id)
|
||||||
|
.ok_or(LoroError::NotFoundError(format!("{:?}", id).into()))
|
||||||
|
.map(|node| node.children.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parent(&self, id: &ContainerID) -> Result<Option<ContainerID>, LoroError> {
|
||||||
|
self.nodes
|
||||||
|
.get(id)
|
||||||
|
.ok_or(LoroError::NotFoundError(format!("{:?}", id).into()))
|
||||||
|
.map(|node| node.parent.clone())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn contains(&self, id: &ContainerID) -> bool {
|
pub fn contains(&self, id: &ContainerID) -> bool {
|
||||||
self.nodes.get(id).is_some() || id.is_root()
|
self.nodes.get(id).is_some() || id.is_root()
|
||||||
|
@ -429,3 +444,32 @@ impl Hierarchy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use fxhash::FxHashMap;
|
||||||
|
|
||||||
|
use crate::{LoroCore, PrelimContainer};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn children_parent() {
|
||||||
|
let mut loro = LoroCore::default();
|
||||||
|
let mut list = loro.get_list("list");
|
||||||
|
let map_container_id = list
|
||||||
|
.push(&loro, PrelimContainer::from(FxHashMap::default()))
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
let list_container_id = list.id();
|
||||||
|
assert_eq!(
|
||||||
|
loro.children(&list_container_id)
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec![map_container_id.clone()]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
loro.parent(&map_container_id).unwrap().unwrap(),
|
||||||
|
list_container_id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
log_store::{EncodeConfig, LoroEncoder},
|
log_store::{EncodeConfig, LoroEncoder},
|
||||||
LoroError, LoroValue,
|
LoroError, LoroValue,
|
||||||
};
|
};
|
||||||
use fxhash::FxHashMap;
|
use fxhash::{FxHashMap, FxHashSet};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -79,6 +79,16 @@ impl LoroCore {
|
||||||
store.contains_container(id)
|
store.contains_container(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn children(&self, id: &ContainerID) -> Result<FxHashSet<ContainerID>, LoroError> {
|
||||||
|
let hierarchy = self.hierarchy.try_lock().unwrap();
|
||||||
|
hierarchy.children(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parent(&self, id: &ContainerID) -> Result<Option<ContainerID>, LoroError> {
|
||||||
|
let hierarchy = self.hierarchy.try_lock().unwrap();
|
||||||
|
hierarchy.parent(id)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: make it private
|
// TODO: make it private
|
||||||
pub fn export(&self, remote_vv: VersionVector) -> FxHashMap<u64, Vec<Change<RemoteOp>>> {
|
pub fn export(&self, remote_vv: VersionVector) -> FxHashMap<u64, Vec<Change<RemoteOp>>> {
|
||||||
let store = self.log_store.read().unwrap();
|
let store = self.log_store.read().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue