fixed some inconsistency bugs with DS

This commit is contained in:
Kevin Jahns 2015-10-05 14:24:11 +02:00
parent 6e9f990d5c
commit 82e2254302
6 changed files with 44 additions and 22 deletions

View File

@ -40,6 +40,7 @@ class AbstractConnector {
this.broadcastedHB = false
this.syncingClients = []
this.whenSyncedListeners = []
this.y.db.stopGarbageCollector()
}
setUserId (userId) {
this.userId = userId

View File

@ -36,7 +36,7 @@ function wait (t) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve()
}, t)
}, t * 5)
})
}
g.wait = wait
@ -150,7 +150,11 @@ g.compareAllUsers = async(function * compareAllUsers (users) {
for (var i = 0; i < d.len; i++) {
var o = yield* this.getOperation([d.id[0], d.id[1] + i])
// gc'd or deleted
expect(o == null || o.deleted).toBeTruthy()
if (d.gc) {
expect(o).toBeUndefined()
} else {
expect(o.deleted).toBeTruthy()
}
}
}
})
@ -234,11 +238,11 @@ function logUsers (self) {
if (self.constructor === Array) {
self = {users: self}
}
console.log('User 1: ', self.users[0].connector.userId) // eslint-disable-line
self.users[0].db.os.logTable() // eslint-disable-line
console.log('User 2: ', self.users[1].connector.userId) // eslint-disable-line
self.users[1].db.os.logTable() // eslint-disable-line
console.log('User 3: ', self.users[2].connector.userId) // eslint-disable-line
self.users[2].db.os.logTable() // eslint-disable-line
console.log('User 1: ', self.users[0].connector.userId, "=============================================") // eslint-disable-line
self.users[0].db.logTable() // eslint-disable-line
console.log('User 2: ', self.users[1].connector.userId, "=============================================") // eslint-disable-line
self.users[1].db.logTable() // eslint-disable-line
console.log('User 3: ', self.users[2].connector.userId, "=============================================") // eslint-disable-line
self.users[2].db.logTable() // eslint-disable-line
}
g.logUsers = logUsers

View File

@ -3,9 +3,9 @@
/*
Partial definition of a transaction
A transaction provides all the the async functionality on a database.
By convention, a transaction has the following properties:
* ss for StateSet
* os for OperationStore
@ -136,17 +136,20 @@ class AbstractTransaction {
}
}
var left = target.left != null ? yield* this.getOperation(target.left) : null
var right = target.right != null ? yield* this.getOperation(target.right) : null
this.store.addToGarbageCollector(target, left)
// set here because it was deleted and/or gc'd
yield* this.setOperation(target)
// check if it is possible to add right to the gc (this delete can't be responsible for left being gc'd)
/*
Check if it is possible to add right to the gc.
Because this delete can't be responsible for left being gc'd,
we don't have to add left to the gc..
*/
var right = target.right != null ? yield* this.getOperation(target.right) : null
if (
right != null &&
right.right != null &&
this.store.addToGarbageCollector(right, target)
) {
yield* this.setOperation(right)
@ -164,7 +167,8 @@ class AbstractTransaction {
yield* this.deleteOperation(id)
o = yield* this.getOperation(id)
}
// TODO: I don't think that this is necessary!!
// check to increase the state of the respective user
var state = yield* this.getState(id[0])
if (state.clock === id[1]) {
@ -270,6 +274,10 @@ class AbstractOperationStore {
garbageCollect()
}
}
stopGarbageCollector () {
this.gc1 = []
this.gc2 = []
}
garbageCollectAfterSync () {
var os = this.os
var self = this
@ -284,12 +292,12 @@ class AbstractOperationStore {
Try to add to GC.
TODO: rename this function
Rulez:
* Only gc if this user is online
* The most left element in a list must not be gc'd.
=> There is at least one element in the list
returns true iff op was added to GC
*/
addToGarbageCollector (op, left) {
@ -342,7 +350,7 @@ class AbstractOperationStore {
}
/*
Apply a list of operations.
* get a transaction
* check whether all Struct.*.requiredOps are in the OS
* check if it is an expected op (otherwise wait for it)
@ -423,7 +431,7 @@ class AbstractOperationStore {
/*
Actually execute an operation, when all expected operations are available.
If op is not yet expected, add it to the list of waiting operations.
This will also try to execute waiting operations
(ops that were not expected yet), after it was applied
*/

View File

@ -70,7 +70,10 @@ class DeleteStore extends Y.utils.RBTree {
}
// can extend right?
var next = n.next()
if (next !== null && Y.utils.compareIds([n.val.id[0], n.val.id[1] + n.val.len], next.val.id)) {
if (next !== null &&
Y.utils.compareIds([n.val.id[0], n.val.id[1] + n.val.len], next.val.id) &&
next.val.gc === false
) {
n.val.len = n.val.len + next.val.len
super.delete(next.val.id)
}
@ -303,7 +306,12 @@ Y.Memory = (function () {
this.ds = new DeleteStore()
}
logTable () {
this.os.logTable()
console.log('User: ', this.y.connector.userId, "=============================================") // eslint-disable-line
console.log("State Set (SS):", this.ss) // eslint-disable-line
console.log("Operation Store (OS):") // eslint-disable-line
this.os.logTable() // eslint-disable-line
console.log("Deletion Store (DS):") //eslint-disable-line
this.ds.logTable() // eslint-disable-line
}
requestTransaction (_makeGen, requestNow) {
if (requestNow == null) { requestNow = false }

View File

@ -175,10 +175,11 @@ var Struct = {
op.right = left.right
left.right = op.id
// if left exists, and it is supposed to be gc'd. Remove it from the gc
/*/ if left exists, and it is supposed to be gc'd. Remove it from the gc
if (left.gc != null) {
this.store.removeFromGarbageCollector(left)
}
*/
yield* this.setOperation(left)
} else {

View File

@ -24,7 +24,7 @@ class YConfig {
map: {}
}
yield* this.addOperation(model)
var root = yield* this.createType(model)
var root = yield* this.getType(model.id)
this.store.y.root = root
callback()
})