diff --git a/package.json b/package.json index d3d279e..35033c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "serializable-bptree", - "version": "4.0.0", + "version": "4.0.1", "description": "Store the B+tree flexibly, not only in-memory.", "main": "dist/cjs/index.cjs", "module": "dist/esm/index.mjs", diff --git a/src/base/BPTree.ts b/src/base/BPTree.ts index 0bec61d..c97af28 100644 --- a/src/base/BPTree.ts +++ b/src/base/BPTree.ts @@ -2,6 +2,7 @@ import { CacheBranchSync } from 'cachebranch' import { ValueComparator } from './ValueComparator' import { SerializableData, SerializeStrategy } from './SerializeStrategy' +import { InvertedWeakMap } from '../utils/InvertedWeakMap' type Sync = T type Async = Promise @@ -55,7 +56,7 @@ export abstract class BPTree { protected readonly strategy: SerializeStrategy protected readonly comparator: ValueComparator - protected readonly nodes: Map> + protected readonly nodes: InvertedWeakMap> protected order!: number protected root!: BPTreeUnknownNode @@ -122,7 +123,7 @@ export abstract class BPTree { this._nodeCreateBuffer = new Map() this._nodeUpdateBuffer = new Map() this._nodeDeleteBuffer = new Map() - this.nodes = new Map() + this.nodes = new InvertedWeakMap() this.strategy = strategy this.comparator = comparator } diff --git a/src/utils/InvertedWeakMap.ts b/src/utils/InvertedWeakMap.ts new file mode 100644 index 0000000..64a015a --- /dev/null +++ b/src/utils/InvertedWeakMap.ts @@ -0,0 +1,39 @@ +export class InvertedWeakMap { + private readonly _map: Map> + private readonly _registry: FinalizationRegistry + + constructor() { + this._map = new Map() + this._registry = new FinalizationRegistry((key) => this._map.delete(key)) + } + + clear(): void { + return this._map.clear() + } + + delete(key: K): boolean { + return this._map.delete(key) + } + + get(key: K): V|undefined { + return this._map.get(key)?.deref() + } + + has(key: K): boolean { + return this._map.has(key) && this.get(key) !== undefined + } + + set(key: K, value: V): this { + this._map.set(key, new WeakRef(value)) + this._registry.register(value, key) + return this + } + + get size(): number { + return this._map.size + } + + keys(): IterableIterator { + return this._map.keys() + } +}