feat: refactoring project

This commit is contained in:
Carlos
2024-11-23 14:56:07 -05:00
parent f0c2a50c18
commit 1c6db5818d
2351 changed files with 39323 additions and 60326 deletions

View File

@@ -8,6 +8,16 @@
const { first } = require("./SetHelpers");
const SortableSet = require("./SortableSet");
/**
* @template T
* @typedef {LazyBucketSortedSet<T, any> | SortableSet<T>} Entry
*/
/**
* @template T
* @typedef {(function(T): any) | (function(any, any): number)} Arg
*/
/**
* Multi layer bucket sorted set:
* Supports adding non-existing items (DO NOT ADD ITEM TWICE),
@@ -24,14 +34,15 @@ class LazyBucketSortedSet {
/**
* @param {function(T): K} getKey function to get key from item
* @param {function(K, K): number} comparator comparator to sort keys
* @param {...((function(T): any) | (function(any, any): number))} args more pairs of getKey and comparator plus optional final comparator for the last layer
* @param {...Arg<T>} args more pairs of getKey and comparator plus optional final comparator for the last layer
*/
constructor(getKey, comparator, ...args) {
this._getKey = getKey;
/** @type {Arg<T>[]} */
this._innerArgs = args;
this._leaf = args.length <= 1;
this._keys = new SortableSet(undefined, comparator);
/** @type {Map<K, LazyBucketSortedSet<T, any> | SortableSet<T>>} */
/** @type {Map<K, Entry<T>>} */
this._map = new Map();
this._unsortedItems = new Set();
this.size = 0;
@@ -54,13 +65,18 @@ class LazyBucketSortedSet {
_addInternal(key, item) {
let entry = this._map.get(key);
if (entry === undefined) {
entry = this._leaf
? new SortableSet(undefined, this._innerArgs[0])
: new /** @type {any} */ (LazyBucketSortedSet)(...this._innerArgs);
entry =
/** @type {Entry<T>} */
(
this._leaf
? new SortableSet(undefined, this._innerArgs[0])
: new /** @type {TODO} */ (LazyBucketSortedSet)(...this._innerArgs)
);
this._keys.add(key);
this._map.set(key, entry);
}
entry.add(item);
/** @type {Entry<T>} */
(entry).add(item);
}
/**
@@ -74,7 +90,7 @@ class LazyBucketSortedSet {
return;
}
const key = this._getKey(item);
const entry = this._map.get(key);
const entry = /** @type {Entry<T>} */ (this._map.get(key));
entry.delete(item);
if (entry.size === 0) {
this._deleteKey(key);
@@ -94,7 +110,7 @@ class LazyBucketSortedSet {
* @returns {T | undefined} an item
*/
popFirst() {
if (this.size === 0) return undefined;
if (this.size === 0) return;
this.size--;
if (this._unsortedItems.size > 0) {
for (const item of this._unsortedItems) {
@@ -104,25 +120,24 @@ class LazyBucketSortedSet {
this._unsortedItems.clear();
}
this._keys.sort();
const key = first(this._keys);
const key = /** @type {K} */ (first(this._keys));
const entry = this._map.get(key);
if (this._leaf) {
const leafEntry = /** @type {SortableSet<T>} */ (entry);
leafEntry.sort();
const item = first(leafEntry);
const item = /** @type {T} */ (first(leafEntry));
leafEntry.delete(item);
if (leafEntry.size === 0) {
this._deleteKey(key);
}
return item;
} else {
const nodeEntry = /** @type {LazyBucketSortedSet<T, any>} */ (entry);
const item = nodeEntry.popFirst();
if (nodeEntry.size === 0) {
this._deleteKey(key);
}
return item;
}
const nodeEntry = /** @type {LazyBucketSortedSet<T, any>} */ (entry);
const item = nodeEntry.popFirst();
if (nodeEntry.size === 0) {
this._deleteKey(key);
}
return item;
}
/**
@@ -135,7 +150,6 @@ class LazyBucketSortedSet {
if (remove) {
this._unsortedItems.delete(item);
this.size--;
return;
}
};
}
@@ -163,32 +177,31 @@ class LazyBucketSortedSet {
this._addInternal(newKey, item);
}
};
} else {
const oldEntry = /** @type {LazyBucketSortedSet<T, any>} */ (
this._map.get(key)
);
const finishUpdate = oldEntry.startUpdate(item);
return remove => {
if (remove) {
this.size--;
finishUpdate(true);
if (oldEntry.size === 0) {
this._deleteKey(key);
}
return;
}
const newKey = this._getKey(item);
if (key === newKey) {
finishUpdate();
} else {
finishUpdate(true);
if (oldEntry.size === 0) {
this._deleteKey(key);
}
this._addInternal(newKey, item);
}
};
}
const oldEntry = /** @type {LazyBucketSortedSet<T, any>} */ (
this._map.get(key)
);
const finishUpdate = oldEntry.startUpdate(item);
return remove => {
if (remove) {
this.size--;
finishUpdate(true);
if (oldEntry.size === 0) {
this._deleteKey(key);
}
return;
}
const newKey = this._getKey(item);
if (key === newKey) {
finishUpdate();
} else {
finishUpdate(true);
if (oldEntry.size === 0) {
this._deleteKey(key);
}
this._addInternal(newKey, item);
}
};
}
/**
@@ -215,16 +228,19 @@ class LazyBucketSortedSet {
* @returns {Iterator<T>} the iterator
*/
[Symbol.iterator]() {
/** @type {Iterator<T>[]} */
const iterators = [];
this._appendIterators(iterators);
iterators.reverse();
let currentIterator = iterators.pop();
let currentIterator =
/** @type {Iterator<T>} */
(iterators.pop());
return {
next: () => {
const res = currentIterator.next();
if (res.done) {
if (iterators.length === 0) return res;
currentIterator = iterators.pop();
currentIterator = /** @type {Iterator<T>} */ (iterators.pop());
return currentIterator.next();
}
return res;