11use super :: * ;
22use crate :: doc:: StateVector ;
3+ use std:: collections:: VecDeque ;
34use std:: {
45 cell:: { Ref , RefCell , RefMut } ,
56 collections:: { hash_map:: Entry , HashMap } ,
@@ -10,6 +11,21 @@ use std::{
1011#[ derive( Clone , PartialEq , Debug ) ]
1112pub struct StructRef ( Arc < RefCell < StructInfo > > ) ;
1213
14+ impl StructRef {
15+ pub fn read < R : CrdtReader > ( decoder : & mut R , id : Id ) -> JwstCodecResult < Self > {
16+ match StructInfo :: read ( decoder, id) {
17+ Ok ( info) => Ok ( info. into ( ) ) ,
18+ Err ( err) => Err ( err) ,
19+ }
20+ }
21+ }
22+
23+ impl < W : CrdtWriter > CrdtWrite < W > for StructRef {
24+ fn write ( & self , writer : & mut W ) -> JwstCodecResult {
25+ self . 0 . borrow ( ) . write ( writer)
26+ }
27+ }
28+
1329impl From < StructInfo > for StructRef {
1430 fn from ( info : StructInfo ) -> Self {
1531 Self ( Arc :: new ( RefCell :: new ( info) ) )
@@ -91,8 +107,10 @@ impl StructRef {
91107#[ derive( Default ) ]
92108pub struct DocStore {
93109 pub items : Arc < RwLock < HashMap < Client , Vec < StructRef > > > > ,
94- pub types : Arc < RwLock < HashMap < String , TypeStoreRef > > > ,
95110 pub delete_set : Arc < RwLock < DeleteSet > > ,
111+
112+ // following fields are only used in memory
113+ pub types : Arc < RwLock < HashMap < String , TypeStoreRef > > > ,
96114 pub pending : Option < Update > ,
97115}
98116
@@ -361,6 +379,77 @@ impl DocStore {
361379 delete_set. add ( id. client , id. clock , len)
362380 }
363381 }
382+
383+ fn diff_state_vectors (
384+ local_state_vector : & StateVector ,
385+ remote_state_vector : & StateVector ,
386+ ) -> Vec < ( Client , Clock ) > {
387+ let mut diff = Vec :: new ( ) ;
388+
389+ for ( client, & remote_clock) in remote_state_vector. iter ( ) {
390+ let local_clock = local_state_vector. get ( client) ;
391+ if local_clock > remote_clock {
392+ diff. push ( ( * client, remote_clock) ) ;
393+ }
394+ }
395+
396+ for ( client, _) in local_state_vector. iter ( ) {
397+ if remote_state_vector. get ( client) == 0 {
398+ diff. push ( ( * client, 0 ) ) ;
399+ }
400+ }
401+
402+ diff
403+ }
404+
405+ pub fn encode_with_state_vector < W : CrdtWriter > (
406+ & self ,
407+ sv : & StateVector ,
408+ encoder : & mut W ,
409+ ) -> JwstCodecResult {
410+ let local_state_vector = self . get_state_vector ( ) ;
411+ let diff = Self :: diff_state_vectors ( & local_state_vector, sv) ;
412+ let mut update_structs: HashMap < u64 , VecDeque < StructInfo > > = HashMap :: new ( ) ;
413+
414+ for ( client, clock) in diff {
415+ // We have made sure that the client is in the local state vector in diff_state_vectors()
416+ if let Some ( items) = self . items . read ( ) . unwrap ( ) . get ( & client) {
417+ if items. is_empty ( ) {
418+ continue ;
419+ }
420+
421+ update_structs. insert ( client, VecDeque :: new ( ) ) ;
422+ let vec_struct_info = update_structs. get_mut ( & client) . unwrap ( ) ;
423+
424+ // the smallest clock in items may exceed the clock
425+ let clock = items. first ( ) . unwrap ( ) . id ( ) . clock . max ( clock) ;
426+ if let Some ( index) = Self :: get_item_index ( items, clock) {
427+ let first_block = items. get ( index) . unwrap ( ) ;
428+ let offset = first_block. clock ( ) - clock;
429+ if offset != 0 {
430+ // needs to implement Content split first
431+ unimplemented ! ( )
432+ } else {
433+ vec_struct_info. push_back ( first_block. borrow ( ) . clone ( ) ) ;
434+ }
435+
436+ for item in items. iter ( ) . skip ( index + 1 ) {
437+ vec_struct_info. push_back ( item. borrow ( ) . clone ( ) ) ;
438+ }
439+ }
440+ }
441+ }
442+
443+ let update = Update {
444+ structs : update_structs,
445+ delete_set : self . delete_set . read ( ) . unwrap ( ) . clone ( ) ,
446+ ..Update :: default ( )
447+ } ;
448+
449+ update. write ( encoder) ?;
450+
451+ Ok ( ( ) )
452+ }
364453}
365454
366455#[ cfg( test) ]
0 commit comments