11use crate :: local_storage:: kv:: keys:: * ;
22use crate :: local_storage:: kv:: snapshot:: SnapshotAction ;
33use crate :: local_storage:: kv:: * ;
4+ use collab:: core:: collab:: { CollabVersion , VersionedData } ;
45use smallvec:: { SmallVec , smallvec} ;
56use std:: collections:: HashSet ;
67use tracing:: { error, info} ;
1920 uid : i64 ,
2021 workspace_id : & str ,
2122 object_id : & str ,
23+ collab_version : Option < & CollabVersion > ,
2224 txn : & T ,
2325 ) -> Result < ( ) , PersistenceError > {
2426 if self . is_exist ( uid, workspace_id, object_id) {
2830 let doc_id = get_or_create_did ( uid, self , workspace_id, object_id) ?;
2931 let doc_state = txn. encode_diff_v1 ( & StateVector :: default ( ) ) ;
3032 let sv = txn. state_vector ( ) . encode_v1 ( ) ;
31- let doc_state_key = make_doc_state_key ( doc_id) ;
33+ let doc_state_key = make_doc_state_key ( doc_id, collab_version ) ;
3234 let sv_key = make_state_vector_key ( doc_id) ;
3335
3436 info ! ( "new doc:{:?}, doc state len:{}" , object_id, doc_state. len( ) ) ;
4345 uid : i64 ,
4446 workspace_id : & str ,
4547 object_id : & str ,
48+ collab_version : Option < & CollabVersion > ,
4649 state_vector : Vec < u8 > ,
4750 doc_state : Vec < u8 > ,
4851 ) -> Result < ( ) , PersistenceError > {
5154 let end = make_doc_end_key ( doc_id) ;
5255 self . remove_range ( start. as_ref ( ) , end. as_ref ( ) ) ?;
5356
54- let doc_state_key = make_doc_state_key ( doc_id) ;
57+ let doc_state_key = make_doc_state_key ( doc_id, collab_version ) ;
5558 let sv_key = make_state_vector_key ( doc_id) ;
5659
5760 info ! ( "new doc:{:?}, doc state len:{}" , object_id, doc_state. len( ) ) ;
7376 uid : i64 ,
7477 workspace_id : & str ,
7578 object_id : & str ,
79+ collab_version : Option < & CollabVersion > ,
7680 state_vector : Vec < u8 > ,
7781 doc_state : Vec < u8 > ,
7882 ) -> Result < ( ) , PersistenceError > {
8387 let end = make_doc_end_key ( doc_id) ;
8488 self . remove_range ( start. as_ref ( ) , end. as_ref ( ) ) ?;
8589
86- let doc_state_key = make_doc_state_key ( doc_id) ;
90+ let doc_state_key = make_doc_state_key ( doc_id, collab_version ) ;
8791 let sv_key = make_state_vector_key ( doc_id) ;
8892 // Insert new doc state and state vector
8993 self . insert ( doc_state_key, doc_state) ?;
9599 get_doc_id ( uid, self , workspace_id, object_id) . is_some ( )
96100 }
97101
102+ fn get_doc_state ( & self , doc_id : DocID ) -> Result < Option < VersionedData > , PersistenceError > {
103+ let doc_state_start = make_doc_start_key ( doc_id) ;
104+ let doc_state_end = make_doc_end_key ( doc_id) ;
105+ let mut cursor = self . range ( doc_state_start. clone ( ) ..doc_state_end) ?;
106+ if let Some ( entry) = cursor. next ( ) {
107+ let key = entry. key ( ) ;
108+ let value = entry. value ( ) ;
109+ if key. starts_with ( doc_state_start. as_ref ( ) ) {
110+ let version = if key. len ( ) > doc_state_start. len ( ) {
111+ let collab_version: [ u8 ; 16 ] =
112+ match key[ doc_state_start. len ( ) ..doc_state_start. len ( ) + 16 ] . try_into ( ) {
113+ Ok ( v) => v,
114+ Err ( _) => {
115+ return Err ( PersistenceError :: InvalidData ( format ! (
116+ "invalid collab version in doc state key: {:?}" ,
117+ key
118+ ) ) ) ;
119+ } ,
120+ } ;
121+ Some ( CollabVersion :: from_bytes ( collab_version) )
122+ } else {
123+ None
124+ } ;
125+ return Ok ( Some ( VersionedData :: new ( value, version) ) ) ;
126+ }
127+ }
128+ Ok ( None )
129+ }
130+
98131 /// Load the document from the database and apply the updates to the transaction.
99132 /// It will try to load the document in these two ways:
100133 /// 1. D = document state + updates
@@ -107,15 +140,14 @@ where
107140 workspace_id : & str ,
108141 object_id : & str ,
109142 txn : & mut TransactionMut ,
110- ) -> Result < u32 , PersistenceError > {
143+ ) -> Result < Option < CollabVersion > , PersistenceError > {
111144 let mut update_count = 0 ;
145+ let mut collab_version = None ;
112146
113147 if let Some ( doc_id) = get_doc_id ( uid, self , workspace_id, object_id) {
114- let doc_state_key = make_doc_state_key ( doc_id) ;
115- if let Some ( doc_state) = self . get ( doc_state_key. as_ref ( ) ) ? {
148+ if let Some ( versioned) = self . get_doc_state ( doc_id) ? {
116149 // Load the doc state
117-
118- match Update :: decode_v1 ( doc_state. as_ref ( ) ) {
150+ match Update :: decode_v1 ( & versioned. data ) {
119151 Ok ( update) => {
120152 txn. try_apply_update ( update) ?;
121153 } ,
@@ -125,6 +157,8 @@ where
125157 } ,
126158 }
127159
160+ collab_version = versioned. version ;
161+
128162 // If the enable_snapshot is true, we will try to load the snapshot.
129163 let update_start = make_doc_update_key ( doc_id, 0 ) . to_vec ( ) ;
130164 let update_end = make_doc_update_key ( doc_id, Clock :: MAX ) ;
@@ -155,7 +189,7 @@ where
155189 ) ;
156190 }
157191
158- Ok ( update_count )
192+ Ok ( collab_version )
159193 } else {
160194 tracing:: trace!( "[Client] => {:?} not exist" , object_id) ;
161195 Err ( PersistenceError :: RecordNotFound ( format ! (
@@ -171,7 +205,7 @@ where
171205 workspace_id : & str ,
172206 object_id : & str ,
173207 doc : & Doc ,
174- ) -> Result < u32 , PersistenceError > {
208+ ) -> Result < Option < CollabVersion > , PersistenceError > {
175209 let mut txn = doc. transact_mut ( ) ;
176210 self . load_doc_with_txn ( uid, workspace_id, object_id, & mut txn)
177211 }
@@ -182,6 +216,7 @@ where
182216 uid : i64 ,
183217 workspace_id : & str ,
184218 object_id : & str ,
219+ version : Option < & CollabVersion > ,
185220 update : & [ u8 ] ,
186221 ) -> Result < Vec < u8 > , PersistenceError > {
187222 match get_doc_id ( uid, self , workspace_id, object_id) {
@@ -196,7 +231,7 @@ where
196231 object_id
197232 ) ) )
198233 } ,
199- Some ( doc_id) => insert_doc_update ( self , doc_id, object_id, update. to_vec ( ) ) ,
234+ Some ( doc_id) => insert_doc_update ( self , doc_id, object_id, version , update. to_vec ( ) ) ,
200235 }
201236 }
202237
@@ -234,6 +269,7 @@ where
234269 uid : i64 ,
235270 workspace_id : & str ,
236271 object_id : & str ,
272+ version : Option < & CollabVersion > ,
237273 doc_state : & [ u8 ] ,
238274 sv : & [ u8 ] ,
239275 ) -> Result < ( ) , PersistenceError > {
@@ -242,7 +278,7 @@ where
242278 let end = make_doc_end_key ( doc_id) ;
243279 self . remove_range ( start. as_ref ( ) , end. as_ref ( ) ) ?;
244280
245- let doc_state_key = make_doc_state_key ( doc_id) ;
281+ let doc_state_key = make_doc_state_key ( doc_id, version ) ;
246282 let sv_key = make_state_vector_key ( doc_id) ;
247283
248284 // Insert new doc state and state vector
@@ -294,10 +330,9 @@ where
294330 self . remove_range ( start. as_ref ( ) , end. as_ref ( ) ) ?;
295331
296332 // Delete the document state and the state vector
297- let doc_state_key = make_doc_state_key ( did) ;
298- let sv_key = make_state_vector_key ( did) ;
299- let _ = self . remove ( doc_state_key. as_ref ( ) ) ;
300- let _ = self . remove ( sv_key. as_ref ( ) ) ;
333+ let doc_state_key = make_doc_start_key ( did) ;
334+ let sv_key = make_doc_end_key ( did) ;
335+ let _ = self . remove_range ( doc_state_key. as_ref ( ) , sv_key. as_ref ( ) ) ;
301336
302337 // Delete the snapshot
303338 self . delete_all_snapshots ( uid, object_id) ?;
0 commit comments