Skip to content

Commit f2f5e7a

Browse files
committed
feat: impl delete set
1 parent 9c13538 commit f2f5e7a

File tree

10 files changed

+766
-91
lines changed

10 files changed

+766
-91
lines changed

libs/jwst-codec/src/doc/codec/content.rs

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ impl Content {
4545
}
4646
}
4747

48+
pub fn countable(&self) -> bool {
49+
!matches!(self, Content::Format { .. } | Content::Deleted(_))
50+
}
51+
4852
pub fn split(&self, diff: u64) -> JwstCodecResult<(Content, Content)> {
4953
// TODO: implement split for other types
5054
match self {

libs/jwst-codec/src/doc/codec/item.rs

+137-5
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,139 @@ pub enum Parent {
66
Id(Id),
77
}
88

9+
#[rustfmt::skip]
10+
#[allow(dead_code)]
11+
pub mod item_flags {
12+
pub const ITEM_KEEP : u8 = 0b0000_0001;
13+
pub const ITEM_COUNTABLE : u8 = 0b0000_0010;
14+
pub const ITEM_DELETED : u8 = 0b0000_0100;
15+
pub const ITEM_MARKED : u8 = 0b0000_1000;
16+
pub const ITEM_HAS_PARENT_SUB : u8 = 0b0010_0000;
17+
pub const ITEM_HAS_RIGHT_ID : u8 = 0b0100_0000;
18+
pub const ITEM_HAS_LEFT_ID : u8 = 0b1000_0000;
19+
}
20+
21+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
22+
pub struct ItemFlags(u8);
23+
24+
impl From<u8> for ItemFlags {
25+
fn from(flags: u8) -> Self {
26+
Self(flags)
27+
}
28+
}
29+
30+
impl ItemFlags {
31+
#[inline(always)]
32+
pub fn set(&mut self, flag: u8) {
33+
self.0 |= flag;
34+
}
35+
36+
#[inline(always)]
37+
pub fn clear(&mut self, flag: u8) {
38+
self.0 &= !flag;
39+
}
40+
41+
#[inline(always)]
42+
pub fn check(&self, flag: u8) -> bool {
43+
self.0 & flag == flag
44+
}
45+
46+
#[inline(always)]
47+
pub fn not(&self, flag: u8) -> bool {
48+
self.0 & flag == 0
49+
}
50+
51+
#[inline(always)]
52+
pub fn keep(&self) -> bool {
53+
self.check(item_flags::ITEM_KEEP)
54+
}
55+
56+
#[inline(always)]
57+
pub fn set_keep(&mut self) {
58+
self.set(item_flags::ITEM_KEEP);
59+
}
60+
61+
#[inline(always)]
62+
pub fn clear_keep(&mut self) {
63+
self.clear(item_flags::ITEM_KEEP);
64+
}
65+
66+
#[inline(always)]
67+
pub fn countable(&self) -> bool {
68+
self.check(item_flags::ITEM_COUNTABLE)
69+
}
70+
71+
#[inline(always)]
72+
pub fn set_countable(&mut self) {
73+
self.set(item_flags::ITEM_COUNTABLE);
74+
}
75+
76+
#[inline(always)]
77+
pub fn clear_countable(&mut self) {
78+
self.clear(item_flags::ITEM_COUNTABLE);
79+
}
80+
81+
#[inline(always)]
82+
pub fn deleted(&self) -> bool {
83+
self.check(item_flags::ITEM_DELETED)
84+
}
85+
86+
#[inline(always)]
87+
pub fn set_deleted(&mut self) {
88+
self.set(item_flags::ITEM_DELETED);
89+
}
90+
91+
#[inline(always)]
92+
pub fn clear_deleted(&mut self) {
93+
self.clear(item_flags::ITEM_DELETED);
94+
}
95+
}
96+
997
#[derive(Debug, Clone, PartialEq)]
1098
pub struct Item {
1199
pub left_id: Option<Id>,
12100
pub right_id: Option<Id>,
13101
pub parent: Option<Parent>,
14102
pub parent_sub: Option<String>,
15103
pub content: Content,
104+
pub flags: ItemFlags,
105+
}
106+
107+
impl Default for Item {
108+
fn default() -> Self {
109+
Self {
110+
left_id: None,
111+
right_id: None,
112+
parent: None,
113+
parent_sub: None,
114+
content: Content::String("".into()),
115+
flags: ItemFlags::from(item_flags::ITEM_COUNTABLE),
116+
}
117+
}
118+
}
119+
120+
impl Item {
121+
pub fn is_empty(&self) -> bool {
122+
self.len() == 0
123+
}
124+
125+
pub fn len(&self) -> u64 {
126+
self.content.clock_len()
127+
}
128+
129+
pub fn deleted(&self) -> bool {
130+
self.flags.deleted()
131+
}
132+
133+
pub fn delete(&mut self) {
134+
if self.deleted() {
135+
return;
136+
}
137+
138+
// self.content.delete();
139+
140+
self.flags.deleted();
141+
}
16142
}
17143

18144
fn read_has_parent(input: &[u8]) -> IResult<&[u8], bool> {
@@ -23,14 +149,15 @@ fn read_has_parent(input: &[u8]) -> IResult<&[u8], bool> {
23149

24150
pub fn read_item(input: &[u8], info: u8, first_5_bit: u8) -> IResult<&[u8], Item> {
25151
let mut input = input;
26-
let has_left_id = info & 0b1000_0000 == 0b1000_0000;
27-
let has_right_id = info & 0b0100_0000 == 0b0100_0000;
28-
let has_parent_sub = info & 0b0010_0000 == 0b0010_0000;
29-
let has_not_parent_info = info & 0b1100_0000 == 0;
152+
let flags: ItemFlags = info.into();
153+
let has_left_id = flags.check(item_flags::ITEM_HAS_LEFT_ID);
154+
let has_right_id = flags.check(item_flags::ITEM_HAS_RIGHT_ID);
155+
let has_parent_sub = flags.check(item_flags::ITEM_HAS_PARENT_SUB);
156+
let has_not_parent_info = !(has_left_id || has_right_id);
30157

31158
// NOTE: read order must keep the same as the order in yjs
32159
// TODO: this data structure design will break the cpu OOE, need to be optimized
33-
let item = Item {
160+
let mut item = Item {
34161
left_id: if has_left_id {
35162
let (tail, id) = read_item_id(input)?;
36163
input = tail;
@@ -77,7 +204,12 @@ pub fn read_item(input: &[u8], info: u8, first_5_bit: u8) -> IResult<&[u8], Item
77204
input = tail;
78205
content
79206
},
207+
flags: ItemFlags::from(0),
80208
};
81209

210+
if item.content.countable() {
211+
item.flags.set_countable();
212+
}
213+
82214
Ok((input, item))
83215
}

libs/jwst-codec/src/doc/codec/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod update;
88
pub use any::Any;
99
pub use content::{Content, YType};
1010
pub use id::{Client, Clock, Id};
11-
pub use item::{Item, Parent};
11+
pub use item::{item_flags, Item, ItemFlags, Parent};
1212
pub use refs::StructInfo;
1313
pub use update::{read_update, Update, UpdateIterator};
1414

libs/jwst-codec/src/doc/codec/refs.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ impl StructInfo {
6767
matches!(self, StructInfo::Item { .. })
6868
}
6969

70+
pub fn flags(&self) -> ItemFlags {
71+
match self {
72+
StructInfo::Item { item, .. } => item.flags,
73+
_ => ItemFlags::from(0),
74+
}
75+
}
76+
7077
pub fn item(&self) -> Option<&Item> {
7178
if let Self::Item { item, .. } = self {
7279
Some(item.as_ref())
@@ -107,36 +114,35 @@ impl StructInfo {
107114
}
108115
}
109116

110-
pub fn split_item(&self, diff: u64) -> JwstCodecResult<(Self, Self)> {
117+
pub fn split_item(&mut self, diff: u64) -> JwstCodecResult<Self> {
111118
if let Self::Item { id, item } = self {
112119
let right_id = Id::new(id.client, id.clock + diff);
113120
let (left_content, right_content) = item.content.split(diff)?;
114121

115-
let left_item = StructInfo::Item {
116-
id: *id,
117-
item: Box::new(Item {
118-
right_id: Some(right_id),
119-
content: left_content,
120-
..item.as_ref().clone()
121-
}),
122-
};
122+
item.right_id = Some(right_id);
123+
item.content = left_content;
123124

124125
let right_item = StructInfo::Item {
125126
id: right_id,
126127
item: Box::new(Item {
127128
left_id: Some(Id::new(id.client, id.clock + diff - 1)),
128129
right_id: item.right_id,
129-
parent: item.parent.clone(),
130-
parent_sub: item.parent_sub.clone(),
131130
content: right_content,
131+
..item.as_ref().clone()
132132
}),
133133
};
134134

135-
Ok((left_item, right_item))
135+
Ok(right_item)
136136
} else {
137137
Err(JwstCodecError::ItemSplitNotSupport)
138138
}
139139
}
140+
141+
pub fn delete(&mut self) {
142+
if let StructInfo::Item { item, .. } = self {
143+
item.delete()
144+
}
145+
}
140146
}
141147

142148
fn read_struct(input: &[u8]) -> IResult<&[u8], RawStructInfo> {

0 commit comments

Comments
 (0)