@inversifyjs/core
Version:
InversifyJs core package
71 lines • 2.44 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WeakList = void 0;
const DEFAULT_MINIMUM_LENGTH_TO_REALLOCATE = 8;
const DEFAULT_MODULUS_TO_REALLOCATE_ON_PUSH = 1024;
const MIN_DEAD_REFS_FOR_REALLOCATION_PERCENTAGE = 0.5;
/**
* A list-like collection that holds weak references to objects.
* Automatically cleans up dead references when a threshold is met.
*
* FinalizationRegistry is not used here due to it's lack of determinism.
* FinalizationRegsitry callbacks are not guaranteed to be called after an object is garbage collected.
*/
class WeakList {
#list;
#minimumLengthToReallocate;
#modulusToReallocateOnPush;
constructor() {
this.#list = [];
this.#minimumLengthToReallocate = DEFAULT_MINIMUM_LENGTH_TO_REALLOCATE;
this.#modulusToReallocateOnPush = DEFAULT_MODULUS_TO_REALLOCATE_ON_PUSH;
}
*[Symbol.iterator]() {
let deadRefCount = 0;
for (const weakRef of this.#list) {
const value = weakRef.deref();
if (value === undefined) {
++deadRefCount;
}
else {
yield value;
}
}
if (this.#list.length >= this.#minimumLengthToReallocate &&
this.#shouldReallocate(deadRefCount)) {
this.#reallocate(deadRefCount);
}
}
push(value) {
const weakRef = new WeakRef(value);
this.#list.push(weakRef);
if (this.#list.length >= this.#minimumLengthToReallocate &&
this.#list.length % this.#modulusToReallocateOnPush === 0) {
let deadRefCount = 0;
for (const ref of this.#list) {
if (ref.deref() === undefined) {
++deadRefCount;
}
}
if (this.#shouldReallocate(deadRefCount)) {
this.#reallocate(deadRefCount);
}
}
}
#reallocate(deadRefCount) {
const newList = new Array(this.#list.length - deadRefCount);
let i = 0;
for (const ref of this.#list) {
if (ref.deref()) {
newList[i++] = ref;
}
}
this.#list = newList;
}
#shouldReallocate(deadRefCount) {
return (deadRefCount >=
this.#list.length * MIN_DEAD_REFS_FOR_REALLOCATION_PERCENTAGE);
}
}
exports.WeakList = WeakList;
//# sourceMappingURL=WeakList.js.map