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.syncingClients = []
 | 
			
		||||
    this.whenSyncedListeners = []
 | 
			
		||||
    this.y.db.stopGarbageCollector()
 | 
			
		||||
  }
 | 
			
		||||
  setUserId (userId) {
 | 
			
		||||
    this.userId = userId
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
@ -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 }
 | 
			
		||||
 | 
			
		||||
@ -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 {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user