UNPKG

@inversifyjs/core

Version:

InversifyJs core package

71 lines 2.44 kB
"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