queue.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. function Queue(capacity) {
  9. this._capacity = capacity;
  10. this._length = 0;
  11. this._front = 0;
  12. }
  13. Queue.prototype._willBeOverCapacity = function (size) {
  14. return this._capacity < size;
  15. };
  16. Queue.prototype._pushOne = function (arg) {
  17. var length = this.length();
  18. this._checkCapacity(length + 1);
  19. var i = (this._front + length) & (this._capacity - 1);
  20. this[i] = arg;
  21. this._length = length + 1;
  22. };
  23. Queue.prototype._unshiftOne = function(value) {
  24. var capacity = this._capacity;
  25. this._checkCapacity(this.length() + 1);
  26. var front = this._front;
  27. var i = (((( front - 1 ) &
  28. ( capacity - 1) ) ^ capacity ) - capacity );
  29. this[i] = value;
  30. this._front = i;
  31. this._length = this.length() + 1;
  32. };
  33. Queue.prototype.unshift = function(fn, receiver, arg) {
  34. this._unshiftOne(arg);
  35. this._unshiftOne(receiver);
  36. this._unshiftOne(fn);
  37. };
  38. Queue.prototype.push = function (fn, receiver, arg) {
  39. var length = this.length() + 3;
  40. if (this._willBeOverCapacity(length)) {
  41. this._pushOne(fn);
  42. this._pushOne(receiver);
  43. this._pushOne(arg);
  44. return;
  45. }
  46. var j = this._front + length - 3;
  47. this._checkCapacity(length);
  48. var wrapMask = this._capacity - 1;
  49. this[(j + 0) & wrapMask] = fn;
  50. this[(j + 1) & wrapMask] = receiver;
  51. this[(j + 2) & wrapMask] = arg;
  52. this._length = length;
  53. };
  54. Queue.prototype.shift = function () {
  55. var front = this._front,
  56. ret = this[front];
  57. this[front] = undefined;
  58. this._front = (front + 1) & (this._capacity - 1);
  59. this._length--;
  60. return ret;
  61. };
  62. Queue.prototype.length = function () {
  63. return this._length;
  64. };
  65. Queue.prototype._checkCapacity = function (size) {
  66. if (this._capacity < size) {
  67. this._resizeTo(this._capacity << 1);
  68. }
  69. };
  70. Queue.prototype._resizeTo = function (capacity) {
  71. var oldCapacity = this._capacity;
  72. this._capacity = capacity;
  73. var front = this._front;
  74. var length = this._length;
  75. var moveItemsCount = (front + length) & (oldCapacity - 1);
  76. arrayMove(this, 0, this, oldCapacity, moveItemsCount);
  77. };
  78. module.exports = Queue;