From 90b7b01e9aa8f9e62f4d8482b0e4cb143e6480b0 Mon Sep 17 00:00:00 2001
From: Kevin Jahns <kevin.jahns@rwth-aachen.de>
Date: Fri, 22 Apr 2016 22:09:49 +0100
Subject: [PATCH] fixes #49

---
 src/Connector.js   |  1 -
 src/Database.js    | 97 ++++++++++++++++++++--------------------------
 src/Struct.js      | 27 +++++--------
 src/Transaction.js |  6 +--
 src/Utils.js       |  9 +++--
 5 files changed, 58 insertions(+), 82 deletions(-)

diff --git a/src/Connector.js b/src/Connector.js
index 37726bca..26846dac 100644
--- a/src/Connector.js
+++ b/src/Connector.js
@@ -225,7 +225,6 @@ module.exports = function (Y/* :any */) {
         return
       }
       if (message.type === 'sync step 1') {
-        // TODO: make transaction, stream the ops
         let conn = this
         let m = message
         this.y.db.requestTransaction(function *() {
diff --git a/src/Database.js b/src/Database.js
index 2ff87f6b..90ede86c 100644
--- a/src/Database.js
+++ b/src/Database.js
@@ -80,8 +80,7 @@ module.exports = function (Y /* :any */) {
         return os.whenTransactionsFinished().then(function () {
           if (os.gc1.length > 0 || os.gc2.length > 0) {
             if (!os.y.isConnected()) {
-              debugger
-              console.log('gc should be empty when disconnected!')
+              console.warn('gc should be empty when disconnected!')
             }
             return new Promise((resolve) => {
               os.requestTransaction(function * () {
@@ -379,68 +378,54 @@ module.exports = function (Y /* :any */) {
     }
     // called by a transaction when an operation is added
     * operationAdded (transaction, op) {
-      if (op.struct === 'Delete') {
-        throw new Error('this section shouldnt be entered anymore!')
-        var target = yield* transaction.getOperation(op.target)
-        if (target != null) {
-          var type = transaction.store.initializedTypes[JSON.stringify(target.parent)]
-          if (type != null) {
-            yield* type._changed(transaction, {
-              struct: 'Delete',
-              target: op.target
-            })
-          }
-        }
-      } else {
-        // increase SS
-        yield* transaction.updateState(op.id[0])
+      // increase SS
+      yield* transaction.updateState(op.id[0])
 
-        var opLen = op.content != null ? op.content.length : 1
-        for (var i = 0; i < opLen; i++) {
-          // notify whenOperation listeners (by id)
-          var sid = JSON.stringify([op.id[0], op.id[1] + i])
-          var l = this.listenersById[sid]
-          delete this.listenersById[sid]
-  
-          if (l != null) {
-            for (var key in l) {
-              var listener = l[key]
-              if (--listener.missing === 0) {
-                this.whenOperationsExist([], listener.op)
-              }
+      var opLen = op.content != null ? op.content.length : 1
+      for (let i = 0; i < opLen; i++) {
+        // notify whenOperation listeners (by id)
+        var sid = JSON.stringify([op.id[0], op.id[1] + i])
+        var l = this.listenersById[sid]
+        delete this.listenersById[sid]
+
+        if (l != null) {
+          for (var key in l) {
+            var listener = l[key]
+            if (--listener.missing === 0) {
+              this.whenOperationsExist([], listener.op)
             }
           }
         }
-        var t = this.initializedTypes[JSON.stringify(op.parent)]
+      }
+      var t = this.initializedTypes[JSON.stringify(op.parent)]
 
-        // if parent is deleted, mark as gc'd and return
-        if (op.parent != null) {
-          var parentIsDeleted = yield* transaction.isDeleted(op.parent)
-          if (parentIsDeleted) {
-            yield* transaction.deleteList(op.id)
-            return
-          }
+      // if parent is deleted, mark as gc'd and return
+      if (op.parent != null) {
+        var parentIsDeleted = yield* transaction.isDeleted(op.parent)
+        if (parentIsDeleted) {
+          yield* transaction.deleteList(op.id)
+          return
         }
+      }
 
-        // notify parent, if it was instanciated as a custom type
-        if (t != null) {
-          let o = Y.utils.copyObject(op)
-          yield* t._changed(transaction, o)
-        }
-        if (!op.deleted) {
-          // Delete if DS says this is actually deleted
-          var len = op.content != null ? op.content.length : 1
-          var startId = op.id // You must not use op.id in the following loop, because op will change when deleted
-          for (var i = 0; i < len; i++) {
-            var id = [startId[0], startId[1] + i]
-            var opIsDeleted = yield* transaction.isDeleted(id)
-            if (opIsDeleted) {
-              var delop = {
-                struct: 'Delete',
-                target: id
-              }
-              yield* this.tryExecute.call(transaction, delop)
+      // notify parent, if it was instanciated as a custom type
+      if (t != null) {
+        let o = Y.utils.copyObject(op)
+        yield* t._changed(transaction, o)
+      }
+      if (!op.deleted) {
+        // Delete if DS says this is actually deleted
+        var len = op.content != null ? op.content.length : 1
+        var startId = op.id // You must not use op.id in the following loop, because op will change when deleted
+        for (let i = 0; i < len; i++) {
+          var id = [startId[0], startId[1] + i]
+          var opIsDeleted = yield* transaction.isDeleted(id)
+          if (opIsDeleted) {
+            var delop = {
+              struct: 'Delete',
+              target: id
             }
+            yield* this.tryExecute.call(transaction, delop)
           }
         }
       }
diff --git a/src/Struct.js b/src/Struct.js
index 82bed80a..fb9a60e8 100644
--- a/src/Struct.js
+++ b/src/Struct.js
@@ -126,11 +126,11 @@ module.exports = function (Y/* :any */) {
       */
       execute: function * (op) {
         var i // loop counter
-        
+
         // during this function some ops may get split into two pieces (e.g. with getInsertionCleanEnd)
         // We try to merge them later, if possible
         var tryToRemergeLater = []
-        
+
         if (op.origin != null) { // TODO: !== instead of !=
           // we save in origin that op originates in it
           // we need that later when we eventually garbage collect origin (see transaction)
@@ -165,13 +165,13 @@ module.exports = function (Y/* :any */) {
           start = startId == null ? null : yield* this.getOperation(startId)
           o = start
         }
-        
+
         // make sure to split op.right if necessary (also add to tryCombineWithLeft)
         if (op.right != null) {
           tryToRemergeLater.push(op.right)
           yield* this.getInsertionCleanStart(op.right)
         }
-        
+
         // handle conflicts
         while (true) {
           if (o != null && !Y.utils.compareIds(o.id, op.right)) {
@@ -212,18 +212,11 @@ module.exports = function (Y/* :any */) {
         // reconnect left and set right of op
         if (op.left != null) {
           left = yield* this.getInsertion(op.left)
-          // TODO: remove false!!
-          if (false && op.content != null && left.content != null && left.id[0] === op.id[0] && left.id[1] + left.content.length === op.id[1] && left.originOf == null && left.deleted !== true && left.gc !== true) {
-            // extend left
-            left.content = left.content.concat(op.content)
-            op = left
-          } else {
-            // link left
-            op.right = left.right
-            left.right = op.id
+          // link left
+          op.right = left.right
+          left.right = op.id
 
-            yield* this.setOperation(left)
-          }
+          yield* this.setOperation(left)
         } else {
           // set op.right from parent, if necessary
           op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start
@@ -266,9 +259,9 @@ module.exports = function (Y/* :any */) {
             yield* this.setOperation(parent)
           }
         }
-        
+
         // try to merge original op.left and op.origin
-        for (var i = 0; i < tryToRemergeLater.length; i++) {
+        for (let i = 0; i < tryToRemergeLater.length; i++) {
           var m = yield* this.getOperation(tryToRemergeLater[i])
           yield* this.tryCombineWithLeft(m)
         }
diff --git a/src/Transaction.js b/src/Transaction.js
index 4bf4eca4..b4790719 100644
--- a/src/Transaction.js
+++ b/src/Transaction.js
@@ -736,9 +736,7 @@ module.exports = function (Y/* :any */) {
         }
         if (this.store.forwardAppliedOperations) {
           var ops = []
-          for (let c = del[1]; c < del[1] + del[2]; c++) {
-            ops.push({struct: 'Delete', target: [d[0], c]}) // TODO: implement Delete with deletion length!
-          }
+          ops.push({struct: 'Delete', target: [d[0], d[1]], length: del[2]})
           this.store.y.connector.broadcastOps(ops)
         }
       }
@@ -798,7 +796,7 @@ module.exports = function (Y/* :any */) {
             !op.gc && !op.deleted
         ) {
           // combine!
-          if (op.originOf != null){
+          if (op.originOf != null) {
             left.originOf = op.originOf
           } else {
             delete left.originOf
diff --git a/src/Utils.js b/src/Utils.js
index f15ca718..d50b51ee 100644
--- a/src/Utils.js
+++ b/src/Utils.js
@@ -247,7 +247,7 @@ module.exports = function (Y /* : any*/) {
       return id1 === id2
     } else {
       return id1[0] === id2[0] && id1[1] === id2[1]
-    } 
+    }
   }
   Y.utils.compareIds = compareIds
 
@@ -265,7 +265,7 @@ module.exports = function (Y /* : any*/) {
     }
   }
   Y.utils.matchesId = matchesId
-  
+
   function getLastId (op) {
     if (op.content == null || op.content.length === 1) {
       return op.id
@@ -298,8 +298,9 @@ module.exports = function (Y /* : any*/) {
       I tried to optimize this for performance, therefore no highlevel operations.
     */
     class SmallLookupBuffer extends Store {
-      constructor () {
-        super(...arguments)
+      constructor (arg) {
+        // super(...arguments) -- do this when this is supported by stable nodejs
+        super(arg)
         this.writeBuffer = createEmptyOpsArray(5)
         this.readBuffer = createEmptyOpsArray(10)
       }
-- 
GitLab