TupleQueue.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const TupleSet = require("./TupleSet");
  7. /**
  8. * FIFO queue for tuples that preserves uniqueness by delegating membership
  9. * tracking to `TupleSet`.
  10. * @template T
  11. * @template V
  12. */
  13. class TupleQueue {
  14. /**
  15. * Seeds the queue with an optional iterable of tuples to visit.
  16. * @param {Iterable<[T, V, ...EXPECTED_ANY]>=} items The initial elements.
  17. */
  18. constructor(items) {
  19. /**
  20. * @private
  21. * @type {TupleSet<T, V>}
  22. */
  23. this._set = new TupleSet(items);
  24. /**
  25. * @private
  26. * @type {Iterator<[T, V, ...EXPECTED_ANY]>}
  27. */
  28. this._iterator = this._set[Symbol.iterator]();
  29. }
  30. /**
  31. * Returns the number of distinct tuples currently queued.
  32. * @returns {number} The number of elements in this queue.
  33. */
  34. get length() {
  35. return this._set.size;
  36. }
  37. /**
  38. * Enqueues a tuple if it is not already present in the underlying set.
  39. * @param {[T, V, ...EXPECTED_ANY]} item The element to add.
  40. * @returns {void}
  41. */
  42. enqueue(...item) {
  43. this._set.add(...item);
  44. }
  45. /**
  46. * Removes and returns the next queued tuple, rebuilding the iterator when
  47. * the underlying tuple set has changed since the last full pass.
  48. * @returns {[T, V, ...EXPECTED_ANY] | undefined} The head of the queue of `undefined` if this queue is empty.
  49. */
  50. dequeue() {
  51. const result = this._iterator.next();
  52. if (result.done) {
  53. if (this._set.size > 0) {
  54. this._iterator = this._set[Symbol.iterator]();
  55. const value =
  56. /** @type {[T, V, ...EXPECTED_ANY]} */
  57. (this._iterator.next().value);
  58. this._set.delete(...value);
  59. return value;
  60. }
  61. return;
  62. }
  63. this._set.delete(.../** @type {[T, V, ...EXPECTED_ANY]} */ (result.value));
  64. return result.value;
  65. }
  66. }
  67. module.exports = TupleQueue;