feat: hierarchy children & parent

This commit is contained in:
leeeon233 2023-01-31 11:39:17 +08:00 committed by Leonzhao
parent 13becdb3f3
commit e402850440
4 changed files with 73 additions and 8 deletions

View file

@ -684,12 +684,9 @@ impl List {
self.with_container(|list| list.iter().enumerate().for_each(f))
}
// pub fn map<F: FnMut(&LoroValue) -> R, R>(
// &self,
// f: F,
// ) -> Map<impl Iterator<Item = &LoroValue>, F> {
// self.with_container(|list| list.iter().map(f))
// }
pub fn map<F: FnMut((usize, &LoroValue)) -> R, R>(&self, f: F) -> Vec<R> {
self.with_container(|list| list.iter().enumerate().map(f).collect())
}
#[must_use]
pub fn is_empty(&self) -> bool {
@ -735,7 +732,7 @@ impl ContainerWrapper for List {
#[cfg(test)]
mod test {
use crate::LoroCore;
use crate::{LoroCore, LoroValue, PrelimContainer};
#[test]
fn test_list_get() {
@ -787,4 +784,16 @@ mod test {
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\""]);
}
}

View file

@ -16,6 +16,8 @@ pub enum LoroError {
LockError,
#[error("LoroValue::Unresolved cannot be converted to PrelimValue")]
PrelimError,
#[error("Cannot find ({0}) ")]
NotFoundError(Box<str>),
// #[error("the data for key `{0}` is not available")]
// Redaction(String),
// #[error("invalid header (expected {expected:?}, found {found:?})")]

View file

@ -8,6 +8,7 @@ use fxhash::{FxHashMap, FxHashSet};
use crate::{
container::{registry::ContainerRegistry, ContainerID},
event::{Event, EventDispatch, Index, Observer, Path, PathAndTarget, RawEvent, SubscriptionID},
LoroError,
};
/// [`Hierarchy`] stores the hierarchical relationship between containers
@ -78,6 +79,20 @@ impl Hierarchy {
.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)]
pub fn contains(&self, id: &ContainerID) -> bool {
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
)
}
}

View file

@ -7,7 +7,7 @@ use crate::{
log_store::{EncodeConfig, LoroEncoder},
LoroError, LoroValue,
};
use fxhash::FxHashMap;
use fxhash::{FxHashMap, FxHashSet};
use tracing::instrument;
use crate::{
@ -79,6 +79,16 @@ impl LoroCore {
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
pub fn export(&self, remote_vv: VersionVector) -> FxHashMap<u64, Vec<Change<RemoteOp>>> {
let store = self.log_store.read().unwrap();