Skip to content

Commit

Permalink
perf: Implement node caching with WeakRef to prevent memory overflow …
Browse files Browse the repository at this point in the history
…and support garbage collection
  • Loading branch information
izure1 committed Sep 4, 2024
1 parent 2e73c29 commit 2c2974c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
5 changes: 3 additions & 2 deletions src/base/BPTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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> = T
type Async<T> = Promise<T>
Expand Down Expand Up @@ -55,7 +56,7 @@ export abstract class BPTree<K, V> {

protected readonly strategy: SerializeStrategy<K, V>
protected readonly comparator: ValueComparator<V>
protected readonly nodes: Map<string, BPTreeUnknownNode<K, V>>
protected readonly nodes: InvertedWeakMap<string, BPTreeUnknownNode<K, V>>
protected order!: number
protected root!: BPTreeUnknownNode<K, V>

Expand Down Expand Up @@ -122,7 +123,7 @@ export abstract class BPTree<K, V> {
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
}
Expand Down
39 changes: 39 additions & 0 deletions src/utils/InvertedWeakMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export class InvertedWeakMap<K extends string|number|symbol, V extends WeakKey> {
private readonly _map: Map<K, WeakRef<V>>
private readonly _registry: FinalizationRegistry<K>

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<K> {
return this._map.keys()
}
}

0 comments on commit 2c2974c

Please sign in to comment.