@@ -2,7 +2,7 @@ use crate::dochandle::{DocHandle, SharedDocument};
2
2
use crate :: interfaces:: { DocumentId , RepoId } ;
3
3
use crate :: interfaces:: { NetworkError , RepoMessage , Storage , StorageError } ;
4
4
use automerge:: sync:: { Message as SyncMessage , State as SyncState , SyncDoc } ;
5
- use automerge:: Automerge ;
5
+ use automerge:: { Automerge , ChangeHash } ;
6
6
use core:: pin:: Pin ;
7
7
use crossbeam_channel:: { select, unbounded, Receiver , Sender } ;
8
8
use futures:: future:: Future ;
@@ -527,6 +527,8 @@ pub(crate) struct DocumentInfo {
527
527
/// Counter of patches since last save,
528
528
/// used to make decisions about full or incemental saves.
529
529
patches_since_last_save : usize ,
530
+ /// Last heads obtained from the automerge doc.
531
+ last_heads : Vec < ChangeHash > ,
530
532
}
531
533
532
534
impl DocumentInfo {
@@ -535,13 +537,18 @@ impl DocumentInfo {
535
537
document : Arc < RwLock < SharedDocument > > ,
536
538
handle_count : Arc < AtomicUsize > ,
537
539
) -> Self {
540
+ let last_heads = {
541
+ let doc = document. read ( ) ;
542
+ doc. automerge . get_heads ( )
543
+ } ;
538
544
DocumentInfo {
539
545
state,
540
546
document,
541
547
handle_count,
542
548
sync_states : Default :: default ( ) ,
543
549
change_observers : Default :: default ( ) ,
544
550
patches_since_last_save : 0 ,
551
+ last_heads,
545
552
}
546
553
}
547
554
@@ -663,8 +670,14 @@ impl DocumentInfo {
663
670
/// Count patches since last save,
664
671
/// returns whether there were any.
665
672
fn note_changes ( & mut self ) -> bool {
666
- // TODO: count patches somehow.
667
- true
673
+ let count = {
674
+ let doc = self . document . read ( ) ;
675
+ let changes = doc. automerge . get_changes ( & self . last_heads ) ;
676
+ changes. len ( )
677
+ } ;
678
+ let has_patches = count > 0 ;
679
+ self . patches_since_last_save = self . patches_since_last_save . checked_add ( count) . unwrap_or ( 0 ) ;
680
+ has_patches
668
681
}
669
682
670
683
fn resolve_change_observers ( & mut self , result : Result < ( ) , RepoError > ) {
@@ -683,18 +696,21 @@ impl DocumentInfo {
683
696
return ;
684
697
}
685
698
let should_compact = self . patches_since_last_save > 10 ;
686
- let storage_fut = if should_compact {
687
- let to_save = {
688
- let mut doc = self . document . write ( ) ;
689
- doc. automerge . save ( )
699
+ let ( storage_fut, new_heads ) = if should_compact {
700
+ let ( to_save, new_heads ) = {
701
+ let doc = self . document . read ( ) ;
702
+ ( doc. automerge . save ( ) , doc . automerge . get_heads ( ) )
690
703
} ;
691
- storage. compact ( document_id. clone ( ) , to_save)
704
+ ( storage. compact ( document_id. clone ( ) , to_save) , new_heads )
692
705
} else {
693
- let to_save = {
694
- let mut doc = self . document . write ( ) ;
695
- doc. automerge . save_incremental ( )
706
+ let ( to_save, new_heads) = {
707
+ let doc = self . document . read ( ) ;
708
+ (
709
+ doc. automerge . save_after ( & self . last_heads ) ,
710
+ doc. automerge . get_heads ( ) ,
711
+ )
696
712
} ;
697
- storage. append ( document_id. clone ( ) , to_save)
713
+ ( storage. append ( document_id. clone ( ) , to_save) , new_heads )
698
714
} ;
699
715
self . state = match self . state {
700
716
DocState :: Sync ( None ) => DocState :: Sync ( Some ( storage_fut) ) ,
@@ -710,6 +726,7 @@ impl DocumentInfo {
710
726
let waker = Arc :: new ( RepoWaker :: Storage ( wake_sender. clone ( ) , document_id) ) ;
711
727
self . state . poll_pending_save ( waker) ;
712
728
self . patches_since_last_save = 0 ;
729
+ self . last_heads = new_heads;
713
730
}
714
731
715
732
/// Apply incoming sync messages.
0 commit comments