queue.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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.push = function (fn, receiver, arg) {
  24. var length = this.length() + 3;
  25. if (this._willBeOverCapacity(length)) {
  26. this._pushOne(fn);
  27. this._pushOne(receiver);
  28. this._pushOne(arg);
  29. return;
  30. }
  31. var j = this._front + length - 3;
  32. this._checkCapacity(length);
  33. var wrapMask = this._capacity - 1;
  34. this[(j + 0) & wrapMask] = fn;
  35. this[(j + 1) & wrapMask] = receiver;
  36. this[(j + 2) & wrapMask] = arg;
  37. this._length = length;
  38. };
  39. Queue.prototype.shift = function () {
  40. var front = this._front,
  41. ret = this[front];
  42. this[front] = undefined;
  43. this._front = (front + 1) & (this._capacity - 1);
  44. this._length--;
  45. return ret;
  46. };
  47. Queue.prototype.length = function () {
  48. return this._length;
  49. };
  50. Queue.prototype._checkCapacity = function (size) {
  51. if (this._capacity < size) {
  52. this._resizeTo(this._capacity << 1);
  53. }
  54. };
  55. Queue.prototype._resizeTo = function (capacity) {
  56. var oldCapacity = this._capacity;
  57. this._capacity = capacity;
  58. var front = this._front;
  59. var length = this._length;
  60. var moveItemsCount = (front + length) & (oldCapacity - 1);
  61. arrayMove(this, 0, this, oldCapacity, moveItemsCount);
  62. };
  63. module.exports = Queue;