fixed some inconsistency bugs with DS
This commit is contained in:
parent
6e9f990d5c
commit
82e2254302
@ -40,6 +40,7 @@ class AbstractConnector {
|
|||||||
this.broadcastedHB = false
|
this.broadcastedHB = false
|
||||||
this.syncingClients = []
|
this.syncingClients = []
|
||||||
this.whenSyncedListeners = []
|
this.whenSyncedListeners = []
|
||||||
|
this.y.db.stopGarbageCollector()
|
||||||
}
|
}
|
||||||
setUserId (userId) {
|
setUserId (userId) {
|
||||||
this.userId = userId
|
this.userId = userId
|
||||||
|
@ -36,7 +36,7 @@ function wait (t) {
|
|||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
resolve()
|
resolve()
|
||||||
}, t)
|
}, t * 5)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
g.wait = wait
|
g.wait = wait
|
||||||
@ -150,7 +150,11 @@ g.compareAllUsers = async(function * compareAllUsers (users) {
|
|||||||
for (var i = 0; i < d.len; i++) {
|
for (var i = 0; i < d.len; i++) {
|
||||||
var o = yield* this.getOperation([d.id[0], d.id[1] + i])
|
var o = yield* this.getOperation([d.id[0], d.id[1] + i])
|
||||||
// gc'd or deleted
|
// 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) {
|
if (self.constructor === Array) {
|
||||||
self = {users: self}
|
self = {users: self}
|
||||||
}
|
}
|
||||||
console.log('User 1: ', self.users[0].connector.userId) // eslint-disable-line
|
console.log('User 1: ', self.users[0].connector.userId, "=============================================") // eslint-disable-line
|
||||||
self.users[0].db.os.logTable() // eslint-disable-line
|
self.users[0].db.logTable() // eslint-disable-line
|
||||||
console.log('User 2: ', self.users[1].connector.userId) // eslint-disable-line
|
console.log('User 2: ', self.users[1].connector.userId, "=============================================") // eslint-disable-line
|
||||||
self.users[1].db.os.logTable() // eslint-disable-line
|
self.users[1].db.logTable() // eslint-disable-line
|
||||||
console.log('User 3: ', self.users[2].connector.userId) // eslint-disable-line
|
console.log('User 3: ', self.users[2].connector.userId, "=============================================") // eslint-disable-line
|
||||||
self.users[2].db.os.logTable() // eslint-disable-line
|
self.users[2].db.logTable() // eslint-disable-line
|
||||||
}
|
}
|
||||||
g.logUsers = logUsers
|
g.logUsers = logUsers
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Partial definition of a transaction
|
Partial definition of a transaction
|
||||||
|
|
||||||
A transaction provides all the the async functionality on a database.
|
A transaction provides all the the async functionality on a database.
|
||||||
|
|
||||||
By convention, a transaction has the following properties:
|
By convention, a transaction has the following properties:
|
||||||
* ss for StateSet
|
* ss for StateSet
|
||||||
* os for OperationStore
|
* os for OperationStore
|
||||||
@ -136,17 +136,20 @@ class AbstractTransaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var left = target.left != null ? yield* this.getOperation(target.left) : null
|
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)
|
this.store.addToGarbageCollector(target, left)
|
||||||
|
|
||||||
// set here because it was deleted and/or gc'd
|
// set here because it was deleted and/or gc'd
|
||||||
yield* this.setOperation(target)
|
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 (
|
if (
|
||||||
right != null &&
|
right != null &&
|
||||||
right.right != null &&
|
|
||||||
this.store.addToGarbageCollector(right, target)
|
this.store.addToGarbageCollector(right, target)
|
||||||
) {
|
) {
|
||||||
yield* this.setOperation(right)
|
yield* this.setOperation(right)
|
||||||
@ -164,7 +167,8 @@ class AbstractTransaction {
|
|||||||
yield* this.deleteOperation(id)
|
yield* this.deleteOperation(id)
|
||||||
o = yield* this.getOperation(id)
|
o = yield* this.getOperation(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: I don't think that this is necessary!!
|
||||||
// check to increase the state of the respective user
|
// check to increase the state of the respective user
|
||||||
var state = yield* this.getState(id[0])
|
var state = yield* this.getState(id[0])
|
||||||
if (state.clock === id[1]) {
|
if (state.clock === id[1]) {
|
||||||
@ -270,6 +274,10 @@ class AbstractOperationStore {
|
|||||||
garbageCollect()
|
garbageCollect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stopGarbageCollector () {
|
||||||
|
this.gc1 = []
|
||||||
|
this.gc2 = []
|
||||||
|
}
|
||||||
garbageCollectAfterSync () {
|
garbageCollectAfterSync () {
|
||||||
var os = this.os
|
var os = this.os
|
||||||
var self = this
|
var self = this
|
||||||
@ -284,12 +292,12 @@ class AbstractOperationStore {
|
|||||||
Try to add to GC.
|
Try to add to GC.
|
||||||
|
|
||||||
TODO: rename this function
|
TODO: rename this function
|
||||||
|
|
||||||
Rulez:
|
Rulez:
|
||||||
* Only gc if this user is online
|
* Only gc if this user is online
|
||||||
* The most left element in a list must not be gc'd.
|
* The most left element in a list must not be gc'd.
|
||||||
=> There is at least one element in the list
|
=> There is at least one element in the list
|
||||||
|
|
||||||
returns true iff op was added to GC
|
returns true iff op was added to GC
|
||||||
*/
|
*/
|
||||||
addToGarbageCollector (op, left) {
|
addToGarbageCollector (op, left) {
|
||||||
@ -342,7 +350,7 @@ class AbstractOperationStore {
|
|||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Apply a list of operations.
|
Apply a list of operations.
|
||||||
|
|
||||||
* get a transaction
|
* get a transaction
|
||||||
* check whether all Struct.*.requiredOps are in the OS
|
* check whether all Struct.*.requiredOps are in the OS
|
||||||
* check if it is an expected op (otherwise wait for it)
|
* 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.
|
Actually execute an operation, when all expected operations are available.
|
||||||
If op is not yet expected, add it to the list of waiting operations.
|
If op is not yet expected, add it to the list of waiting operations.
|
||||||
|
|
||||||
This will also try to execute waiting operations
|
This will also try to execute waiting operations
|
||||||
(ops that were not expected yet), after it was applied
|
(ops that were not expected yet), after it was applied
|
||||||
*/
|
*/
|
||||||
|
@ -70,7 +70,10 @@ class DeleteStore extends Y.utils.RBTree {
|
|||||||
}
|
}
|
||||||
// can extend right?
|
// can extend right?
|
||||||
var next = n.next()
|
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
|
n.val.len = n.val.len + next.val.len
|
||||||
super.delete(next.val.id)
|
super.delete(next.val.id)
|
||||||
}
|
}
|
||||||
@ -303,7 +306,12 @@ Y.Memory = (function () {
|
|||||||
this.ds = new DeleteStore()
|
this.ds = new DeleteStore()
|
||||||
}
|
}
|
||||||
logTable () {
|
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) {
|
requestTransaction (_makeGen, requestNow) {
|
||||||
if (requestNow == null) { requestNow = false }
|
if (requestNow == null) { requestNow = false }
|
||||||
|
@ -175,10 +175,11 @@ var Struct = {
|
|||||||
op.right = left.right
|
op.right = left.right
|
||||||
left.right = op.id
|
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) {
|
if (left.gc != null) {
|
||||||
this.store.removeFromGarbageCollector(left)
|
this.store.removeFromGarbageCollector(left)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
yield* this.setOperation(left)
|
yield* this.setOperation(left)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user