@@ -6,13 +6,139 @@ pub enum Parent {
6
6
Id ( Id ) ,
7
7
}
8
8
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
+
9
97
#[ derive( Debug , Clone , PartialEq ) ]
10
98
pub struct Item {
11
99
pub left_id : Option < Id > ,
12
100
pub right_id : Option < Id > ,
13
101
pub parent : Option < Parent > ,
14
102
pub parent_sub : Option < String > ,
15
103
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
+ }
16
142
}
17
143
18
144
impl Item {
@@ -21,14 +147,15 @@ impl Item {
21
147
info : u8 ,
22
148
first_5_bit : u8 ,
23
149
) -> JwstCodecResult < Self > {
24
- let has_left_id = info & 0b1000_0000 == 0b1000_0000 ;
25
- let has_right_id = info & 0b0100_0000 == 0b0100_0000 ;
26
- let has_parent_sub = info & 0b0010_0000 == 0b0010_0000 ;
27
- let has_not_parent_info = info & 0b1100_0000 == 0 ;
150
+ let flags: ItemFlags = info. into ( ) ;
151
+ let has_left_id = flags. check ( item_flags:: ITEM_HAS_LEFT_ID ) ;
152
+ let has_right_id = flags. check ( item_flags:: ITEM_HAS_RIGHT_ID ) ;
153
+ let has_parent_sub = flags. check ( item_flags:: ITEM_HAS_PARENT_SUB ) ;
154
+ let has_not_parent_info = !( has_left_id || has_right_id) ;
28
155
29
156
// NOTE: read order must keep the same as the order in yjs
30
157
// TODO: this data structure design will break the cpu OOE, need to be optimized
31
- let item = Self {
158
+ let mut item = Self {
32
159
left_id : if has_left_id {
33
160
Some ( decoder. read_item_id ( ) ?)
34
161
} else {
@@ -62,8 +189,13 @@ impl Item {
62
189
debug_assert_ne ! ( first_5_bit, 10 ) ;
63
190
Content :: read ( decoder, first_5_bit) ?
64
191
} ,
192
+ flags : ItemFlags :: from ( 0 ) ,
65
193
} ;
66
194
195
+ if item. content . countable ( ) {
196
+ item. flags . set_countable ( ) ;
197
+ }
198
+
67
199
Ok ( item)
68
200
}
69
201
@@ -72,16 +204,13 @@ impl Item {
72
204
// write info
73
205
let mut info = self . content . get_info ( ) ;
74
206
if self . left_id . is_some ( ) {
75
- info |= 0b1000_0000 ;
207
+ info |= item_flags :: ITEM_HAS_LEFT_ID ;
76
208
}
77
209
if self . right_id . is_some ( ) {
78
- info |= 0b0100_0000 ;
79
- }
80
- if self . parent . is_some ( ) || self . parent_sub . is_some ( ) {
81
- info |= 0b0010_0000 ;
210
+ info |= item_flags:: ITEM_HAS_RIGHT_ID ;
82
211
}
83
- if self . parent . is_none ( ) && self . parent_sub . is_none ( ) {
84
- info |= 0b0001_0000 ;
212
+ if self . parent_sub . is_some ( ) {
213
+ info |= item_flags :: ITEM_HAS_PARENT_SUB ;
85
214
}
86
215
encoder. write_info ( info) ?;
87
216
}
0 commit comments