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;
9 function Queue(capacity) {
10 this._capacity = capacity;
15 Queue.prototype._willBeOverCapacity = function (size) {
16 return this._capacity < size;
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);
24 this._length = length + 1;
27 Queue.prototype._unshiftOne = function(value) {
28 var capacity = this._capacity;
29 this._checkCapacity(this.length() + 1);
30 var front = this._front;
31 var i = (((( front - 1 ) &
32 ( capacity - 1) ) ^ capacity ) - capacity );
35 this._length = this.length() + 1;
38 Queue.prototype.unshift = function(fn, receiver, arg) {
39 this._unshiftOne(arg);
40 this._unshiftOne(receiver);
44 Queue.prototype.push = function (fn, receiver, arg) {
45 var length = this.length() + 3;
46 if (this._willBeOverCapacity(length)) {
48 this._pushOne(receiver);
52 var j = this._front + length - 3;
53 this._checkCapacity(length);
54 var wrapMask = this._capacity - 1;
55 this[(j + 0) & wrapMask] = fn;
56 this[(j + 1) & wrapMask] = receiver;
57 this[(j + 2) & wrapMask] = arg;
58 this._length = length;
61 Queue.prototype.shift = function () {
62 var front = this._front,
65 this[front] = undefined;
66 this._front = (front + 1) & (this._capacity - 1);
71 Queue.prototype.length = function () {
75 Queue.prototype._checkCapacity = function (size) {
76 if (this._capacity < size) {
77 this._resizeTo(this._capacity << 1);
81 Queue.prototype._resizeTo = function (capacity) {
82 var oldCapacity = this._capacity;
83 this._capacity = capacity;
84 var front = this._front;
85 var length = this._length;
86 var moveItemsCount = (front + length) & (oldCapacity - 1);
87 arrayMove(this, 0, this, oldCapacity, moveItemsCount);
90 module.exports = Queue;