Implemented more efficient garbage collectior
from worst case of O(n) -> O(1) - where n is the number of insertions in a list So this is a huge improvement, I guess :)
This commit is contained in:
		
							parent
							
								
									38bf398709
								
							
						
					
					
						commit
						39dc2317b7
					
				| @ -208,6 +208,7 @@ g.compareAllUsers = async(function * compareAllUsers (users) { | ||||
|         yield* this.os.iterate(this, null, null, function * (o) { | ||||
|           o = Y.utils.copyObject(o) | ||||
|           delete o.origin | ||||
|           delete o.originOf | ||||
|           db1.push(o) | ||||
|         }) | ||||
|       }) | ||||
| @ -222,6 +223,7 @@ g.compareAllUsers = async(function * compareAllUsers (users) { | ||||
|         yield* this.os.iterate(this, null, null, function * (o) { | ||||
|           o = Y.utils.copyObject(o) | ||||
|           delete o.origin | ||||
|           delete o.originOf | ||||
|           expect(db1[count++]).toEqual(o) | ||||
|         }) | ||||
|       }) | ||||
|  | ||||
| @ -126,6 +126,19 @@ module.exports = function (Y/* :any */) { | ||||
|       execute: function *(op) { | ||||
|         var i // loop counter
 | ||||
|         var distanceToOrigin = i = yield* Struct.Insert.getDistanceToOrigin.call(this, op) // most cases: 0 (starts from 0)
 | ||||
| 
 | ||||
|         if (op.origin != null) { | ||||
|           // we save in origin that op originates in it
 | ||||
|           // we need that later when we eventually garbage collect origin (see transaction)
 | ||||
|           var origin = yield* this.getOperation(op.origin) | ||||
|           if (origin.originOf == null) { | ||||
|             origin.originOf = [] | ||||
|           } | ||||
|           origin.originOf.push(op.id) | ||||
|           yield* this.setOperation(origin) | ||||
|         } | ||||
| 
 | ||||
|         // now we begin to insert op in the list of insertions..
 | ||||
|         var o | ||||
|         var parent | ||||
|         var start | ||||
|  | ||||
| @ -362,23 +362,31 @@ module.exports = function (Y/* :any */) { | ||||
|         if (o.right != null) { | ||||
|           var right = yield* this.getOperation(o.right) | ||||
|           right.left = o.left | ||||
|           if (Y.utils.compareIds(right.origin, o.id)) { // rights origin is o
 | ||||
| 
 | ||||
|           if (Y.utils.compareIds(right.origin, id)) { // rights origin is o
 | ||||
|             // find new origin of right ops
 | ||||
|             // origin is the first left deleted operation
 | ||||
|             var neworigin = o.left | ||||
|             var neworigin_ = null | ||||
|             while (neworigin != null) { | ||||
|               var neworigin_ = yield* this.getOperation(neworigin) | ||||
|               neworigin_ = yield* this.getOperation(neworigin) | ||||
|               if (neworigin_.deleted) { | ||||
|                 break | ||||
|               } | ||||
|               neworigin = neworigin_.left | ||||
|             } | ||||
| 
 | ||||
|             // reset origin of all right ops (except first right - duh!),
 | ||||
| 
 | ||||
|             /* ** The following code does not rely on the the originOf property ** | ||||
|                   I recently added originOf to all Insert Operations (see Struct.Insert.execute), | ||||
|                   which saves which operations originate in a Insert operation. | ||||
|                   Garbage collecting without originOf is more memory efficient, but is nearly impossible for large texts, or lists! | ||||
|                   But I keep this code for now | ||||
|             ``` | ||||
|             // reset origin of right
 | ||||
|             right.origin = neworigin | ||||
| 
 | ||||
|             // reset origin of all right ops (except first right - duh!),
 | ||||
|             // until you find origin pointer to the left of o
 | ||||
|             // search until you find origin pointer to the left of o
 | ||||
|             if (right.right != null) { | ||||
|               var i = yield* this.getOperation(right.right) | ||||
|               var ids = [o.id, o.right] | ||||
| @ -399,9 +407,41 @@ module.exports = function (Y/* :any */) { | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } /* otherwise, rights origin is to the left of o, | ||||
|                then there is no right op (from o), that origins in o */ | ||||
|           yield* this.setOperation(right) | ||||
|             ``` | ||||
|             */ | ||||
|             // ** Now the new implementation starts **
 | ||||
|             // reset neworigin of all originOf[*]
 | ||||
|             for (var _i in o.originOf) { | ||||
|               var originsIn = yield* this.getOperation(o.originOf[_i]) | ||||
|               if (originsIn != null) { | ||||
|                 originsIn.origin = neworigin | ||||
|                 yield* this.setOperation(originsIn) | ||||
|               } | ||||
|             } | ||||
|             if (neworigin != null) { | ||||
|               if (neworigin_.originOf == null) { | ||||
|                 neworigin_.originOf = o.originOf | ||||
|               } else { | ||||
|                 neworigin_.originOf = o.originOf.concat(neworigin_.originOf) | ||||
|               } | ||||
|               yield* this.setOperation(neworigin_) | ||||
|             } | ||||
|             // we don't need to set right here, because
 | ||||
|             // right should be in o.originOf => it is set it the previous for loop
 | ||||
|           } else { | ||||
|             // we didn't need to reset the origin of right
 | ||||
|             // so we have to set right here
 | ||||
|             yield* this.setOperation(right) | ||||
|           } | ||||
|           // o may originate in another operation.
 | ||||
|           // Since o is deleted, we have to reset o.origin's `originOf` property
 | ||||
|           if (o.origin != null) { | ||||
|             var origin = yield* this.getOperation(o.origin) | ||||
|             origin.originOf = origin.originOf.filter(function (_id) { | ||||
|               return !Y.utils.compareIds(id, _id) | ||||
|             }) | ||||
|             yield* this.setOperation(origin) | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         if (o.parent != null) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user