Queue.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /**
  2. * A queue that can enqueue items at the end, and dequeue items from the front.
  3. *
  4. * @alias Queue
  5. * @constructor
  6. */
  7. function Queue() {
  8. this._array = [];
  9. this._offset = 0;
  10. this._length = 0;
  11. }
  12. Object.defineProperties(Queue.prototype, {
  13. /**
  14. * The length of the queue.
  15. *
  16. * @memberof Queue.prototype
  17. *
  18. * @type {Number}
  19. * @readonly
  20. */
  21. length: {
  22. get: function () {
  23. return this._length;
  24. },
  25. },
  26. });
  27. /**
  28. * Enqueues the specified item.
  29. *
  30. * @param {*} item The item to enqueue.
  31. */
  32. Queue.prototype.enqueue = function (item) {
  33. this._array.push(item);
  34. this._length++;
  35. };
  36. /**
  37. * Dequeues an item. Returns undefined if the queue is empty.
  38. *
  39. * @returns {*} The the dequeued item.
  40. */
  41. Queue.prototype.dequeue = function () {
  42. if (this._length === 0) {
  43. return undefined;
  44. }
  45. const array = this._array;
  46. let offset = this._offset;
  47. const item = array[offset];
  48. array[offset] = undefined;
  49. offset++;
  50. if (offset > 10 && offset * 2 > array.length) {
  51. //compact array
  52. this._array = array.slice(offset);
  53. offset = 0;
  54. }
  55. this._offset = offset;
  56. this._length--;
  57. return item;
  58. };
  59. /**
  60. * Returns the item at the front of the queue. Returns undefined if the queue is empty.
  61. *
  62. * @returns {*} The item at the front of the queue.
  63. */
  64. Queue.prototype.peek = function () {
  65. if (this._length === 0) {
  66. return undefined;
  67. }
  68. return this._array[this._offset];
  69. };
  70. /**
  71. * Check whether this queue contains the specified item.
  72. *
  73. * @param {*} item The item to search for.
  74. */
  75. Queue.prototype.contains = function (item) {
  76. return this._array.indexOf(item) !== -1;
  77. };
  78. /**
  79. * Remove all items from the queue.
  80. */
  81. Queue.prototype.clear = function () {
  82. this._array.length = this._offset = this._length = 0;
  83. };
  84. /**
  85. * Sort the items in the queue in-place.
  86. *
  87. * @param {Queue.Comparator} compareFunction A function that defines the sort order.
  88. */
  89. Queue.prototype.sort = function (compareFunction) {
  90. if (this._offset > 0) {
  91. //compact array
  92. this._array = this._array.slice(this._offset);
  93. this._offset = 0;
  94. }
  95. this._array.sort(compareFunction);
  96. };
  97. /**
  98. * A function used to compare two items while sorting a queue.
  99. * @callback Queue.Comparator
  100. *
  101. * @param {*} a An item in the array.
  102. * @param {*} b An item in the array.
  103. * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>,
  104. * a positive value if <code>a</code> is greater than <code>b</code>, or
  105. * 0 if <code>a</code> is equal to <code>b</code>.
  106. *
  107. * @example
  108. * function compareNumbers(a, b) {
  109. * return a - b;
  110. * }
  111. */
  112. export default Queue;