queue.js (1873B)
1 "use strict"; 2 function arrayMove(src, srcIndex, dst, dstIndex, len) { 3 for (var j = 0; j < len; ++j) { 4 dst[j + dstIndex] = src[j + srcIndex]; 5 src[j + srcIndex] = void 0; 6 } 7 } 8 9 function Queue(capacity) { 10 this._capacity = capacity; 11 this._length = 0; 12 this._front = 0; 13 } 14 15 Queue.prototype._willBeOverCapacity = function (size) { 16 return this._capacity < size; 17 }; 18 19 Queue.prototype._pushOne = function (arg) { 20 var length = this.length(); 21 this._checkCapacity(length + 1); 22 var i = (this._front + length) & (this._capacity - 1); 23 this[i] = arg; 24 this._length = length + 1; 25 }; 26 27 Queue.prototype.push = function (fn, receiver, arg) { 28 var length = this.length() + 3; 29 if (this._willBeOverCapacity(length)) { 30 this._pushOne(fn); 31 this._pushOne(receiver); 32 this._pushOne(arg); 33 return; 34 } 35 var j = this._front + length - 3; 36 this._checkCapacity(length); 37 var wrapMask = this._capacity - 1; 38 this[(j + 0) & wrapMask] = fn; 39 this[(j + 1) & wrapMask] = receiver; 40 this[(j + 2) & wrapMask] = arg; 41 this._length = length; 42 }; 43 44 Queue.prototype.shift = function () { 45 var front = this._front, 46 ret = this[front]; 47 48 this[front] = undefined; 49 this._front = (front + 1) & (this._capacity - 1); 50 this._length--; 51 return ret; 52 }; 53 54 Queue.prototype.length = function () { 55 return this._length; 56 }; 57 58 Queue.prototype._checkCapacity = function (size) { 59 if (this._capacity < size) { 60 this._resizeTo(this._capacity << 1); 61 } 62 }; 63 64 Queue.prototype._resizeTo = function (capacity) { 65 var oldCapacity = this._capacity; 66 this._capacity = capacity; 67 var front = this._front; 68 var length = this._length; 69 var moveItemsCount = (front + length) & (oldCapacity - 1); 70 arrayMove(this, 0, this, oldCapacity, moveItemsCount); 71 }; 72 73 module.exports = Queue;