ArrayQueue.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /**
  7. * @template T
  8. */
  9. class ArrayQueue {
  10. /**
  11. * @param {Iterable<T>=} items The initial elements.
  12. */
  13. constructor(items) {
  14. /**
  15. * @private
  16. * @type {T[]}
  17. */
  18. this._list = items ? Array.from(items) : [];
  19. /**
  20. * @private
  21. * @type {T[]}
  22. */
  23. this._listReversed = [];
  24. }
  25. /**
  26. * Returns the number of elements in this queue.
  27. * @returns {number} The number of elements in this queue.
  28. */
  29. get length() {
  30. return this._list.length + this._listReversed.length;
  31. }
  32. /**
  33. * Empties the queue.
  34. */
  35. clear() {
  36. this._list.length = 0;
  37. this._listReversed.length = 0;
  38. }
  39. /**
  40. * Appends the specified element to this queue.
  41. * @param {T} item The element to add.
  42. * @returns {void}
  43. */
  44. enqueue(item) {
  45. this._list.push(item);
  46. }
  47. /**
  48. * Retrieves and removes the head of this queue.
  49. * @returns {T | undefined} The head of the queue of `undefined` if this queue is empty.
  50. */
  51. dequeue() {
  52. if (this._listReversed.length === 0) {
  53. if (this._list.length === 0) return undefined;
  54. if (this._list.length === 1) return this._list.pop();
  55. if (this._list.length < 16) return this._list.shift();
  56. const temp = this._listReversed;
  57. this._listReversed = this._list;
  58. this._listReversed.reverse();
  59. this._list = temp;
  60. }
  61. return this._listReversed.pop();
  62. }
  63. /**
  64. * Finds and removes an item
  65. * @param {T} item the item
  66. * @returns {void}
  67. */
  68. delete(item) {
  69. const i = this._list.indexOf(item);
  70. if (i >= 0) {
  71. this._list.splice(i, 1);
  72. } else {
  73. const i = this._listReversed.indexOf(item);
  74. if (i >= 0) this._listReversed.splice(i, 1);
  75. }
  76. }
  77. [Symbol.iterator]() {
  78. return {
  79. next: () => {
  80. const item = this.dequeue();
  81. if (item) {
  82. return {
  83. done: false,
  84. value: item
  85. };
  86. }
  87. return {
  88. done: true,
  89. value: undefined
  90. };
  91. }
  92. };
  93. }
  94. }
  95. module.exports = ArrayQueue;