From 71bf6438e18373aa6dd56e7d9ee9e4537f78157d Mon Sep 17 00:00:00 2001
From: Kevin Jahns <kevin.jahns@rwth-aachen.de>
Date: Mon, 25 Apr 2016 13:09:52 +0200
Subject: [PATCH] found some gc bugs that occur when using deletion lengths

---
 src/Database.js    |  9 ++++++---
 src/Struct.js      |  3 +++
 src/Transaction.js | 18 +++++++-----------
 3 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/src/Database.js b/src/Database.js
index 90ede86c..f49d2bc2 100644
--- a/src/Database.js
+++ b/src/Database.js
@@ -113,6 +113,11 @@ module.exports = function (Y /* :any */) {
         garbageCollect()
       }
     }
+    queueGarbageCollector (id) {
+      if (this.y.isConnected()) {
+        this.gc1.push(id)
+      }
+    }
     emptyGarbageCollector () {
       return new Promise(resolve => {
         var check = () => {
@@ -185,9 +190,7 @@ module.exports = function (Y /* :any */) {
         if (gc) {
           op.gc = true
           yield* this.setOperation(op)
-          if (this.store.y.connector.isSynced) {
-            this.store.gc1.push(op.id)
-          }
+          this.store.queueGarbageCollector(op.id)
           return true
         }
       }
diff --git a/src/Struct.js b/src/Struct.js
index fb9a60e8..6cfe5077 100644
--- a/src/Struct.js
+++ b/src/Struct.js
@@ -229,6 +229,9 @@ module.exports = function (Y/* :any */) {
 
           // if right exists, and it is supposed to be gc'd. Remove it from the gc
           if (right.gc != null) {
+            if (right.content != null && right.content.length > 1) {
+              right = yield* this.getInsertionCleanEnd(right.id)
+            }
             this.store.removeFromGarbageCollector(right)
           }
           yield* this.setOperation(right)
diff --git a/src/Transaction.js b/src/Transaction.js
index b4790719..57b70e3b 100644
--- a/src/Transaction.js
+++ b/src/Transaction.js
@@ -165,9 +165,7 @@ module.exports = function (Y/* :any */) {
           if (start.opContent != null) {
             yield* this.deleteOperation(start.opContent)
           }
-          if (this.store.y.connector.isSynced) {
-            this.store.gc1.push(start.id)
-          }
+          this.store.queueGarbageCollector(start.id)
         }
         start = start.right
       }
@@ -320,6 +318,7 @@ module.exports = function (Y/* :any */) {
         yield* this.ds.delete(next.id)
       }
       yield* this.ds.put(n)
+      yield* this.updateState(n.id[0])
     }
     /*
       Mark an operation as deleted.
@@ -445,7 +444,7 @@ module.exports = function (Y/* :any */) {
               }
             }
             yield* this.setOperation(op)
-            this.store.gc1.push(op.id)
+            this.store.gc1.push(op.id) // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!)
             return
           }
         }
@@ -472,9 +471,7 @@ module.exports = function (Y/* :any */) {
       var o = yield* this.getOperation(id)
       yield* this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd
       // if op exists, then clean that mess up..
-      if (o == null) {
-        yield* this.updateState(id[0])
-      } else if (o != null) {
+      if (o != null) {
         var deps = []
         if (o.opContent != null) {
           deps.push(o.opContent)
@@ -491,10 +488,9 @@ module.exports = function (Y/* :any */) {
             }
             dep.gc = true
             yield* this.setOperation(dep)
-            this.store.gc1.push(dep.id)
+            this.store.queueGarbageCollector(dep.id)
           } else {
             yield* this.markGarbageCollected(deps[i], 1)
-            yield* this.updateState(deps[i][0]) // TODO: unneccessary?
           }
         }
 
@@ -845,7 +841,7 @@ module.exports = function (Y/* :any */) {
           yield* this.setOperation(left)
           yield* this.setOperation(ins)
           if (left.gc) {
-            this.store.gc1.push(ins.id)
+            this.store.queueGarbageCollector(ins.id)
           }
           return ins
         }
@@ -873,7 +869,7 @@ module.exports = function (Y/* :any */) {
           yield* this.setOperation(right)
           yield* this.setOperation(ins)
           if (ins.gc) {
-            this.store.gc1.push(right.id)
+            this.store.queueGarbageCollector(right.id)
           }
           return ins
         }
-- 
GitLab