AppendOnlyStackedSet.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Ivan Kopeykin @vankop
  4. */
  5. "use strict";
  6. /**
  7. * @template T
  8. */
  9. class AppendOnlyStackedSet {
  10. /**
  11. * @param {Set<T>[]} sets an optional array of sets
  12. */
  13. constructor(sets = []) {
  14. /** @type {Set<T>[]} */
  15. this._sets = sets;
  16. /** @type {Set<T> | undefined} */
  17. this._current = undefined;
  18. }
  19. /**
  20. * @param {T} el element
  21. */
  22. add(el) {
  23. if (!this._current) {
  24. this._current = new Set();
  25. this._sets.push(this._current);
  26. }
  27. this._current.add(el);
  28. }
  29. /**
  30. * @param {T} el element
  31. * @returns {boolean} result
  32. */
  33. has(el) {
  34. for (const set of this._sets) {
  35. if (set.has(el)) return true;
  36. }
  37. return false;
  38. }
  39. clear() {
  40. this._sets = [];
  41. if (this._current) {
  42. this._current = undefined;
  43. }
  44. }
  45. /**
  46. * @returns {AppendOnlyStackedSet<T>} child
  47. */
  48. createChild() {
  49. return new AppendOnlyStackedSet(this._sets.length ? [...this._sets] : []);
  50. }
  51. /**
  52. * @returns {Iterator<T>} iterable iterator
  53. */
  54. [Symbol.iterator]() {
  55. const iterators = this._sets.map((map) => map[Symbol.iterator]());
  56. let current = iterators.pop();
  57. return {
  58. next() {
  59. if (!current) return { done: true, value: undefined };
  60. let result = current.next();
  61. while (result.done && iterators.length > 0) {
  62. current = /** @type {SetIterator<T>} */ (iterators.pop());
  63. result = current.next();
  64. }
  65. return result;
  66. }
  67. };
  68. }
  69. }
  70. module.exports = AppendOnlyStackedSet;