aboutsummaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/util/SortableSet.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/webpack/lib/util/SortableSet.js')
-rw-r--r--node_modules/webpack/lib/util/SortableSet.js140
1 files changed, 140 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/util/SortableSet.js b/node_modules/webpack/lib/util/SortableSet.js
new file mode 100644
index 00000000..44b692f3
--- /dev/null
+++ b/node_modules/webpack/lib/util/SortableSet.js
@@ -0,0 +1,140 @@
+"use strict";
+
+/**
+ * A subset of Set that offers sorting functionality
+ * @template T item type in set
+ * @extends {Set<T>}
+ */
+class SortableSet extends Set {
+ /**
+ * Create a new sortable set
+ * @param {Iterable<T>=} initialIterable The initial iterable value
+ * @typedef {function(T, T): number} SortFunction
+ * @param {SortFunction=} defaultSort Default sorting function
+ */
+ constructor(initialIterable, defaultSort) {
+ super(initialIterable);
+ /** @private @type {function(T, T): number}} */
+ this._sortFn = defaultSort;
+ /** @private @type {function(T, T): number} | null} */
+ this._lastActiveSortFn = null;
+ /** @private @type {Map<Function, T[]> | undefined} */
+ this._cache = undefined;
+ /** @private @type {Map<Function, T[]|string|number> | undefined} */
+ this._cacheOrderIndependent = undefined;
+ }
+
+ /**
+ * @param {T} value value to add to set
+ * @returns {this} returns itself
+ */
+ add(value) {
+ this._lastActiveSortFn = null;
+ this._invalidateCache();
+ this._invalidateOrderedCache();
+ super.add(value);
+ return this;
+ }
+
+ /**
+ * @param {T} value value to delete
+ * @returns {boolean} true if value existed in set, false otherwise
+ */
+ delete(value) {
+ this._invalidateCache();
+ this._invalidateOrderedCache();
+ return super.delete(value);
+ }
+
+ /**
+ * @returns {void}
+ */
+ clear() {
+ this._invalidateCache();
+ this._invalidateOrderedCache();
+ return super.clear();
+ }
+
+ /**
+ * Sort with a comparer function
+ * @param {SortFunction} sortFn Sorting comparer function
+ * @returns {void}
+ */
+ sortWith(sortFn) {
+ if (this.size <= 1 || sortFn === this._lastActiveSortFn) {
+ // already sorted - nothing to do
+ return;
+ }
+
+ const sortedArray = Array.from(this).sort(sortFn);
+ super.clear();
+ for (let i = 0; i < sortedArray.length; i += 1) {
+ super.add(sortedArray[i]);
+ }
+ this._lastActiveSortFn = sortFn;
+ this._invalidateCache();
+ }
+
+ sort() {
+ this.sortWith(this._sortFn);
+ }
+
+ /**
+ * Get data from cache
+ * @param {function(SortableSet<T>): T[]} fn function to calculate value
+ * @returns {T[]} returns result of fn(this), cached until set changes
+ */
+ getFromCache(fn) {
+ if (this._cache === undefined) {
+ this._cache = new Map();
+ } else {
+ const data = this._cache.get(fn);
+ if (data !== undefined) {
+ return data;
+ }
+ }
+ const newData = fn(this);
+ this._cache.set(fn, newData);
+ return newData;
+ }
+
+ /**
+ * @param {function(SortableSet<T>): string|number|T[]} fn function to calculate value
+ * @returns {any} returns result of fn(this), cached until set changes
+ */
+ getFromUnorderedCache(fn) {
+ if (this._cacheOrderIndependent === undefined) {
+ this._cacheOrderIndependent = new Map();
+ } else {
+ const data = this._cacheOrderIndependent.get(fn);
+ if (data !== undefined) {
+ return data;
+ }
+ }
+ const newData = fn(this);
+ this._cacheOrderIndependent.set(fn, newData);
+ return newData;
+ }
+
+ /**
+ * @private
+ * @returns {void}
+ */
+ _invalidateCache() {
+ if (this._cache !== undefined) {
+ this._cache.clear();
+ }
+ }
+
+ /**
+ * @private
+ * @returns {void}
+ */
+ _invalidateOrderedCache() {
+ if (this._cacheOrderIndependent !== undefined) {
+ this._cacheOrderIndependent.clear();
+ }
+ }
+}
+
+module.exports = SortableSet;