diff --git a/frontend/rust-lib/flowy-revision/src/rev_persistence.rs b/frontend/rust-lib/flowy-revision/src/rev_persistence.rs index ac40390771..62d4a0e408 100644 --- a/frontend/rust-lib/flowy-revision/src/rev_persistence.rs +++ b/frontend/rust-lib/flowy-revision/src/rev_persistence.rs @@ -104,9 +104,14 @@ where new_revision: &'a Revision, rev_compress: &Arc, ) -> FlowyResult { - let mut sync_seq_write_guard = self.sync_seq.write().await; - if sync_seq_write_guard.step > self.configuration.merge_threshold { - let compact_seq = sync_seq_write_guard.compact(); + let mut sync_seq = self.sync_seq.write().await; + let step = sync_seq.step; + + // Before the new_revision pushed into the sync_seq, we check if the current `step` of the + // sync_seq is less equal or greater than the merge threshold. If yes, it's need to merged + // with the new_revision into one revision. + if step >= self.configuration.merge_threshold - 1 { + let compact_seq = sync_seq.compact(); let range = RevisionRange { start: *compact_seq.front().unwrap(), end: *compact_seq.back().unwrap(), @@ -119,20 +124,18 @@ where revisions.push(new_revision.clone()); // compact multiple revisions into one - let compact_revision = rev_compress.merge_revisions(&self.user_id, &self.object_id, revisions)?; - let rev_id = compact_revision.rev_id; - tracing::Span::current().record("rev_id", &rev_id); - - // insert new revision - let _ = sync_seq_write_guard.dry_push(rev_id)?; + let merged_revision = rev_compress.merge_revisions(&self.user_id, &self.object_id, revisions)?; + let rev_id = merged_revision.rev_id; + tracing::Span::current().record("rev_id", &merged_revision.rev_id); + let _ = sync_seq.dry_push(merged_revision.rev_id)?; // replace the revisions in range with compact revision - self.compact(&range, compact_revision).await?; + self.compact(&range, merged_revision).await?; Ok(rev_id) } else { tracing::Span::current().record("rev_id", &new_revision.rev_id); self.add(new_revision.clone(), RevisionState::Sync, true).await?; - sync_seq_write_guard.push(new_revision.rev_id)?; + sync_seq.push(new_revision.rev_id)?; Ok(new_revision.rev_id) } } @@ -201,7 +204,6 @@ where let _ = self .disk_cache .delete_revision_records(&self.object_id, Some(rev_ids))?; - self.add(new_revision, RevisionState::Sync, true).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-revision/tests/revision_test/local_revision_test.rs b/frontend/rust-lib/flowy-revision/tests/revision_test/local_revision_test.rs index 88ee0bc0c9..b91d32386d 100644 --- a/frontend/rust-lib/flowy-revision/tests/revision_test/local_revision_test.rs +++ b/frontend/rust-lib/flowy-revision/tests/revision_test/local_revision_test.rs @@ -190,7 +190,7 @@ async fn revision_compress_three_revisions_test2() { #[tokio::test] async fn revision_merge_per_5_revision_test() { - let test = RevisionTest::new_with_configuration(4).await; + let test = RevisionTest::new_with_configuration(5).await; for i in 0..20 { let content = format!("{}", i); let (base_rev_id, rev_id) = test.next_rev_id_pair(); @@ -202,5 +202,42 @@ async fn revision_merge_per_5_revision_test() { .await; } - test.run_scripts(vec![AssertNumberOfSyncRevisions { num: 5 }]).await; + test.run_scripts(vec![ + AssertNumberOfSyncRevisions { num: 4 }, + AssertNextSyncRevisionContent { + expected: "01234".to_string(), + }, + AckRevision { rev_id: 1 }, + AssertNextSyncRevisionContent { + expected: "56789".to_string(), + }, + AckRevision { rev_id: 2 }, + AssertNextSyncRevisionContent { + expected: "1011121314".to_string(), + }, + AckRevision { rev_id: 3 }, + AssertNextSyncRevisionContent { + expected: "1516171819".to_string(), + }, + AckRevision { rev_id: 4 }, + AssertNextSyncRevisionId { rev_id: None }, + ]) + .await; +} + +#[tokio::test] +async fn revision_merge_per_100_revision_test() { + let test = RevisionTest::new_with_configuration(100).await; + for i in 0..1000 { + let content = format!("{}", i); + let (base_rev_id, rev_id) = test.next_rev_id_pair(); + test.run_script(AddLocalRevision { + content, + base_rev_id, + rev_id, + }) + .await; + } + + test.run_scripts(vec![AssertNumberOfSyncRevisions { num: 10 }]).await; }