@nxtedition/slice 1.1.10 → 1.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,52 +34,56 @@ const s = new Slice()
34
34
 
35
35
  pool.realloc(s, 64) // allocate 64 bytes from pool
36
36
  s.write('hello')
37
- pool.realloc(s, 128) // grow — may reuse same slot
37
+ pool.realloc(s, 128) // grow — moves to the 128-byte bucket (contents not preserved)
38
+ pool.realloc(s, 100) // shrink within the bucket — in-place, just a field update
38
39
  pool.realloc(s, 0) // free — slot is recycled
39
40
  ```
40
41
 
41
42
  ## Benchmarks
42
43
 
43
- Measured on Apple M3 Pro, Node.js v25.3.0:
44
+ Measured on Apple M3 Pro, Node.js v25.6.1. Every `PoolAllocator` iteration performs a real alloc + free pair (a bare repeated `realloc(slice, N)` would hit the same-size early return and measure a no-op).
44
45
 
45
- ### Allocation
46
+ ### Allocation (alloc + free per iteration)
46
47
 
47
- | Operation | `Buffer.allocUnsafe` | `Buffer.allocUnsafeSlow` | `PoolAllocator` | Speedup |
48
- | ---------------- | -------------------: | -----------------------: | --------------: | ------: |
49
- | alloc 64 bytes | 38.08 ns | 41.23 ns | **5.66 ns** | 6.7x |
50
- | alloc 256 bytes | 52.09 ns | 231.46 ns | **5.90 ns** | 8.8x |
51
- | alloc 1024 bytes | 91.24 ns | 340.75 ns | **5.83 ns** | 15.6x |
52
- | alloc 4096 bytes | 446.53 ns | 437.83 ns | **6.24 ns** | 71.6x |
48
+ | Operation | `Buffer.allocUnsafe` | `Buffer.allocUnsafeSlow` | `PoolAllocator` | Speedup |
49
+ | --------------------- | -------------------: | -----------------------: | --------------: | ------: |
50
+ | alloc/free 64 bytes | 28.87 ns | 31.08 ns | **14.05 ns** | 2.1x |
51
+ | alloc/free 256 bytes | 38.22 ns | 172.16 ns | **12.97 ns** | 2.9x |
52
+ | alloc/free 1024 bytes | 61.32 ns | 226.35 ns | **13.16 ns** | 4.7x |
53
+ | alloc/free 4096 bytes | 285.70 ns | 272.15 ns | **13.21 ns** | 20.6x |
53
54
 
54
55
  ### Allocation (GC)
55
56
 
56
- | Operation | `Buffer.allocUnsafe` | `Buffer.allocUnsafeSlow` | `PoolAllocator` | Speedup |
57
- | ---------------- | -------------------: | -----------------------: | --------------: | ------: |
58
- | alloc 64 bytes | 400.46 ns | 167.94 ns | **6.33 ns** | 63.3x |
59
- | alloc 256 bytes | 309.57 ns | 500.58 ns | **6.35 ns** | 48.7x |
60
- | alloc 4096 bytes | 653.40 ns | 620.19 ns | **6.32 ns** | 103.4x |
57
+ | Operation | `Buffer.allocUnsafe` | `Buffer.allocUnsafeSlow` | `PoolAllocator` | Speedup |
58
+ | --------------------- | -------------------: | -----------------------: | --------------: | ------: |
59
+ | alloc/free 64 bytes | 204.54 ns | 107.27 ns | **17.60 ns** | 6.1x |
60
+ | alloc/free 256 bytes | 198.66 ns | 324.21 ns | **17.58 ns** | 11.3x |
61
+ | alloc/free 4096 bytes | 378.27 ns | 360.77 ns | **17.28 ns** | 20.9x |
61
62
 
62
- Under GC pressure, the advantage grows dramatically — up to **103x** faster — because `PoolAllocator` reuses slots from a pre-allocated buffer and never creates objects for V8 to trace.
63
+ Under GC pressure the advantage grows — up to **~21x** — because `PoolAllocator` reuses slots from a pre-allocated buffer and never creates objects for V8 to trace. Speedup is computed against the faster of the two `Buffer` variants.
63
64
 
64
65
  ### Slice creation vs `Buffer.subarray`
65
66
 
66
67
  | Operation | `Buffer.subarray` | `Slice` | Speedup |
67
68
  | ---------------------- | ----------------: | -----------: | ------: |
68
- | subarray 64 bytes | 38.11 ns | **12.99 ns** | 2.9x |
69
- | subarray 1024 bytes | 36.87 ns | **13.26 ns** | 2.8x |
70
- | subarray 64 bytes (GC) | 127.30 ns | **81.60 ns** | 1.6x |
69
+ | subarray 64 bytes | 29.32 ns | **4.13 ns** | 7.1x |
70
+ | subarray 1024 bytes | 28.60 ns | **4.11 ns** | 7.0x |
71
+ | subarray 64 bytes (GC) | 90.84 ns | **80.43 ns** | 1.1x |
71
72
 
72
73
  ### Combined operations
73
74
 
75
+ `Buffer` is the faster of `Buffer.allocUnsafe`/`Buffer.allocUnsafeSlow` per row.
76
+
74
77
  | Operation | `Buffer` | `PoolAllocator` | Speedup |
75
78
  | ------------------------------------- | --------: | --------------: | ------: |
76
- | alloc/free 64 bytes | 32.72 ns | **30.80 ns** | 1.1x |
77
- | alloc/free 64 bytes (GC) | 273.35 ns | **73.34 ns** | 3.7x |
78
- | alloc/free 256 bytes | 58.88 ns | **29.38 ns** | 2.0x |
79
- | realloc churn (64 → 128 → 64) | 93.63 ns | **26.99 ns** | 3.5x |
80
- | realloc in-place (grow within bucket) | 60.16 ns | **11.06 ns** | 5.4x |
81
- | 10 concurrent allocs then free | 406.26 ns | **337.83 ns** | 1.2x |
82
- | 10 concurrent allocs then free (GC) | 647.95 ns | **649.73 ns** | 1.0x |
79
+ | new Slice + alloc/free 64 bytes | 25.54 ns | **15.44 ns** | 1.7x |
80
+ | new Slice + alloc/free 64 bytes (GC) | 116.92 ns | **61.42 ns** | 1.9x |
81
+ | new Slice + alloc/free 256 bytes | 29.62 ns | **15.38 ns** | 1.9x |
82
+ | realloc churn (64 → 128 → 64) | 48.76 ns | **17.30 ns** | 2.8x |
83
+ | realloc in-place (grow within bucket) | 48.39 ns | **6.84 ns** | 7.1x |
84
+ | 10 concurrent allocs then free | 307.90 ns | **176.16 ns** | 1.7x |
85
+ | 10 concurrent allocs then free (GC) | 470.07 ns | **372.63 ns** | 1.3x |
86
+ | 10 concurrent allocs then free ×2 | 635.30 ns | **345.13 ns** | 1.8x |
83
87
 
84
88
  ## API
85
89
 
@@ -89,19 +93,23 @@ A lightweight view over a `Buffer` with explicit offset and length tracking.
89
93
 
90
94
  #### `new Slice(buffer?: Buffer, byteOffset?: number, byteLength?: number, maxByteLength?: number)`
91
95
 
92
- Creates a new slice. All parameters are optional — defaults to an empty slice.
96
+ Creates a new slice. All parameters are optional — defaults to an empty slice. `byteLength` defaults to the remaining bytes (`buffer.byteLength - byteOffset`), matching `Slice.from` and typed-array conventions. The constructor does **no** validation; pass only consistent values, or use `Slice.from` for a checked construction.
97
+
98
+ #### `Slice.from(buffer: Buffer, byteOffset?: number, byteLength?: number): Slice`
99
+
100
+ Validated factory for wrapping an existing `Buffer`. `byteOffset` defaults to `0` and `byteLength` to the remaining bytes (`buffer.byteLength - byteOffset`). Throws `TypeError` if `buffer` is not a `Buffer`, and `RangeError` if `byteOffset`/`byteLength` are negative, non-integer, or `byteOffset + byteLength` exceeds the buffer. Prefer this over the bare constructor when the inputs are untrusted.
93
101
 
94
102
  #### Properties
95
103
 
96
104
  - `buffer: Buffer` — The underlying `Buffer`
97
105
  - `byteOffset: number` — Start offset into the buffer
98
106
  - `byteLength: number` — Current length in bytes
99
- - `maxByteLength: number` — Maximum capacity in bytes
107
+ - `maxByteLength: number` — For a pool-allocated slice, the power-of-2 bucket capacity (always `>= byteLength`). For a heap-fallback slice it tracks the allocation's capacity (the high-water `byteLength`), which `realloc` uses to resize large slices in place. For a manually-constructed slice it defaults to `byteLength` and no `Slice` method bounds reads or writes against it (those are validated/clamped against `byteLength`) — but `realloc` treats any non-pool slice's `maxByteLength` as its capacity if such a slice is passed to it.
100
108
  - `length: number` — Alias for `byteLength`
101
109
 
102
110
  #### Methods
103
111
 
104
- - `reset(): void` — Clear the slice back to empty state. **Note:** this does not return the slot to the `PoolAllocator` you must call `realloc(slice, 0)` to free pool memory.
112
+ - `reset(): void` — Clear the slice back to empty state. **Note:** this does not return the slot to the `PoolAllocator`. To free pool memory call `realloc(slice, 0)` and do **not** `reset()` first: `reset()` detaches the slice from the pool buffer, so a subsequent `realloc(slice, 0)` can no longer locate the slot and the slot leaks.
105
113
  - `copy(target: Uint8Array | Slice, targetStart?: number, sourceStart?: number, sourceEnd?: number): number` — Copy data to a `Uint8Array`/`Buffer` or `Slice`. Returns bytes copied.
106
114
  - `compare(target: Uint8Array | Slice, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): -1 | 0 | 1` — Compare with a `Uint8Array`/`Buffer` or `Slice`
107
115
  - `write(string: string, offset?: number, length?: number, encoding?: BufferEncoding): number` — Write a string into the slice. Returns bytes written.
@@ -117,8 +125,10 @@ All offsets are **relative to the slice** (i.e. `0` is `byteOffset`). For a `Sli
117
125
 
118
126
  The rule is consistent across the API:
119
127
 
120
- - **Start/offset arguments are validated** — `set`'s `offset`, `copy`/`compare`'s `sourceStart`/`targetStart`, `toString`/`toBuffer`'s `start`, `write`'s `offset`/`length`, and `at`'s `index` must be in-range integers. Out-of-range or non-integer values throw `RangeError`. This prevents a negative offset from resolving to a position **before** the slice and reading/writing adjacent (pool) memory.
121
- - **End arguments are clamped** — `sourceEnd`/`targetEnd`/`end` are clamped to the slice's logical length (matching `Buffer`'s lenient end-of-range behavior), so over-long ranges never read past the slice's end.
128
+ - **Start/offset arguments are validated** — `set`'s `offset`, `copy`/`compare`'s `sourceStart`/`targetStart`, `toString`/`toBuffer`'s `start`, `write`'s `offset`, and `at`'s `index` must be in-range integers. Out-of-range or non-integer values throw `RangeError`. This prevents a negative offset from resolving to a position **before** the slice and reading/writing adjacent (pool) memory.
129
+ - **End arguments are validated, then clamped** — `sourceEnd`/`targetEnd`/`end` must be integers (`NaN`, fractional, and `±Infinity` throw `RangeError`; omit the argument to mean "to the end of the slice"). In-range validation stays lenient: integer ends beyond the slice are clamped to the slice's logical length (matching `Buffer`'s end-of-range behavior), so over-long ranges never read past the slice's end.
130
+ - **`write`'s `length` is hybrid** — a negative or non-integer `length` throws `RangeError`, but a too-large `length` is clamped to the bytes available in the slice (it behaves like an end argument, not a strict start argument).
131
+ - For a raw `Buffer`/`Uint8Array` target, `targetStart`/`targetEnd` (and a non-`Slice` `compare` target's range) are passed straight through to the underlying `Buffer` method, so they follow `Buffer`'s own coercion/validation rather than the rules above.
122
132
 
123
133
  #### Static
124
134
 
@@ -130,17 +140,17 @@ Pre-allocates a contiguous memory pool and manages slices using power-of-2 bucke
130
140
 
131
141
  #### `new PoolAllocator(poolTotalOrBuffer?: number | Buffer | ArrayBufferView | ArrayBuffer | SharedArrayBuffer)`
132
142
 
133
- Creates a pool allocator. Pass a byte size to allocate a fresh backing buffer (default 128 MB, must be a non-negative integer), or pass an existing `Buffer`/`ArrayBufferView`/`ArrayBuffer`/`SharedArrayBuffer` to back the pool with caller-provided memory.
143
+ Creates a pool allocator. Pass a byte size to allocate a fresh backing buffer (default 128 MB, must be a non-negative integer), or pass an existing `Buffer`/`ArrayBufferView`/`ArrayBuffer`/`SharedArrayBuffer` to back the pool with caller-provided memory. `Infinity` means **unbounded**: no pool is pre-allocated, every allocation falls back to a standalone `Buffer`, and `size` stays `0` — so size-based pruning never triggers. `NaN`, negative, and fractional sizes throw `RangeError`.
134
144
 
135
145
  > **Single-owner.** The allocator's bookkeeping lives in the instance, not in the backing buffer. When you supply your own buffer, that buffer must be owned exclusively by this allocator: do not build your own `Slice` views over it, do not share it with a second `PoolAllocator`, and (for a `SharedArrayBuffer`) do not allocate from more than one thread — the metadata is not shared or atomic, so doing any of these silently produces overlapping allocations.
136
146
 
137
147
  #### Methods
138
148
 
139
149
  - `realloc(byteLength: number): Slice` — Allocate a fresh slice.
140
- - `realloc(slice: Slice, byteLength: number): Slice` — Resize a slice, or free it by passing `0`. **Contents are not preserved** — `realloc` has `malloc` semantics, not C `realloc` semantics; after a resize the bytes are undefined (a same-bucket resize happens to keep them in place, but do not rely on it). Only call `realloc` with a slice that belongs to this allocator (or a fresh/empty `Slice`); passing a slice from another pool, or freeing the same slice twice, corrupts the allocator's accounting.
150
+ - `realloc(slice: Slice, byteLength: number): Slice` — Resize a slice, or free it by passing `0`. **Contents are not preserved** — `realloc` has `malloc` semantics, not C `realloc` semantics; after a resize the bytes are undefined (a same-bucket or in-place resize happens to keep them in place, but do not rely on it). Only call `realloc` with a slice that belongs to this allocator (or a fresh/empty `Slice`); passing a slice from another pool over the same backing buffer, or freeing the same pool slot through two aliasing `Slice` objects, throws `Invalid pool state` when the corruption is detectable (a bucket's live count would go negative) — but do not rely on detection: an aliasing free while other slices remain live in the same bucket silently corrupts the accounting. (Calling `realloc(slice, 0)` twice on the _same_ object is a harmless no-op — the first free empties the slice, so the second returns immediately.)
141
151
  - `isFromPool(slice: Slice | null | undefined): boolean` — Check if a slice's buffer is this pool's backing buffer. Note this is an identity check; it returns `true` for any slice over the same buffer, not only ones this allocator handed out.
142
152
 
143
- Allocations larger than 256 KB (the largest bucket), or made when the contiguous pool is exhausted, fall back to a fresh standalone `Buffer` (`isFromPool` returns `false`) and are excluded from `size`/`stats`.
153
+ Allocations larger than 256 KB (the largest bucket), or made when the contiguous pool is exhausted, fall back to a fresh standalone `Buffer` (`isFromPool` returns `false`) and are excluded from `size`/`stats`. Resizing such a slice while the request stays above 256 KB reuses the existing backing store in place when it fits — capacity is retained up to the power-of-2 ceiling of the request (< 2× waste), so size churn **within the retained capacity** does not reallocate (churn spanning a wider than 2× band still reallocates); shrinking below that bound, or to a pool-eligible size, allocates anew (rejoining the pool when possible). Note the in-place path keeps whatever backing buffer the slice already has — including a hand-constructed one — so do not use `realloc` to detach a slice from caller-shared memory.
144
154
 
145
155
  #### Properties
146
156
 
package/lib/index.d.ts CHANGED
@@ -49,3 +49,4 @@ export declare class PoolAllocator {
49
49
  }[];
50
50
  };
51
51
  }
52
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAI5B,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,qBAAa,KAAM,YAAW,SAAS;IACrC,MAAM,EAAE,MAAM,CAAY;IAC1B,UAAU,EAAE,MAAM,CAAI;IACtB,UAAU,EAAE,MAAM,CAAI;IACtB,aAAa,EAAE,MAAM,CAAI;IAEzB,MAAM,KAAK,SAAS,IAAI,MAAM,CAE7B;IAED,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,SAAI,EAAE,UAAU,SAAiC,GAAG,KAAK;gBAuB7F,MAAM,0BAAkB,EACxB,UAAU,SAAI,EACd,UAAU,SAAiC,EAC3C,aAAa,SAAa;IAQ5B,KAAK,IAAI,IAAI;IAOb,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,CACF,MAAM,EAAE,UAAU,GAAG,KAAK,EAC1B,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM;IAuET,OAAO,CACL,MAAM,EAAE,UAAU,GAAG,KAAK,EAC1B,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAwEb,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM;IA2B1F,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAyBrE,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IASzB,IAAI,CAAC,IAAI,EAAE;QACT,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAA;KAC1E,GAAG,OAAO;IAIX,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM;IA+BzE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM;IAiC9C,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAEjC;IAED,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM;CAkChC;AAED,qBAAa,aAAa;;gBAYtB,iBAAiB,GAAE,MAAM,GAAG,eAAe,GAAG,WAAW,GAAG,iBAAiB,GAAG,MAE1E;IAuCR,IAAI,IAAI,WAEP;IAED,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO;IAIpD,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK;IAClC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,GAAG,KAAK;IAsIhD,IAAI,KAAK;;;;;;;;;;;;;MAeR;CACF"}
package/lib/index.js CHANGED
@@ -1,517 +1,501 @@
1
- import util from 'node:util'
2
-
3
- const EMPTY_BUF = Buffer.alloc(0)
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
- export class Slice {
12
- buffer = EMPTY_BUF
13
- byteOffset = 0
14
- byteLength = 0
15
- maxByteLength = 0
16
-
17
- static get EMPTY_BUF() {
18
- return EMPTY_BUF
19
- }
20
-
21
- static from(buffer , byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
22
- if (!(buffer instanceof Buffer)) {
23
- throw new TypeError('buffer must be a Buffer')
24
- }
25
-
26
- if (byteOffset < 0 || !Number.isInteger(byteOffset)) {
27
- throw new RangeError(`Invalid byteOffset: ${byteOffset}`)
28
- }
29
-
30
- if (byteLength < 0 || !Number.isInteger(byteLength)) {
31
- throw new RangeError(`Invalid byteLength: ${byteLength}`)
32
- }
33
-
34
- if (byteOffset + byteLength > buffer.byteLength) {
35
- throw new RangeError(
36
- `byteOffset + byteLength (${byteOffset + byteLength}) exceeds buffer size (${buffer.byteLength})`,
37
- )
38
- }
39
-
40
- return new Slice(buffer, byteOffset, byteLength)
41
- }
42
-
43
- constructor(
44
- buffer = Slice.EMPTY_BUF,
45
- byteOffset = 0,
46
- byteLength = buffer.byteLength,
47
- maxByteLength = byteLength,
48
- ) {
49
- this.buffer = buffer
50
- this.byteOffset = byteOffset
51
- this.byteLength = byteLength
52
- this.maxByteLength = maxByteLength
53
- }
54
-
55
- reset() {
56
- this.buffer = Slice.EMPTY_BUF
57
- this.byteOffset = 0
58
- this.byteLength = 0
59
- this.maxByteLength = 0
60
- }
61
-
62
- get length() {
63
- return this.byteLength
64
- }
65
-
66
- copy(
67
- target ,
68
- targetStart ,
69
- sourceStart ,
70
- sourceEnd ,
71
- ) {
72
- const sliceEnd = this.byteOffset + this.byteLength
73
-
74
- if (sourceStart === undefined) {
75
- sourceStart = this.byteOffset
76
- } else {
77
- // Start offsets are validated (not clamped) so a negative offset can
78
- // never resolve to a position before the slice and read adjacent
79
- // (pool) memory.
80
- if (sourceStart < 0 || sourceStart > this.byteLength || !Number.isInteger(sourceStart)) {
81
- throw new RangeError(`Invalid sourceStart: ${sourceStart}`)
82
- }
83
- sourceStart += this.byteOffset
84
- }
85
-
86
- if (sourceEnd === undefined) {
87
- sourceEnd = sliceEnd
88
- } else {
89
- sourceEnd += this.byteOffset
90
- }
91
-
92
- // Clamp the end against the logical slice length so copy() cannot read
93
- // past the slice's own end and leak adjacent (pool) memory.
94
- if (sourceEnd > sliceEnd) {
95
- sourceEnd = sliceEnd
96
- }
97
- if (sourceEnd < sourceStart) {
98
- sourceEnd = sourceStart
99
- }
100
-
101
- if (target instanceof Slice) {
102
- const targetEnd = target.byteOffset + target.byteLength
103
- if (targetStart === undefined) {
104
- targetStart = target.byteOffset
105
- } else {
106
- if (targetStart < 0 || targetStart > target.byteLength || !Number.isInteger(targetStart)) {
107
- throw new RangeError(`Invalid targetStart: ${targetStart}`)
108
- }
109
- targetStart += target.byteOffset
110
- }
111
-
112
- target = target.buffer
113
- if (sourceEnd - sourceStart > targetEnd - targetStart) {
114
- sourceEnd = sourceStart + (targetEnd - targetStart)
115
- }
116
- }
117
-
118
- if (
119
- sourceStart === targetStart &&
120
- this.buffer.buffer === target.buffer &&
121
- this.buffer.byteOffset === target.byteOffset
122
- ) {
123
- return sourceEnd - sourceStart
124
- }
125
-
126
- return this.buffer.copy(target, targetStart, sourceStart, sourceEnd)
127
- }
128
-
129
- compare(
130
- target ,
131
- targetStart ,
132
- targetEnd ,
133
- sourceStart ,
134
- sourceEnd ,
135
- ) {
136
- if (
137
- target === this &&
138
- targetStart === undefined &&
139
- targetEnd === undefined &&
140
- sourceStart === undefined &&
141
- sourceEnd === undefined
142
- ) {
143
- return 0
144
- }
145
-
146
- const sliceEnd = this.byteOffset + this.byteLength
147
-
148
- if (target instanceof Slice) {
149
- const targetSliceEnd = target.byteOffset + target.byteLength
150
- if (targetStart === undefined) {
151
- targetStart = target.byteOffset
152
- } else {
153
- if (targetStart < 0 || targetStart > target.byteLength || !Number.isInteger(targetStart)) {
154
- throw new RangeError(`Invalid targetStart: ${targetStart}`)
155
- }
156
- targetStart += target.byteOffset
157
- }
158
-
159
- if (targetEnd === undefined) {
160
- targetEnd = targetSliceEnd
161
- } else {
162
- targetEnd += target.byteOffset
163
- }
164
-
165
- if (targetEnd > targetSliceEnd) {
166
- targetEnd = targetSliceEnd
167
- }
168
- if (targetEnd < targetStart) {
169
- targetEnd = targetStart
170
- }
171
- target = target.buffer
172
- }
173
-
174
- if (sourceStart === undefined) {
175
- sourceStart = this.byteOffset
176
- } else {
177
- if (sourceStart < 0 || sourceStart > this.byteLength || !Number.isInteger(sourceStart)) {
178
- throw new RangeError(`Invalid sourceStart: ${sourceStart}`)
179
- }
180
- sourceStart += this.byteOffset
181
- }
182
-
183
- if (sourceEnd === undefined) {
184
- sourceEnd = sliceEnd
185
- } else {
186
- sourceEnd += this.byteOffset
187
- }
188
-
189
- if (sourceEnd > sliceEnd) {
190
- sourceEnd = sliceEnd
191
- }
192
- if (sourceEnd < sourceStart) {
193
- sourceEnd = sourceStart
194
- }
195
-
196
- return this.buffer.compare(target, targetStart, targetEnd, sourceStart, sourceEnd)
197
- }
198
-
199
- write(string , offset , length , encoding ) {
200
- const sliceEnd = this.byteOffset + this.byteLength
201
-
202
- if (offset === undefined) {
203
- offset = this.byteOffset
204
- } else {
205
- if (offset < 0 || offset > this.byteLength || !Number.isInteger(offset)) {
206
- throw new RangeError(`Invalid offset: ${offset}`)
207
- }
208
- offset += this.byteOffset
209
- }
210
-
211
- const available = sliceEnd - offset
212
- if (length === undefined) {
213
- length = available
214
- } else {
215
- if (length < 0 || !Number.isInteger(length)) {
216
- throw new RangeError(`Invalid length: ${length}`)
217
- }
218
- if (length > available) {
219
- length = available
220
- }
221
- }
222
-
223
- return this.buffer.write(string, offset, length, encoding)
224
- }
225
-
226
- set(source , offset ) {
227
- if (source == null) {
228
- return
229
- }
230
-
231
- if (offset === undefined) {
232
- offset = this.byteOffset
233
- } else {
234
- // Validate (not clamp): a negative offset would resolve to a position
235
- // before the slice and corrupt adjacent (pool) memory.
236
- if (offset < 0 || offset > this.byteLength || !Number.isInteger(offset)) {
237
- throw new RangeError(`Invalid offset: ${offset}`)
238
- }
239
- offset += this.byteOffset
240
- }
241
-
242
- const available = this.byteOffset + this.byteLength - offset
243
- if (available <= 0) {
244
- return
245
- }
246
-
247
- const end = source.byteLength < available ? source.byteLength : available
248
- source.copy(this.buffer, offset, 0, end)
249
- }
250
-
251
- at(index ) {
252
- if (!Number.isInteger(index) || index >= this.byteLength || index < -this.byteLength) {
253
- throw new RangeError(`Index out of range: ${index}`)
254
- }
255
- return index >= 0
256
- ? this.buffer[this.byteOffset + index]
257
- : this.buffer[this.byteOffset + this.byteLength + index]
258
- }
259
-
260
- test(expr
261
-
262
- ) {
263
- return expr.test(this.buffer, this.byteOffset, this.byteLength)
264
- }
265
-
266
- toString(encoding , start , end ) {
267
- const sliceEnd = this.byteOffset + this.byteLength
268
-
269
- if (start === undefined) {
270
- start = this.byteOffset
271
- } else {
272
- if (start < 0 || start > this.byteLength || !Number.isInteger(start)) {
273
- throw new RangeError(`Invalid start: ${start}`)
274
- }
275
- start += this.byteOffset
276
- }
277
-
278
- if (end === undefined) {
279
- end = sliceEnd
280
- } else {
281
- end += this.byteOffset
282
- }
283
-
284
- if (end > sliceEnd) {
285
- end = sliceEnd
286
- }
287
- if (end < start) {
288
- end = start
1
+ import util from 'node:util';
2
+ const EMPTY_BUF = Buffer.alloc(0);
3
+ export class Slice {
4
+ buffer = EMPTY_BUF;
5
+ byteOffset = 0;
6
+ byteLength = 0;
7
+ maxByteLength = 0;
8
+ static get EMPTY_BUF() {
9
+ return EMPTY_BUF;
10
+ }
11
+ static from(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
12
+ if (!(buffer instanceof Buffer)) {
13
+ throw new TypeError('buffer must be a Buffer');
14
+ }
15
+ if (byteOffset < 0 || !Number.isInteger(byteOffset)) {
16
+ throw new RangeError(`Invalid byteOffset: ${byteOffset}`);
17
+ }
18
+ if (byteLength < 0 || !Number.isInteger(byteLength)) {
19
+ throw new RangeError(`Invalid byteLength: ${byteLength}`);
20
+ }
21
+ if (byteOffset + byteLength > buffer.byteLength) {
22
+ throw new RangeError(`byteOffset + byteLength (${byteOffset + byteLength}) exceeds buffer size (${buffer.byteLength})`);
23
+ }
24
+ return new Slice(buffer, byteOffset, byteLength);
25
+ }
26
+ constructor(buffer = Slice.EMPTY_BUF, byteOffset = 0, byteLength = buffer.byteLength - byteOffset, maxByteLength = byteLength) {
27
+ this.buffer = buffer;
28
+ this.byteOffset = byteOffset;
29
+ this.byteLength = byteLength;
30
+ this.maxByteLength = maxByteLength;
31
+ }
32
+ reset() {
33
+ this.buffer = Slice.EMPTY_BUF;
34
+ this.byteOffset = 0;
35
+ this.byteLength = 0;
36
+ this.maxByteLength = 0;
37
+ }
38
+ get length() {
39
+ return this.byteLength;
40
+ }
41
+ copy(target, targetStart, sourceStart, sourceEnd) {
42
+ const sliceEnd = this.byteOffset + this.byteLength;
43
+ if (sourceStart === undefined) {
44
+ sourceStart = this.byteOffset;
45
+ }
46
+ else {
47
+ // Start offsets are validated (not clamped) so a negative offset can
48
+ // never resolve to a position before the slice and read adjacent
49
+ // (pool) memory.
50
+ if (sourceStart < 0 || sourceStart > this.byteLength || !Number.isInteger(sourceStart)) {
51
+ throw new RangeError(`Invalid sourceStart: ${sourceStart}`);
52
+ }
53
+ sourceStart += this.byteOffset;
54
+ }
55
+ if (sourceEnd === undefined) {
56
+ sourceEnd = sliceEnd;
57
+ }
58
+ else {
59
+ // Ends are clamped when out of range but must still be integers: a
60
+ // NaN/fractional end compares false against the clamps below and would
61
+ // poison the aliasing short-circuit's returned count. Omit the argument
62
+ // to mean "to the end of the slice".
63
+ if (!Number.isInteger(sourceEnd)) {
64
+ throw new RangeError(`Invalid sourceEnd: ${sourceEnd}`);
65
+ }
66
+ sourceEnd += this.byteOffset;
67
+ }
68
+ // Clamp the end against the logical slice length so copy() cannot read
69
+ // past the slice's own end and leak adjacent (pool) memory.
70
+ if (sourceEnd > sliceEnd) {
71
+ sourceEnd = sliceEnd;
72
+ }
73
+ if (sourceEnd < sourceStart) {
74
+ sourceEnd = sourceStart;
75
+ }
76
+ if (target instanceof Slice) {
77
+ const targetEnd = target.byteOffset + target.byteLength;
78
+ if (targetStart === undefined) {
79
+ targetStart = target.byteOffset;
80
+ }
81
+ else {
82
+ if (targetStart < 0 || targetStart > target.byteLength || !Number.isInteger(targetStart)) {
83
+ throw new RangeError(`Invalid targetStart: ${targetStart}`);
84
+ }
85
+ targetStart += target.byteOffset;
86
+ }
87
+ target = target.buffer;
88
+ if (sourceEnd - sourceStart > targetEnd - targetStart) {
89
+ sourceEnd = sourceStart + (targetEnd - targetStart);
90
+ }
91
+ }
92
+ if (sourceStart === targetStart &&
93
+ this.buffer.buffer === target.buffer &&
94
+ this.buffer.byteOffset === target.byteOffset) {
95
+ // The regions alias so the copy is a no-op, but the returned count must
96
+ // match what Buffer.copy would report: clamped to the target's remaining
97
+ // capacity. (For a Slice target, sourceEnd was already capacity-clamped
98
+ // above; this min is then a no-op.)
99
+ const available = target.byteLength - targetStart;
100
+ const count = sourceEnd - sourceStart;
101
+ return count > available ? (available > 0 ? available : 0) : count;
102
+ }
103
+ return this.buffer.copy(target, targetStart, sourceStart, sourceEnd);
104
+ }
105
+ compare(target, targetStart, targetEnd, sourceStart, sourceEnd) {
106
+ if (target === this &&
107
+ targetStart === undefined &&
108
+ targetEnd === undefined &&
109
+ sourceStart === undefined &&
110
+ sourceEnd === undefined) {
111
+ return 0;
112
+ }
113
+ const sliceEnd = this.byteOffset + this.byteLength;
114
+ if (target instanceof Slice) {
115
+ const targetSliceEnd = target.byteOffset + target.byteLength;
116
+ if (targetStart === undefined) {
117
+ targetStart = target.byteOffset;
118
+ }
119
+ else {
120
+ if (targetStart < 0 || targetStart > target.byteLength || !Number.isInteger(targetStart)) {
121
+ throw new RangeError(`Invalid targetStart: ${targetStart}`);
122
+ }
123
+ targetStart += target.byteOffset;
124
+ }
125
+ if (targetEnd === undefined) {
126
+ targetEnd = targetSliceEnd;
127
+ }
128
+ else {
129
+ // Validated here (not left to Buffer.compare) so the error names the
130
+ // slice-relative value the caller passed, not a byteOffset-shifted one.
131
+ if (!Number.isInteger(targetEnd)) {
132
+ throw new RangeError(`Invalid targetEnd: ${targetEnd}`);
133
+ }
134
+ targetEnd += target.byteOffset;
135
+ }
136
+ if (targetEnd > targetSliceEnd) {
137
+ targetEnd = targetSliceEnd;
138
+ }
139
+ if (targetEnd < targetStart) {
140
+ targetEnd = targetStart;
141
+ }
142
+ target = target.buffer;
143
+ }
144
+ if (sourceStart === undefined) {
145
+ sourceStart = this.byteOffset;
146
+ }
147
+ else {
148
+ if (sourceStart < 0 || sourceStart > this.byteLength || !Number.isInteger(sourceStart)) {
149
+ throw new RangeError(`Invalid sourceStart: ${sourceStart}`);
150
+ }
151
+ sourceStart += this.byteOffset;
152
+ }
153
+ if (sourceEnd === undefined) {
154
+ sourceEnd = sliceEnd;
155
+ }
156
+ else {
157
+ if (!Number.isInteger(sourceEnd)) {
158
+ throw new RangeError(`Invalid sourceEnd: ${sourceEnd}`);
159
+ }
160
+ sourceEnd += this.byteOffset;
161
+ }
162
+ if (sourceEnd > sliceEnd) {
163
+ sourceEnd = sliceEnd;
164
+ }
165
+ if (sourceEnd < sourceStart) {
166
+ sourceEnd = sourceStart;
167
+ }
168
+ return this.buffer.compare(target, targetStart, targetEnd, sourceStart, sourceEnd);
289
169
  }
290
-
291
- return this.buffer.toString(encoding, start, end)
292
- }
293
-
294
- toBuffer(start , end ) {
295
- const sliceEnd = this.byteOffset + this.byteLength
296
-
297
- if (start === undefined) {
298
- start = this.byteOffset
299
- } else {
300
- if (start < 0 || start > this.byteLength || !Number.isInteger(start)) {
301
- throw new RangeError(`Invalid start: ${start}`)
302
- }
303
- start += this.byteOffset
170
+ write(string, offset, length, encoding) {
171
+ const sliceEnd = this.byteOffset + this.byteLength;
172
+ if (offset === undefined) {
173
+ offset = this.byteOffset;
174
+ }
175
+ else {
176
+ if (offset < 0 || offset > this.byteLength || !Number.isInteger(offset)) {
177
+ throw new RangeError(`Invalid offset: ${offset}`);
178
+ }
179
+ offset += this.byteOffset;
180
+ }
181
+ const available = sliceEnd - offset;
182
+ if (length === undefined) {
183
+ length = available;
184
+ }
185
+ else {
186
+ if (length < 0 || !Number.isInteger(length)) {
187
+ throw new RangeError(`Invalid length: ${length}`);
188
+ }
189
+ if (length > available) {
190
+ length = available;
191
+ }
192
+ }
193
+ return this.buffer.write(string, offset, length, encoding);
304
194
  }
305
-
306
- if (end === undefined) {
307
- end = sliceEnd
308
- } else {
309
- end += this.byteOffset
195
+ set(source, offset) {
196
+ if (source == null) {
197
+ return;
198
+ }
199
+ if (offset === undefined) {
200
+ offset = this.byteOffset;
201
+ }
202
+ else {
203
+ // Validate (not clamp): a negative offset would resolve to a position
204
+ // before the slice and corrupt adjacent (pool) memory.
205
+ if (offset < 0 || offset > this.byteLength || !Number.isInteger(offset)) {
206
+ throw new RangeError(`Invalid offset: ${offset}`);
207
+ }
208
+ offset += this.byteOffset;
209
+ }
210
+ const available = this.byteOffset + this.byteLength - offset;
211
+ if (available <= 0) {
212
+ return;
213
+ }
214
+ const end = source.byteLength < available ? source.byteLength : available;
215
+ source.copy(this.buffer, offset, 0, end);
310
216
  }
311
-
312
- if (end > sliceEnd) {
313
- end = sliceEnd
217
+ at(index) {
218
+ if (!Number.isInteger(index) || index >= this.byteLength || index < -this.byteLength) {
219
+ throw new RangeError(`Index out of range: ${index}`);
220
+ }
221
+ return index >= 0
222
+ ? this.buffer[this.byteOffset + index]
223
+ : this.buffer[this.byteOffset + this.byteLength + index];
314
224
  }
315
- if (end < start) {
316
- end = start
225
+ test(expr) {
226
+ return expr.test(this.buffer, this.byteOffset, this.byteLength);
317
227
  }
318
-
319
- return start === 0 && end === this.buffer.byteLength
320
- ? this.buffer
321
- : this.buffer.subarray(start, end)
322
- }
323
-
324
- get [Symbol.toStringTag]() {
325
- return 'Slice'
326
- }
327
-
328
- [util.inspect.custom]() {
329
- const MAX_BYTES = 32
330
- const len = this.byteLength
331
-
332
- // Never read past the underlying buffer. A malformed slice (byteOffset /
333
- // byteLength extending beyond the buffer) is exactly the state a developer
334
- // inspects while debugging pool corruption — inspect must not throw on it.
335
- const available = this.buffer.byteLength - this.byteOffset
336
- const safeLen = available > 0 ? (len < available ? len : available) : 0
337
- const shown = safeLen < MAX_BYTES ? safeLen : MAX_BYTES
338
-
339
- let hex = ''
340
- for (let i = 0; i < shown; i++) {
341
- if (i !== 0) {
342
- hex += ' '
343
- }
344
- hex += this.buffer[this.byteOffset + i].toString(16).padStart(2, '0')
228
+ toString(encoding, start, end) {
229
+ const sliceEnd = this.byteOffset + this.byteLength;
230
+ if (start === undefined) {
231
+ start = this.byteOffset;
232
+ }
233
+ else {
234
+ if (start < 0 || start > this.byteLength || !Number.isInteger(start)) {
235
+ throw new RangeError(`Invalid start: ${start}`);
236
+ }
237
+ start += this.byteOffset;
238
+ }
239
+ if (end === undefined) {
240
+ end = sliceEnd;
241
+ }
242
+ else {
243
+ if (!Number.isInteger(end)) {
244
+ throw new RangeError(`Invalid end: ${end}`);
245
+ }
246
+ end += this.byteOffset;
247
+ }
248
+ if (end > sliceEnd) {
249
+ end = sliceEnd;
250
+ }
251
+ if (end < start) {
252
+ end = start;
253
+ }
254
+ return this.buffer.toString(encoding, start, end);
345
255
  }
346
- if (shown < len) {
347
- hex += ` ... (${len - shown} more)`
256
+ toBuffer(start, end) {
257
+ const sliceEnd = this.byteOffset + this.byteLength;
258
+ if (start === undefined) {
259
+ start = this.byteOffset;
260
+ }
261
+ else {
262
+ if (start < 0 || start > this.byteLength || !Number.isInteger(start)) {
263
+ throw new RangeError(`Invalid start: ${start}`);
264
+ }
265
+ start += this.byteOffset;
266
+ }
267
+ if (end === undefined) {
268
+ end = sliceEnd;
269
+ }
270
+ else {
271
+ if (!Number.isInteger(end)) {
272
+ throw new RangeError(`Invalid end: ${end}`);
273
+ }
274
+ end += this.byteOffset;
275
+ }
276
+ if (end > sliceEnd) {
277
+ end = sliceEnd;
278
+ }
279
+ if (end < start) {
280
+ end = start;
281
+ }
282
+ return start === 0 && end === this.buffer.byteLength
283
+ ? this.buffer
284
+ : this.buffer.subarray(start, end);
285
+ }
286
+ get [Symbol.toStringTag]() {
287
+ return 'Slice';
288
+ }
289
+ [util.inspect.custom]() {
290
+ const MAX_BYTES = 32;
291
+ const len = this.byteLength;
292
+ // A malformed slice (a NaN/non-finite/fractional/negative/out-of-bounds
293
+ // byteOffset or byteLength) is exactly the state a developer inspects while
294
+ // debugging pool corruption — inspect must never throw on it. Coerce
295
+ // byteOffset to a safe integer index in [0, buffer.byteLength]: the
296
+ // `>= 0` test is false for NaN and -Infinity (→ 0), Math.floor truncates a
297
+ // fractional offset, and Math.min caps Infinity/oversize at the buffer end
298
+ // (available 0). Every buffer access below is then guaranteed in-bounds and
299
+ // begin + shown <= buffer.byteLength holds.
300
+ const bufferLength = this.buffer.byteLength;
301
+ const begin = this.byteOffset >= 0 ? Math.min(Math.floor(this.byteOffset), bufferLength) : 0;
302
+ const cap = bufferLength - begin;
303
+ const safeLen = len > 0 ? (len < cap ? len : cap) : 0;
304
+ const shown = safeLen < MAX_BYTES ? safeLen : MAX_BYTES;
305
+ let hex = '';
306
+ for (let i = 0; i < shown; i++) {
307
+ if (i !== 0) {
308
+ hex += ' ';
309
+ }
310
+ hex += this.buffer[begin + i].toString(16).padStart(2, '0');
311
+ }
312
+ if (shown < len) {
313
+ hex += ` ... (${len - shown} more)`;
314
+ }
315
+ const str = this.buffer.toString('utf8', begin, begin + shown);
316
+ const truncated = shown < len ? '…' : '';
317
+ return `Slice(${len}): "${str}${truncated}" <${hex}>`;
348
318
  }
349
-
350
- const str = this.buffer.toString('utf8', this.byteOffset, this.byteOffset + shown)
351
- const truncated = shown < len ? '…' : ''
352
-
353
- return `Slice(${len}): "${str}${truncated}" <${hex}>`
354
- }
355
319
  }
356
-
357
320
  export class PoolAllocator {
358
- #size = 0
359
- #padding = 0
360
-
361
- #poolsBucket = []
362
- #poolsBucketUsed = []
363
- #poolBuffer
364
- #poolOffset = 0
365
- #poolSize = 0
366
- #poolCount = 0
367
-
368
- constructor(
369
- poolTotalOrBuffer = 128 *
370
- 1024 *
371
- 1024,
372
- ) {
373
- if (typeof poolTotalOrBuffer === 'number') {
374
- if (!Number.isInteger(poolTotalOrBuffer) || poolTotalOrBuffer < 0) {
375
- throw new RangeError(`Invalid pool size: ${poolTotalOrBuffer}`)
376
- }
377
- this.#poolBuffer = Buffer.allocUnsafeSlow(poolTotalOrBuffer)
378
- } else if (poolTotalOrBuffer instanceof Buffer) {
379
- this.#poolBuffer = poolTotalOrBuffer
380
- } else if (ArrayBuffer.isView(poolTotalOrBuffer)) {
381
- this.#poolBuffer = Buffer.from(
382
- poolTotalOrBuffer.buffer,
383
- poolTotalOrBuffer.byteOffset,
384
- poolTotalOrBuffer.byteLength,
385
- )
386
- } else if (
387
- poolTotalOrBuffer instanceof ArrayBuffer ||
388
- poolTotalOrBuffer instanceof SharedArrayBuffer
389
- ) {
390
- this.#poolBuffer = Buffer.from(poolTotalOrBuffer)
391
- } else {
392
- throw new TypeError(
393
- 'Invalid poolTotalOrBuffer: must be a Buffer, ArrayBufferView, ArrayBuffer, SharedArrayBuffer, or number',
394
- )
395
- }
396
-
397
- for (let n = 0; 2 ** n <= 256 * 1024; n++) {
398
- this.#poolsBucket.push([])
399
- this.#poolsBucketUsed.push(0)
400
- }
401
- }
402
-
403
- get size() {
404
- return this.#size
405
- }
406
-
407
- isFromPool(slice ) {
408
- return slice != null && slice.buffer === this.#poolBuffer
409
- }
410
-
411
-
412
-
413
- realloc(slice , byteLength ) {
414
- if (typeof slice === 'number') {
415
- byteLength = slice
416
- slice = new Slice()
417
- }
418
-
419
- if (byteLength == null || !Number.isInteger(byteLength) || byteLength < 0) {
420
- throw new TypeError(`Invalid byteLength: ${byteLength}`)
421
- }
422
-
423
- // 2^30 is the largest power-of-two that fits a 32-bit signed int; a
424
- // larger request overflows `1 << dstIdx` to a negative bucket size.
425
- if (byteLength > 1 << 30) {
426
- throw new RangeError(`byteLength too large: ${byteLength} (max ${1 << 30})`)
427
- }
428
-
429
- if (slice.byteLength === byteLength) {
430
- return slice
431
- }
432
-
433
- // Ceil to nearest power of two.
434
- const dstIdx = byteLength <= 8 ? 3 : 32 - Math.clz32(byteLength - 1)
435
-
436
- if (slice.buffer === this.#poolBuffer) {
437
- const srcIdx = 32 - Math.clz32(slice.maxByteLength - 1)
438
-
439
- if (slice.maxByteLength !== 1 << srcIdx) {
440
- throw new Error(`Invalid pool state`)
441
- }
442
-
443
- this.#size -= slice.maxByteLength
444
- this.#padding -= slice.maxByteLength - slice.byteLength
445
-
446
- if (srcIdx === dstIdx) {
447
- slice.byteLength = byteLength
448
- this.#size += slice.maxByteLength
449
- this.#padding += slice.maxByteLength - slice.byteLength
450
- return slice
451
- }
452
-
453
- this.#poolsBucket[srcIdx].push(slice.byteOffset)
454
- this.#poolsBucketUsed[srcIdx] -= 1
455
- this.#poolSize -= slice.maxByteLength
321
+ #size = 0;
322
+ #padding = 0;
323
+ #poolsBucket = [];
324
+ #poolsBucketUsed = [];
325
+ #poolBuffer;
326
+ #poolOffset = 0;
327
+ #poolSize = 0;
328
+ #poolCount = 0;
329
+ constructor(poolTotalOrBuffer = 128 *
330
+ 1024 *
331
+ 1024) {
332
+ if (typeof poolTotalOrBuffer === 'number') {
333
+ // Infinity means "unbounded": no pre-allocated pool, every allocation
334
+ // falls back to a standalone Buffer and size stays 0 — the 1.0.x
335
+ // contract that consumers (e.g. SubscriptionRegistry maxSize: Infinity)
336
+ // rely on. NaN and negative/fractional sizes are still rejected.
337
+ if (poolTotalOrBuffer === Infinity) {
338
+ poolTotalOrBuffer = 0;
339
+ }
340
+ if (!Number.isInteger(poolTotalOrBuffer) || poolTotalOrBuffer < 0) {
341
+ throw new RangeError(`Invalid pool size: ${poolTotalOrBuffer}`);
342
+ }
343
+ this.#poolBuffer = Buffer.allocUnsafeSlow(poolTotalOrBuffer);
344
+ }
345
+ else if (poolTotalOrBuffer instanceof Buffer) {
346
+ this.#poolBuffer = poolTotalOrBuffer;
347
+ }
348
+ else if (ArrayBuffer.isView(poolTotalOrBuffer)) {
349
+ this.#poolBuffer = Buffer.from(poolTotalOrBuffer.buffer, poolTotalOrBuffer.byteOffset, poolTotalOrBuffer.byteLength);
350
+ }
351
+ else if (poolTotalOrBuffer instanceof ArrayBuffer ||
352
+ poolTotalOrBuffer instanceof SharedArrayBuffer) {
353
+ this.#poolBuffer = Buffer.from(poolTotalOrBuffer);
354
+ }
355
+ else {
356
+ throw new TypeError('Invalid poolTotalOrBuffer: must be a Buffer, ArrayBufferView, ArrayBuffer, SharedArrayBuffer, or number');
357
+ }
358
+ for (let n = 0; 2 ** n <= 256 * 1024; n++) {
359
+ this.#poolsBucket.push([]);
360
+ this.#poolsBucketUsed.push(0);
361
+ }
456
362
  }
457
-
458
- slice.reset()
459
-
460
- if (byteLength === 0) {
461
- return slice
363
+ get size() {
364
+ return this.#size;
462
365
  }
463
-
464
- const maxByteLength = 1 << dstIdx
465
-
466
- if (dstIdx < this.#poolsBucket.length && this.#poolsBucket[dstIdx].length) {
467
- slice.buffer = this.#poolBuffer
468
- slice.byteOffset = this.#poolsBucket[dstIdx].pop()
469
- slice.byteLength = byteLength
470
- slice.maxByteLength = maxByteLength
471
-
472
- this.#poolsBucketUsed[dstIdx] += 1
473
- this.#poolSize += maxByteLength
474
- this.#size += maxByteLength
475
- this.#padding += maxByteLength - byteLength
476
- } else if (
477
- dstIdx < this.#poolsBucket.length &&
478
- this.#poolOffset + maxByteLength <= this.#poolBuffer.byteLength
479
- ) {
480
- slice.buffer = this.#poolBuffer
481
- slice.byteOffset = this.#poolOffset
482
- slice.byteLength = byteLength
483
- slice.maxByteLength = maxByteLength
484
-
485
- this.#poolOffset += maxByteLength
486
- this.#poolCount += 1
487
- this.#poolsBucketUsed[dstIdx] += 1
488
- this.#poolSize += maxByteLength
489
- this.#size += maxByteLength
490
- this.#padding += maxByteLength - byteLength
491
- } else {
492
- slice.buffer = Buffer.allocUnsafeSlow(byteLength)
493
- slice.byteOffset = 0
494
- slice.byteLength = byteLength
495
- slice.maxByteLength = byteLength
366
+ isFromPool(slice) {
367
+ return slice != null && slice.buffer === this.#poolBuffer;
496
368
  }
497
-
498
- return slice
499
- }
500
-
501
- get stats() {
502
- return {
503
- size: this.#size,
504
- padding: this.#padding,
505
- ratio: this.#size > this.#padding ? this.#size / (this.#size - this.#padding) : 1,
506
- poolTotal: this.#poolBuffer.byteLength,
507
- poolUsed: this.#poolOffset,
508
- poolSize: this.#poolSize,
509
- poolCount: this.#poolCount,
510
- buckets: this.#poolsBucket.map((pool, i) => ({
511
- free: pool.length,
512
- used: this.#poolsBucketUsed[i],
513
- size: pool.length + this.#poolsBucketUsed[i],
514
- })),
369
+ realloc(slice, byteLength) {
370
+ if (typeof slice === 'number') {
371
+ byteLength = slice;
372
+ slice = new Slice();
373
+ }
374
+ if (byteLength == null || !Number.isInteger(byteLength) || byteLength < 0) {
375
+ throw new TypeError(`Invalid byteLength: ${byteLength}`);
376
+ }
377
+ // 2^30 is the largest power-of-two that fits a 32-bit signed int; a
378
+ // larger request overflows `1 << dstIdx` to a negative bucket size.
379
+ if (byteLength > 1 << 30) {
380
+ throw new RangeError(`byteLength too large: ${byteLength} (max ${1 << 30})`);
381
+ }
382
+ if (slice.byteLength === byteLength) {
383
+ return slice;
384
+ }
385
+ // Ceil to nearest power of two — the destination bucket and its byte size.
386
+ const dstIdx = byteLength <= 8 ? 3 : 32 - Math.clz32(byteLength - 1);
387
+ const maxByteLength = 1 << dstIdx;
388
+ if (slice.buffer === this.#poolBuffer) {
389
+ const srcMaxByteLength = slice.maxByteLength;
390
+ // Same-bucket resize is the hot path: just update the logical length and
391
+ // adjust padding by the delta — no bucket bookkeeping, no second clz32,
392
+ // no net change to #size. A free (byteLength === 0) is deliberately
393
+ // excluded so it always falls through to the free-list path below:
394
+ // byteLength 0 maps to dstIdx 3 / maxByteLength 8, which would otherwise
395
+ // match a live bucket-3 slot here and "resize" it to 0 — leaking the slot
396
+ // (never returned to the free list, still counted in #size/#poolSize).
397
+ if (byteLength !== 0 && srcMaxByteLength === maxByteLength) {
398
+ this.#padding += slice.byteLength - byteLength;
399
+ slice.byteLength = byteLength;
400
+ return slice;
401
+ }
402
+ const srcIdx = 32 - Math.clz32(srcMaxByteLength - 1);
403
+ // Corruption tripwire for a foreign/double-freed slice. maxByteLength must
404
+ // be a power of two that maps to a real pool bucket — index in
405
+ // [3, poolsBucket.length). The pool never hands out a slot below bucket 3
406
+ // (8 bytes), so a smaller power of two (1/2/4 → srcIdx 0/1/2) is just as
407
+ // corrupt as an oversized one (e.g. 2^20 → srcIdx 20, out of range):
408
+ // `=== 1 << srcIdx` alone passes both, after which the bucket bookkeeping
409
+ // below would drive an always-empty bucket's `used` count negative (or
410
+ // index a non-existent bucket) and drift #size/#poolSize. A used count
411
+ // already at 0 means this slot was never handed out by this allocator
412
+ // (double-free through an aliasing Slice, or a slice from another
413
+ // allocator over the same backing buffer) — freeing it would push a
414
+ // duplicate/foreign offset onto the free list and later hand out two
415
+ // overlapping slices.
416
+ if (srcMaxByteLength !== 1 << srcIdx ||
417
+ srcIdx < 3 ||
418
+ srcIdx >= this.#poolsBucket.length ||
419
+ this.#poolsBucketUsed[srcIdx] <= 0) {
420
+ throw new Error(`Invalid pool state`);
421
+ }
422
+ this.#size -= srcMaxByteLength;
423
+ this.#padding -= srcMaxByteLength - slice.byteLength;
424
+ this.#poolsBucket[srcIdx].push(slice.byteOffset);
425
+ this.#poolsBucketUsed[srcIdx] -= 1;
426
+ this.#poolSize -= srcMaxByteLength;
427
+ }
428
+ else if (dstIdx >= this.#poolsBucket.length &&
429
+ byteLength <= slice.maxByteLength &&
430
+ slice.maxByteLength <= maxByteLength &&
431
+ Number.isInteger(slice.byteOffset) &&
432
+ slice.byteOffset >= 0 &&
433
+ slice.maxByteLength <= slice.buffer.byteLength - slice.byteOffset) {
434
+ // In-place resize of a heap (non-pool) slice. The request is above the
435
+ // top pool bucket (so it can never rejoin the pool) and fits the slice's
436
+ // existing capacity, so reallocating ~300KB+ of backing store for a size
437
+ // change would be pure waste. Retained capacity is bounded by the
438
+ // power-of-two ceiling of the request (< 2x), so a shrink from a much
439
+ // larger allocation still releases its memory. The byteOffset/window
440
+ // checks keep a hand-constructed slice's resize inside its real buffer
441
+ // (a negative or fractional byteOffset would inflate the window
442
+ // arithmetic) — but they cannot detect a foreign buffer that aliases
443
+ // other memory; passing such a slice is documented misuse. Contents are
444
+ // incidentally retained but remain undefined per realloc's malloc
445
+ // semantics.
446
+ slice.byteLength = byteLength;
447
+ return slice;
448
+ }
449
+ if (byteLength === 0) {
450
+ slice.reset();
451
+ return slice;
452
+ }
453
+ if (dstIdx < this.#poolsBucket.length && this.#poolsBucket[dstIdx].length) {
454
+ slice.buffer = this.#poolBuffer;
455
+ slice.byteOffset = this.#poolsBucket[dstIdx].pop();
456
+ slice.byteLength = byteLength;
457
+ slice.maxByteLength = maxByteLength;
458
+ this.#poolsBucketUsed[dstIdx] += 1;
459
+ this.#poolSize += maxByteLength;
460
+ this.#size += maxByteLength;
461
+ this.#padding += maxByteLength - byteLength;
462
+ }
463
+ else if (dstIdx < this.#poolsBucket.length &&
464
+ this.#poolOffset + maxByteLength <= this.#poolBuffer.byteLength) {
465
+ slice.buffer = this.#poolBuffer;
466
+ slice.byteOffset = this.#poolOffset;
467
+ slice.byteLength = byteLength;
468
+ slice.maxByteLength = maxByteLength;
469
+ this.#poolOffset += maxByteLength;
470
+ this.#poolCount += 1;
471
+ this.#poolsBucketUsed[dstIdx] += 1;
472
+ this.#poolSize += maxByteLength;
473
+ this.#size += maxByteLength;
474
+ this.#padding += maxByteLength - byteLength;
475
+ }
476
+ else {
477
+ slice.buffer = Buffer.allocUnsafeSlow(byteLength);
478
+ slice.byteOffset = 0;
479
+ slice.byteLength = byteLength;
480
+ slice.maxByteLength = byteLength;
481
+ }
482
+ return slice;
483
+ }
484
+ get stats() {
485
+ return {
486
+ size: this.#size,
487
+ padding: this.#padding,
488
+ ratio: this.#size > this.#padding ? this.#size / (this.#size - this.#padding) : 1,
489
+ poolTotal: this.#poolBuffer.byteLength,
490
+ poolUsed: this.#poolOffset,
491
+ poolSize: this.#poolSize,
492
+ poolCount: this.#poolCount,
493
+ buckets: this.#poolsBucket.map((pool, i) => ({
494
+ free: pool.length,
495
+ used: this.#poolsBucketUsed[i],
496
+ size: pool.length + this.#poolsBucketUsed[i],
497
+ })),
498
+ };
515
499
  }
516
- }
517
500
  }
501
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/slice",
3
- "version": "1.1.10",
3
+ "version": "1.1.12",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -14,7 +14,7 @@
14
14
  "access": "public"
15
15
  },
16
16
  "scripts": {
17
- "build": "rimraf lib && tsc -p tsconfig.build.json && amaroc ./src/index.ts && mv src/index.js lib/",
17
+ "build": "rimraf lib && tsc -p tsconfig.build.json",
18
18
  "prepublishOnly": "yarn build",
19
19
  "typecheck": "tsc --noEmit",
20
20
  "test": "yarn build && node --test",
@@ -24,11 +24,10 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/node": "^25.5.0",
27
- "amaroc": "^1.0.1",
28
27
  "oxlint-tsgolint": "^0.17.0",
29
28
  "rimraf": "^6.1.3",
30
29
  "tsd": "^0.33.0",
31
30
  "typescript": "^5.9.3"
32
31
  },
33
- "gitHead": "7c9c7457c885c644c7a1e70ef894d4727ce240d6"
32
+ "gitHead": "c9f2526dc870597de119b8ec5083f97901d4a2e2"
34
33
  }