memory-allocator
Advanced tools
+30
| import { AVLTree } from '@foxglove/avl'; | ||
| export default class Ranges { | ||
| #tree = new AVLTree(); | ||
| add(range) { | ||
| let set = this.#tree.get(range.length); | ||
| if (set === undefined) this.#tree.set(range.length, set = new Set()); | ||
| set.add(range); | ||
| } | ||
| remove(range) { | ||
| if (range === null) return false; | ||
| const set = this.#tree.get(range.length); | ||
| if (set === undefined) return false; | ||
| const success = set.delete(range); | ||
| if (set.size === 0) this.#tree.delete(range.length); | ||
| return success; | ||
| } | ||
| pop(minLength) { | ||
| const entry = this.#tree.findGreaterThanOrEqual(minLength); | ||
| if (entry === undefined) return undefined; | ||
| const set = entry[1]; | ||
| const range = set.values().next().value; | ||
| set.delete(range); | ||
| if (set.size === 0) this.#tree.delete(range.length); | ||
| return range; | ||
| } | ||
| } |
+9
-21
| import BufferRange from './BufferRange.js'; | ||
| import MemoryRef from './MemoryRef.js'; | ||
| import Ranges from './Ranges.js'; | ||
| export default class MemoryAllocator { | ||
| // #memoryRefs = new Set(); | ||
| #ranges = new Set(); | ||
| #ranges = new Ranges(); | ||
| #bufferSize; | ||
@@ -13,6 +14,6 @@ | ||
| addBuffer(size = 0) { | ||
| addBuffer(size = 0, add = true) { | ||
| const buffer = new ArrayBuffer(Math.max(this.#bufferSize, size)); | ||
| const range = new BufferRange(buffer, 0, buffer.byteLength); | ||
| this.#ranges.add(range); | ||
| if (add) this.#ranges.add(range); | ||
| return range; | ||
@@ -22,10 +23,6 @@ } | ||
| allocate(size) { | ||
| let range; // we try to find the smallest range of sufficient size | ||
| for (const r of this.#ranges) { | ||
| if (r.length >= size && (range === undefined || range.length > r.length)) range = r; | ||
| } | ||
| if (range === undefined) range = this.addBuffer(size); | ||
| let range = this.#ranges.pop(size); | ||
| if (range === undefined) range = this.addBuffer(size, false); | ||
| const [allocatedRange, remainingRange] = range.sub(size); | ||
| this.#ranges.delete(range); | ||
| if (remainingRange.length > 0) this.#ranges.add(remainingRange); | ||
@@ -39,17 +36,8 @@ | ||
| #free(ref, range) { | ||
| async #free(ref, range) { | ||
| // this.#memoryRefs.delete(ref); | ||
| if (this.#ranges.has(range.left)) { | ||
| this.#ranges.delete(range.left); | ||
| range = range.mergeLeft(); | ||
| } | ||
| if (this.#ranges.has(range.right)) { | ||
| this.#ranges.delete(range.right); | ||
| range = range.mergeRight(); | ||
| } | ||
| if (this.#ranges.remove(range.left)) range = range.mergeLeft(); | ||
| if (this.#ranges.remove(range.right)) range = range.mergeRight(); | ||
| this.#ranges.add(range); | ||
| } | ||
| } |
+1
-1
@@ -15,3 +15,3 @@ import EventEmitter from 'events'; | ||
| async free() { | ||
| free() { | ||
| const range = this.#range; | ||
@@ -18,0 +18,0 @@ this.#range = null; |
+2
-1
| { | ||
| "name": "memory-allocator", | ||
| "author": "Warriors Life", | ||
| "version": "0.1.0", | ||
| "version": "0.2.0", | ||
| "description": "Simple ArrayBuffer memory allocator", | ||
@@ -20,4 +20,5 @@ "license": "MIT", | ||
| "dependencies": { | ||
| "@foxglove/avl": "^1.0.0", | ||
| "events": "^3.3.0" | ||
| } | ||
| } |
+3
-3
| # memory-allocator | ||
| A simple ArrayBuffer memory allocator for JS. | ||
| A simple ArrayBuffer memory allocator for JS. It can be found on NPM as [`memory-allocator`](https://www.npmjs.com/package/memory-allocator) or [`@warriors-life/memory-allocator`](https://www.npmjs.com/package/@warriors-life/memory-allocator), or on [GitHub Packages](https://github.com/warriors-life/memory-allocator/pkgs/npm/memory-allocator) as latter. | ||
@@ -22,3 +22,3 @@ Not to be confused with the [`memory-pool`](https://www.npmjs.com/package/memory-pool) package, which removes the overhead of object creation by maintaining a pool of them and modifying their properties (see also [`PrimitivePool`](https://github.com/gkjohnson/three-mesh-bvh/blob/master/src/utils/PrimitivePool.js)). | ||
| ### .addBuffer(size?: number >= bufferSize): ignore | ||
| Manually create a buffer of the specified size. | ||
| Manually add a buffer of the specified size. | ||
@@ -31,3 +31,3 @@ ### .allocate(size): MemoryRef | ||
| ### async .free(): void | ||
| ### .free(): void | ||
| Mark the reference as freed. It can no longer be used after that and the underlying memory may be redistributed. | ||
@@ -34,0 +34,0 @@ |
7626
13.5%8
14.29%130
14.04%2
100%+ Added
+ Added