Skip to content

Commit

Permalink
refactor: re-implement map type
Browse files Browse the repository at this point in the history
  • Loading branch information
forehalo committed Sep 15, 2023
1 parent 645c9c4 commit 178df5b
Show file tree
Hide file tree
Showing 14 changed files with 370 additions and 362 deletions.
2 changes: 1 addition & 1 deletion y-octo/bin/memory_leak_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fn run_map_test() {
let doc = Doc::default();
let mut map = doc.get_or_create_map("test").unwrap();
for (idx, key) in base_text.iter().enumerate() {
map.insert(key, idx).unwrap();
map.set(key.to_string(), idx).unwrap();
}
}
}
Expand Down
25 changes: 12 additions & 13 deletions y-octo/src/doc/codec/item.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use crate::sync::{Arc, AtomicU8, Ordering};
use crate::sync::{AtomicU8, Ordering};

#[derive(Debug, Clone)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
Expand Down Expand Up @@ -118,16 +118,15 @@ pub(crate) struct Item {
pub id: Id,
pub origin_left_id: Option<Id>,
pub origin_right_id: Option<Id>,
#[cfg_attr(all(test, not(loom)), proptest(value = "Somr::default()"))]
pub left: Somr<Item>,
#[cfg_attr(all(test, not(loom)), proptest(value = "Somr::default()"))]
pub right: Somr<Item>,
#[cfg_attr(all(test, not(loom)), proptest(value = "Somr::none()"))]
pub left: ItemRef,
#[cfg_attr(all(test, not(loom)), proptest(value = "Somr::none()"))]
pub right: ItemRef,
pub parent: Option<Parent>,
// TODO: Optmize
// use Box<str> and share it with same parent_sub items
pub parent_sub: Option<String>,
// make content Arc, so we can share the content between items
// and item can be readonly and cloned fast.
// TODO: considering using Cow
pub content: Arc<Content>,
pub content: Content,
#[cfg_attr(all(test, not(loom)), proptest(value = "ItemFlags::default()"))]
pub flags: ItemFlags,
}
Expand Down Expand Up @@ -187,7 +186,7 @@ impl Default for Item {
right: Somr::none(),
parent: None,
parent_sub: None,
content: Arc::new(Content::Deleted(0)),
content: Content::Deleted(0),
flags: ItemFlags::from(0),
}
}
Expand Down Expand Up @@ -216,7 +215,7 @@ impl Item {
right,
parent,
parent_sub,
content: Arc::new(content),
content,
flags,
}
}
Expand Down Expand Up @@ -364,7 +363,7 @@ impl Item {
// tag must not GC or Skip, this must process in parse_struct
debug_assert_ne!(first_5_bit, 0);
debug_assert_ne!(first_5_bit, 10);
Arc::new(Content::read(decoder, first_5_bit)?)
Content::read(decoder, first_5_bit)?
},
left: Somr::none(),
right: Somr::none(),
Expand All @@ -375,7 +374,7 @@ impl Item {
item.flags.set_countable();
}

if matches!(item.content.as_ref(), Content::Deleted(_)) {
if matches!(item.content, Content::Deleted(_)) {
item.flags.set_deleted();
}

Expand Down
6 changes: 2 additions & 4 deletions y-octo/src/doc/codec/refs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use sync::Arc;

use super::*;

// make fields Copy + Clone without much effort
Expand Down Expand Up @@ -81,7 +79,7 @@ impl Node {
_ => {
let item = Somr::new(Item::read(decoder, id, info, first_5_bit)?);

if let Content::Type(ty) = item.get().unwrap().content.as_ref() {
if let Content::Type(ty) = &item.get().unwrap().content {
if let Some(mut ty) = ty.ty_mut() {
ty.item = item.clone();
}
Expand Down Expand Up @@ -271,7 +269,7 @@ impl Node {
return false;
}

match (Arc::make_mut(&mut litem.content), Arc::make_mut(&mut ritem.content)) {
match (&mut litem.content, &mut ritem.content) {
(Content::Deleted(l), Content::Deleted(r)) => {
*l += *r;
}
Expand Down
5 changes: 2 additions & 3 deletions y-octo/src/doc/codec/utils/items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::{item::item_flags, *};
use crate::sync::Arc;

pub(crate) struct ItemBuilder {
item: Item,
Expand Down Expand Up @@ -54,7 +53,7 @@ impl ItemBuilder {
}

pub fn content(mut self, content: Content) -> ItemBuilder {
self.item.content = Arc::new(content);
self.item.content = content;
self
}

Expand Down Expand Up @@ -92,7 +91,7 @@ mod tests {
assert_eq!(item.origin_right_id, Some(Id::new(4, 5)));
assert!(matches!(item.parent, Some(Parent::String(text)) if text == "test"));
assert_eq!(item.parent_sub, None);
assert_eq!(item.content, Arc::new(Content::Any(vec![Any::String("Hello".into())])));
assert_eq!(item.content, Content::Any(vec![Any::String("Hello".into())]));
});
}
}
2 changes: 1 addition & 1 deletion y-octo/src/doc/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ mod tests {
let doc = Doc::new();

let mut map = doc.get_or_create_map("abc").unwrap();
map.insert("a", 1).unwrap();
map.set("a".to_string(), 1).unwrap();
let binary = doc.encode_update_v1().unwrap();

let doc_new = Doc::new();
Expand Down
12 changes: 6 additions & 6 deletions y-octo/src/doc/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl DocStore {
histories.push(RawHistory {
id: item.id.to_string(),
parent,
content: Value::try_from(item.content.as_ref())
content: Value::try_from(&item.content)
.map(|v| v.to_string())
.unwrap_or("unknown".to_owned()),
})
Expand All @@ -159,8 +159,8 @@ mod test {
let doc = Doc::default();
let mut map = doc.get_or_create_map("map").unwrap();
let mut sub_map = doc.create_map().unwrap();
map.insert("sub_map", sub_map.clone()).unwrap();
sub_map.insert("key", "value").unwrap();
map.set("sub_map".to_string(), sub_map.clone()).unwrap();
sub_map.set("key".to_string(), "value").unwrap();

assert_eq!(doc.clients()[0], doc.client());
});
Expand All @@ -172,8 +172,8 @@ mod test {
let doc = Doc::default();
let mut map = doc.get_or_create_map("map").unwrap();
let mut sub_map = doc.create_map().unwrap();
map.insert("sub_map", sub_map.clone()).unwrap();
sub_map.insert("key", "value").unwrap();
map.set("sub_map".to_string(), sub_map.clone()).unwrap();
sub_map.set("key".to_string(), "value").unwrap();

let history = doc.store.read().unwrap().history(0).unwrap();

Expand All @@ -191,7 +191,7 @@ mod test {
mock_histories.push(RawHistory {
id: item.id.to_string(),
parent,
content: Value::try_from(item.content.as_ref())
content: Value::try_from(&item.content)
.map(|v| v.to_string())
.unwrap_or("unknown".to_owned()),
})
Expand Down
43 changes: 13 additions & 30 deletions y-octo/src/doc/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl DocStore {
let id = (self.client(), self.get_state(self.client())).into();
let item = Somr::new(Item::new(id, content, left, right, parent, parent_sub));

if let Content::Type(ty) = item.get().unwrap().content.as_ref() {
if let Content::Type(ty) = &item.get().unwrap().content {
if let Some(mut ty) = ty.ty_mut() {
ty.item = item.clone();
}
Expand Down Expand Up @@ -375,15 +375,12 @@ impl DocStore {
Some(Parent::Id(parent_id)) => {
match self.get_node(*parent_id) {
Some(Node::Item(parent_item)) => {
match &parent_item.get().unwrap().content.as_ref() {
Content::Type(ty) => {
item.parent.replace(Parent::Type(ty.clone()));
}
_ => {
// invalid parent, take it.
item.parent.take();
// return Err(JwstCodecError::InvalidParent);
}
if let Content::Type(ty) = &parent_item.get().unwrap().content {
item.parent.replace(Parent::Type(ty.clone()));
} else {
// invalid parent, take it.
item.parent.take();
// return Err(JwstCodecError::InvalidParent);
}
}
_ => {
Expand All @@ -406,7 +403,7 @@ impl DocStore {
};

// assign store in ytype to ensure store exists if a ytype not has any children
if let Content::Type(ty) = Arc::make_mut(&mut item.content) {
if let Content::Type(ty) = &mut item.content {
ty.store = Arc::downgrade(&store_ref);

// we keep ty owner in dangling_types so the delete of any type will not make it
Expand Down Expand Up @@ -450,7 +447,7 @@ impl DocStore {
this.origin_left_id = left_ref.get().map(|left| left.last_id());
this.left = left_ref;
}
this.content = Arc::new(this.content.split(offset)?.1);
this.content = this.content.split(offset)?.1;
}

if let Some(Parent::Type(ty)) = &this.parent {
Expand Down Expand Up @@ -618,7 +615,7 @@ impl DocStore {
}
}

match item.content.as_ref() {
match &item.content {
Content::Type(ty) => {
if let Some(mut ty) = ty.ty_mut() {
// items in ty are all refs, not owned
Expand Down Expand Up @@ -850,7 +847,7 @@ impl DocStore {
let _ = mem::replace(&mut items[idx], Node::new_gc(item.id, item.len()));
} else {
let mut item = unsafe { item_ref.get_mut_unchecked() };
item.content = Arc::new(Content::Deleted(item.len()));
item.content = Content::Deleted(item.len());
item.flags.clear_countable();
debug_assert!(!item.flags.countable());
}
Expand Down Expand Up @@ -1141,14 +1138,7 @@ mod tests {
store.gc_delete_set().unwrap();

assert_eq!(
store
.get_node((1, 0))
.unwrap()
.as_item()
.get()
.unwrap()
.content
.as_ref(),
&store.get_node((1, 0)).unwrap().as_item().get().unwrap().content,
&Content::Deleted(4)
);
});
Expand All @@ -1173,14 +1163,7 @@ mod tests {

assert_eq!(arr.len(), 0);
assert_eq!(
store
.get_node((1, 0))
.unwrap()
.as_item()
.get()
.unwrap()
.content
.as_ref(),
&store.get_node((1, 0)).unwrap().as_item().get().unwrap().content,
&Content::Deleted(1)
);

Expand Down
10 changes: 5 additions & 5 deletions y-octo/src/doc/types/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl Iterator for ArrayIter {
for item in self.0.by_ref() {
if let Some(item) = item.get() {
if item.countable() {
return Some(item.content.as_ref().try_into().unwrap());
return Some(Value::try_from(&item.content).unwrap());
}
}
}
Expand All @@ -39,9 +39,9 @@ impl Array {
debug_assert!(offset == 0);
if let Some(item) = item.get() {
// TODO: rewrite to content.read(&mut [Any])
return match item.content.as_ref() {
return match &item.content {
Content::Any(any) => return any.first().map(|any| Value::Any(any.clone())),
_ => item.content.as_ref().try_into().map_or_else(|_| None, Some),
_ => Value::try_from(&item.content).map_or_else(|_| None, Some),
};
}

Expand Down Expand Up @@ -83,8 +83,6 @@ impl serde::Serialize for Array {

#[cfg(test)]
mod tests {
use yrs::{Array, Options, Text, Transact};

use super::*;

#[test]
Expand All @@ -108,6 +106,7 @@ mod tests {
#[test]
#[cfg_attr(miri, ignore)]
fn test_ytext_equal() {
use yrs::{Options, Text, Transact};
let options = DocOptions::default();
let yrs_options = Options::default();

Expand Down Expand Up @@ -166,6 +165,7 @@ mod tests {
#[test]
#[cfg_attr(miri, ignore)]
fn test_yrs_array_decode() {
use yrs::{Array, Transact};
let update = {
let doc = yrs::Doc::new();
let array = doc.get_or_insert_array("abc");
Expand Down
1 change: 1 addition & 0 deletions y-octo/src/doc/types/list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub(crate) trait ListType: AsInner<Inner = YTypeRef> {

fn iter_item(&self) -> ListIterator {
let inner = self.as_inner().ty().unwrap();
// TODO: should we keep the lock in iteration?
ListIterator::new(inner.start.clone())
}

Expand Down
Loading

0 comments on commit 178df5b

Please sign in to comment.