Kaynağa Gözat

Merge pull request #14932 from overleaf/em-optimise-ops-compression

Optimize ops compression in project-history

GitOrigin-RevId: 8131e8b833f64bb6560a966105e1d377e55b669e
Eric Mc Sween 2 yıl önce
ebeveyn
işleme
43570cb7b4
1 değiştirilmiş dosya ile 44 ekleme ve 25 silme
  1. 44 25
      services/project-history/app/js/UpdateTranslator.js

+ 44 - 25
services/project-history/app/js/UpdateTranslator.js

@@ -55,7 +55,7 @@ function _convertToChange(projectId, updateWithBlob) {
     let pathname = update.meta.pathname
 
     pathname = _convertPathname(pathname)
-    const builder = new TextOperationsBuilder(update.doc, docLength, pathname)
+    const builder = new TextOperationsBuilder(docLength, pathname)
     // convert ops
     for (const op of update.op) {
       builder.addOp(op)
@@ -153,15 +153,15 @@ export function _convertPathname(pathname) {
 }
 
 class TextOperationsBuilder {
-  constructor(docId, docLength, pathname) {
+  constructor(docLength, pathname) {
     this.operations = []
-    this.doc_id = docId
-    this.doc_length = docLength
+    this.currentOperation = []
+    this.cursor = 0
+    this.docLength = docLength
     this.pathname = pathname
   }
 
   addOp(op) {
-    let retain
     if (op.c != null) {
       return // ignore comment op
     }
@@ -170,41 +170,60 @@ class TextOperationsBuilder {
     }
 
     // We sometimes receive operations that operate at positions outside the
-    // doc_length. Document updater coerces the position to the end of the
+    // docLength. Document updater coerces the position to the end of the
     // document. We do the same here.
-    const pos = Math.min(op.p, this.doc_length)
+    const pos = Math.min(op.p, this.docLength)
 
-    const textOperation = []
-    if (pos > 0) {
-      textOperation.push(pos)
+    if (pos < this.cursor) {
+      this.pushCurrentOperation()
+      // At this point, this.cursor === 0 and we can continue
+    }
+
+    if (pos > this.cursor) {
+      this.retain(pos - this.cursor)
     }
 
     if (op.i != null) {
-      textOperation.push(op.i)
-      retain = this.doc_length - pos
-      this.doc_length += op.i.length
+      this.insert(op.i)
     }
 
     if (op.d != null) {
-      textOperation.push(-op.d.length)
-      retain = this.doc_length - pos - op.d.length
-      this.doc_length -= op.d.length
+      this.delete(op.d.length)
     }
+  }
 
-    if (retain > 0) {
-      textOperation.push(retain)
-    }
-    this.pushTextOperation(textOperation)
+  retain(length) {
+    this.currentOperation.push(length)
+    this.cursor += length
+  }
+
+  insert(str) {
+    this.currentOperation.push(str)
+    this.cursor += str.length
+    this.docLength += str.length
+  }
+
+  delete(length) {
+    this.currentOperation.push(-length)
+    this.docLength -= length
   }
 
-  pushTextOperation(textOperation) {
-    this.operations.push({
-      pathname: this.pathname,
-      textOperation,
-    })
+  pushCurrentOperation() {
+    if (this.cursor < this.docLength) {
+      this.retain(this.docLength - this.cursor)
+    }
+    if (this.currentOperation.length > 0) {
+      this.operations.push({
+        pathname: this.pathname,
+        textOperation: this.currentOperation,
+      })
+      this.currentOperation = []
+    }
+    this.cursor = 0
   }
 
   finish() {
+    this.pushCurrentOperation()
     return this.operations
   }
 }