@nxtedition/slice 1.1.9 → 1.1.11
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 +42 -14
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +432 -457
- package/lib/index.js.map +1 -0
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Node.js `Buffer.subarray()` is slow. Every call creates a new `Buffer` object
|
|
|
10
10
|
|
|
11
11
|
`Slice` avoids this entirely. It is a plain JavaScript object with `buffer`, `byteOffset`, and `byteLength` fields. Creating a slice is just setting three properties — no typed array wrapper creation, no GC pressure from short-lived `Buffer` objects. Operations like `toString`, `copy`, and `compare` delegate directly to the underlying buffer with the correct offsets.
|
|
12
12
|
|
|
13
|
-
`PoolAllocator` takes this further. Like Node's internal pool, it has management overhead — but
|
|
13
|
+
`PoolAllocator` takes this further. Like Node's internal pool, it has management overhead — but for in-pool sizes it never allocates new backing stores (only allocations larger than the 256 KB top bucket, or made once the contiguous pool is exhausted, fall back to a standalone `Buffer`), and because `Slice` is a plain object rather than a typed array, resizing or freeing a slice doesn't produce garbage for V8 to collect. It pre-allocates a large contiguous buffer and hands out regions using power-of-2 bucketing. When a slice is freed, its slot is recycled. When a slice is resized within the same bucket, no data moves at all — just a field update. This gives you `malloc`/`realloc`/`free` semantics with near-zero overhead per operation. The trade-off is upfront memory allocation and internal fragmentation from power-of-2 rounding — a 10-byte allocation uses a 16-byte slot. Buckets are also independent: a freed 16-byte slot cannot satisfy a 32-byte request, so the pool can become fragmented if allocation sizes are uneven. Use `stats` to monitor pool utilization and tune the pool size for your workload.
|
|
14
14
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
@@ -89,28 +89,43 @@ A lightweight view over a `Buffer` with explicit offset and length tracking.
|
|
|
89
89
|
|
|
90
90
|
#### `new Slice(buffer?: Buffer, byteOffset?: number, byteLength?: number, maxByteLength?: number)`
|
|
91
91
|
|
|
92
|
-
Creates a new slice. All parameters are optional — defaults to an empty slice.
|
|
92
|
+
Creates a new slice. All parameters are optional — defaults to an empty slice. The constructor does **no** validation; pass only consistent values, or use `Slice.from` for a checked construction.
|
|
93
|
+
|
|
94
|
+
#### `Slice.from(buffer: Buffer, byteOffset?: number, byteLength?: number): Slice`
|
|
95
|
+
|
|
96
|
+
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
97
|
|
|
94
98
|
#### Properties
|
|
95
99
|
|
|
96
100
|
- `buffer: Buffer` — The underlying `Buffer`
|
|
97
101
|
- `byteOffset: number` — Start offset into the buffer
|
|
98
102
|
- `byteLength: number` — Current length in bytes
|
|
99
|
-
- `maxByteLength: number` —
|
|
103
|
+
- `maxByteLength: number` — For a pool-allocated slice, the power-of-2 bucket capacity (always `>= byteLength`). For a manually-constructed slice it defaults to `byteLength` and is purely informational: no method bounds writes against it — reads and writes are validated/clamped against `byteLength`.
|
|
100
104
|
- `length: number` — Alias for `byteLength`
|
|
101
105
|
|
|
102
106
|
#### Methods
|
|
103
107
|
|
|
104
|
-
- `reset(): void` — Clear the slice back to empty state. **Note:** this does not return the slot to the `PoolAllocator
|
|
105
|
-
- `copy(target:
|
|
106
|
-
- `compare(target:
|
|
108
|
+
- `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.
|
|
109
|
+
- `copy(target: Uint8Array | Slice, targetStart?: number, sourceStart?: number, sourceEnd?: number): number` — Copy data to a `Uint8Array`/`Buffer` or `Slice`. Returns bytes copied.
|
|
110
|
+
- `compare(target: Uint8Array | Slice, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): -1 | 0 | 1` — Compare with a `Uint8Array`/`Buffer` or `Slice`
|
|
107
111
|
- `write(string: string, offset?: number, length?: number, encoding?: BufferEncoding): number` — Write a string into the slice. Returns bytes written.
|
|
108
|
-
- `set(source: Buffer | Slice | null | undefined, offset?: number): void` — Copy from a `Buffer` or `Slice` into this slice
|
|
109
|
-
- `at(index: number): number` — Read byte at index (supports negative indexing)
|
|
112
|
+
- `set(source: Buffer | Slice | null | undefined, offset?: number): void` — Copy from a `Buffer` or `Slice` into this slice. (A plain `Uint8Array` source is not accepted — it has no `copy` method.)
|
|
113
|
+
- `at(index: number): number` — Read byte at integer index (supports negative indexing)
|
|
110
114
|
- `test(expr: { test(buffer: Buffer, byteOffset: number, byteLength: number): boolean }): boolean` — Test the slice against an expression object
|
|
111
115
|
- `toString(encoding?: BufferEncoding, start?: number, end?: number): string` — Convert to string
|
|
112
116
|
- `toBuffer(start?: number, end?: number): Buffer` — Return a `Buffer` view
|
|
113
117
|
|
|
118
|
+
#### Validation & bounds
|
|
119
|
+
|
|
120
|
+
All offsets are **relative to the slice** (i.e. `0` is `byteOffset`). For a `Slice` target, target offsets are relative to that slice; for a raw `Buffer`/`Uint8Array` target they are absolute (passed straight through to the underlying `Buffer` method).
|
|
121
|
+
|
|
122
|
+
The rule is consistent across the API:
|
|
123
|
+
|
|
124
|
+
- **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.
|
|
125
|
+
- **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.
|
|
126
|
+
- **`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).
|
|
127
|
+
- 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.
|
|
128
|
+
|
|
114
129
|
#### Static
|
|
115
130
|
|
|
116
131
|
- `Slice.EMPTY_BUF: Buffer` — Shared empty buffer singleton
|
|
@@ -119,19 +134,32 @@ Creates a new slice. All parameters are optional — defaults to an empty slice.
|
|
|
119
134
|
|
|
120
135
|
Pre-allocates a contiguous memory pool and manages slices using power-of-2 bucketing.
|
|
121
136
|
|
|
122
|
-
#### `new PoolAllocator(
|
|
137
|
+
#### `new PoolAllocator(poolTotalOrBuffer?: number | Buffer | ArrayBufferView | ArrayBuffer | SharedArrayBuffer)`
|
|
123
138
|
|
|
124
|
-
Creates a pool allocator.
|
|
139
|
+
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.
|
|
140
|
+
|
|
141
|
+
> **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.
|
|
125
142
|
|
|
126
143
|
#### Methods
|
|
127
144
|
|
|
128
|
-
- `realloc(
|
|
129
|
-
- `
|
|
145
|
+
- `realloc(byteLength: number): Slice` — Allocate a fresh slice.
|
|
146
|
+
- `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 pool slot through two aliasing `Slice` objects, corrupts the allocator's 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.)
|
|
147
|
+
- `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.
|
|
148
|
+
|
|
149
|
+
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`.
|
|
130
150
|
|
|
131
151
|
#### Properties
|
|
132
152
|
|
|
133
|
-
- `size: number` — Total
|
|
134
|
-
- `stats
|
|
153
|
+
- `size: number` — Total reserved bytes of all active **pool** allocations (sum of bucket sizes; equals `stats.poolSize`).
|
|
154
|
+
- `stats` — Detailed allocation statistics:
|
|
155
|
+
- `size` — same as the `size` getter (active pool bytes, including power-of-2 padding).
|
|
156
|
+
- `padding` — bytes lost to power-of-2 rounding across active pool slices.
|
|
157
|
+
- `ratio` — `size / (size - padding)`; `1` when there is no padding.
|
|
158
|
+
- `poolTotal` — capacity of the backing buffer in bytes.
|
|
159
|
+
- `poolUsed` — bump-pointer high-water mark; monotonic, never decreases.
|
|
160
|
+
- `poolSize` — active pool bytes (same as `size`).
|
|
161
|
+
- `poolCount` — number of distinct slots ever bump-allocated (monotonic high-water count, not a live count).
|
|
162
|
+
- `buckets` — per power-of-2 bucket: `{ free, used, size }`.
|
|
135
163
|
|
|
136
164
|
## License
|
|
137
165
|
|
package/lib/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type SliceLike = {
|
|
|
4
4
|
byteOffset: number;
|
|
5
5
|
byteLength: number;
|
|
6
6
|
};
|
|
7
|
-
export declare class Slice {
|
|
7
|
+
export declare class Slice implements SliceLike {
|
|
8
8
|
buffer: Buffer;
|
|
9
9
|
byteOffset: number;
|
|
10
10
|
byteLength: number;
|
|
@@ -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,SAAoB,EAC9B,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;IA0DT,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;IAgEb,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;IA4BzE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM;IA8B9C,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;IAgCR,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;IAuGhD,IAAI,KAAK;;;;;;;;;;;;;MAeR;CACF"}
|
package/lib/index.js
CHANGED
|
@@ -1,463 +1,438 @@
|
|
|
1
|
-
import util from 'node:util'
|
|
2
|
-
|
|
3
|
-
const EMPTY_BUF = Buffer.alloc(0)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import util from 'node:util';
|
|
2
|
+
const EMPTY_BUF = Buffer.alloc(0);
|
|
11
3
|
export class Slice {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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, 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
|
+
sourceEnd += this.byteOffset;
|
|
60
|
+
}
|
|
61
|
+
// Clamp the end against the logical slice length so copy() cannot read
|
|
62
|
+
// past the slice's own end and leak adjacent (pool) memory.
|
|
63
|
+
if (sourceEnd > sliceEnd) {
|
|
64
|
+
sourceEnd = sliceEnd;
|
|
65
|
+
}
|
|
66
|
+
if (sourceEnd < sourceStart) {
|
|
67
|
+
sourceEnd = sourceStart;
|
|
68
|
+
}
|
|
69
|
+
if (target instanceof Slice) {
|
|
70
|
+
const targetEnd = target.byteOffset + target.byteLength;
|
|
71
|
+
if (targetStart === undefined) {
|
|
72
|
+
targetStart = target.byteOffset;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
if (targetStart < 0 || targetStart > target.byteLength || !Number.isInteger(targetStart)) {
|
|
76
|
+
throw new RangeError(`Invalid targetStart: ${targetStart}`);
|
|
77
|
+
}
|
|
78
|
+
targetStart += target.byteOffset;
|
|
79
|
+
}
|
|
80
|
+
target = target.buffer;
|
|
81
|
+
if (sourceEnd - sourceStart > targetEnd - targetStart) {
|
|
82
|
+
sourceEnd = sourceStart + (targetEnd - targetStart);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (sourceStart === targetStart &&
|
|
86
|
+
this.buffer.buffer === target.buffer &&
|
|
87
|
+
this.buffer.byteOffset === target.byteOffset) {
|
|
88
|
+
return sourceEnd - sourceStart;
|
|
89
|
+
}
|
|
90
|
+
return this.buffer.copy(target, targetStart, sourceStart, sourceEnd);
|
|
91
|
+
}
|
|
92
|
+
compare(target, targetStart, targetEnd, sourceStart, sourceEnd) {
|
|
93
|
+
if (target === this &&
|
|
94
|
+
targetStart === undefined &&
|
|
95
|
+
targetEnd === undefined &&
|
|
96
|
+
sourceStart === undefined &&
|
|
97
|
+
sourceEnd === undefined) {
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
const sliceEnd = this.byteOffset + this.byteLength;
|
|
101
|
+
if (target instanceof Slice) {
|
|
102
|
+
const targetSliceEnd = target.byteOffset + target.byteLength;
|
|
103
|
+
if (targetStart === undefined) {
|
|
104
|
+
targetStart = target.byteOffset;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
if (targetStart < 0 || targetStart > target.byteLength || !Number.isInteger(targetStart)) {
|
|
108
|
+
throw new RangeError(`Invalid targetStart: ${targetStart}`);
|
|
109
|
+
}
|
|
110
|
+
targetStart += target.byteOffset;
|
|
111
|
+
}
|
|
112
|
+
if (targetEnd === undefined) {
|
|
113
|
+
targetEnd = targetSliceEnd;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
targetEnd += target.byteOffset;
|
|
117
|
+
}
|
|
118
|
+
if (targetEnd > targetSliceEnd) {
|
|
119
|
+
targetEnd = targetSliceEnd;
|
|
120
|
+
}
|
|
121
|
+
if (targetEnd < targetStart) {
|
|
122
|
+
targetEnd = targetStart;
|
|
123
|
+
}
|
|
124
|
+
target = target.buffer;
|
|
125
|
+
}
|
|
126
|
+
if (sourceStart === undefined) {
|
|
127
|
+
sourceStart = this.byteOffset;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
if (sourceStart < 0 || sourceStart > this.byteLength || !Number.isInteger(sourceStart)) {
|
|
131
|
+
throw new RangeError(`Invalid sourceStart: ${sourceStart}`);
|
|
132
|
+
}
|
|
133
|
+
sourceStart += this.byteOffset;
|
|
134
|
+
}
|
|
135
|
+
if (sourceEnd === undefined) {
|
|
136
|
+
sourceEnd = sliceEnd;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
sourceEnd += this.byteOffset;
|
|
140
|
+
}
|
|
141
|
+
if (sourceEnd > sliceEnd) {
|
|
142
|
+
sourceEnd = sliceEnd;
|
|
143
|
+
}
|
|
144
|
+
if (sourceEnd < sourceStart) {
|
|
145
|
+
sourceEnd = sourceStart;
|
|
146
|
+
}
|
|
147
|
+
return this.buffer.compare(target, targetStart, targetEnd, sourceStart, sourceEnd);
|
|
148
|
+
}
|
|
149
|
+
write(string, offset, length, encoding) {
|
|
150
|
+
const sliceEnd = this.byteOffset + this.byteLength;
|
|
151
|
+
if (offset === undefined) {
|
|
152
|
+
offset = this.byteOffset;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
if (offset < 0 || offset > this.byteLength || !Number.isInteger(offset)) {
|
|
156
|
+
throw new RangeError(`Invalid offset: ${offset}`);
|
|
157
|
+
}
|
|
158
|
+
offset += this.byteOffset;
|
|
159
|
+
}
|
|
160
|
+
const available = sliceEnd - offset;
|
|
161
|
+
if (length === undefined) {
|
|
162
|
+
length = available;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
if (length < 0 || !Number.isInteger(length)) {
|
|
166
|
+
throw new RangeError(`Invalid length: ${length}`);
|
|
167
|
+
}
|
|
168
|
+
if (length > available) {
|
|
169
|
+
length = available;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return this.buffer.write(string, offset, length, encoding);
|
|
173
|
+
}
|
|
174
|
+
set(source, offset) {
|
|
175
|
+
if (source == null) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (offset === undefined) {
|
|
179
|
+
offset = this.byteOffset;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Validate (not clamp): a negative offset would resolve to a position
|
|
183
|
+
// before the slice and corrupt adjacent (pool) memory.
|
|
184
|
+
if (offset < 0 || offset > this.byteLength || !Number.isInteger(offset)) {
|
|
185
|
+
throw new RangeError(`Invalid offset: ${offset}`);
|
|
186
|
+
}
|
|
187
|
+
offset += this.byteOffset;
|
|
188
|
+
}
|
|
189
|
+
const available = this.byteOffset + this.byteLength - offset;
|
|
190
|
+
if (available <= 0) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const end = source.byteLength < available ? source.byteLength : available;
|
|
194
|
+
source.copy(this.buffer, offset, 0, end);
|
|
195
|
+
}
|
|
196
|
+
at(index) {
|
|
197
|
+
if (!Number.isInteger(index) || index >= this.byteLength || index < -this.byteLength) {
|
|
198
|
+
throw new RangeError(`Index out of range: ${index}`);
|
|
199
|
+
}
|
|
200
|
+
return index >= 0
|
|
201
|
+
? this.buffer[this.byteOffset + index]
|
|
202
|
+
: this.buffer[this.byteOffset + this.byteLength + index];
|
|
203
|
+
}
|
|
204
|
+
test(expr) {
|
|
205
|
+
return expr.test(this.buffer, this.byteOffset, this.byteLength);
|
|
206
|
+
}
|
|
207
|
+
toString(encoding, start, end) {
|
|
208
|
+
const sliceEnd = this.byteOffset + this.byteLength;
|
|
209
|
+
if (start === undefined) {
|
|
210
|
+
start = this.byteOffset;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
if (start < 0 || start > this.byteLength || !Number.isInteger(start)) {
|
|
214
|
+
throw new RangeError(`Invalid start: ${start}`);
|
|
215
|
+
}
|
|
216
|
+
start += this.byteOffset;
|
|
217
|
+
}
|
|
218
|
+
if (end === undefined) {
|
|
219
|
+
end = sliceEnd;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
end += this.byteOffset;
|
|
223
|
+
}
|
|
224
|
+
if (end > sliceEnd) {
|
|
225
|
+
end = sliceEnd;
|
|
226
|
+
}
|
|
227
|
+
if (end < start) {
|
|
228
|
+
end = start;
|
|
229
|
+
}
|
|
230
|
+
return this.buffer.toString(encoding, start, end);
|
|
231
|
+
}
|
|
232
|
+
toBuffer(start, end) {
|
|
233
|
+
const sliceEnd = this.byteOffset + this.byteLength;
|
|
234
|
+
if (start === undefined) {
|
|
235
|
+
start = this.byteOffset;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
if (start < 0 || start > this.byteLength || !Number.isInteger(start)) {
|
|
239
|
+
throw new RangeError(`Invalid start: ${start}`);
|
|
240
|
+
}
|
|
241
|
+
start += this.byteOffset;
|
|
242
|
+
}
|
|
243
|
+
if (end === undefined) {
|
|
244
|
+
end = sliceEnd;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
end += this.byteOffset;
|
|
248
|
+
}
|
|
249
|
+
if (end > sliceEnd) {
|
|
250
|
+
end = sliceEnd;
|
|
251
|
+
}
|
|
252
|
+
if (end < start) {
|
|
253
|
+
end = start;
|
|
254
|
+
}
|
|
255
|
+
return start === 0 && end === this.buffer.byteLength
|
|
256
|
+
? this.buffer
|
|
257
|
+
: this.buffer.subarray(start, end);
|
|
258
|
+
}
|
|
259
|
+
get [Symbol.toStringTag]() {
|
|
260
|
+
return 'Slice';
|
|
261
|
+
}
|
|
262
|
+
[util.inspect.custom]() {
|
|
263
|
+
const MAX_BYTES = 32;
|
|
264
|
+
const len = this.byteLength;
|
|
265
|
+
// A malformed slice (a NaN/non-finite/fractional/negative/out-of-bounds
|
|
266
|
+
// byteOffset or byteLength) is exactly the state a developer inspects while
|
|
267
|
+
// debugging pool corruption — inspect must never throw on it. Coerce
|
|
268
|
+
// byteOffset to a safe integer index in [0, buffer.byteLength]: the
|
|
269
|
+
// `>= 0` test is false for NaN and -Infinity (→ 0), Math.floor truncates a
|
|
270
|
+
// fractional offset, and Math.min caps Infinity/oversize at the buffer end
|
|
271
|
+
// (available 0). Every buffer access below is then guaranteed in-bounds and
|
|
272
|
+
// begin + shown <= buffer.byteLength holds.
|
|
273
|
+
const bufferLength = this.buffer.byteLength;
|
|
274
|
+
const begin = this.byteOffset >= 0 ? Math.min(Math.floor(this.byteOffset), bufferLength) : 0;
|
|
275
|
+
const cap = bufferLength - begin;
|
|
276
|
+
const safeLen = len > 0 ? (len < cap ? len : cap) : 0;
|
|
277
|
+
const shown = safeLen < MAX_BYTES ? safeLen : MAX_BYTES;
|
|
278
|
+
let hex = '';
|
|
279
|
+
for (let i = 0; i < shown; i++) {
|
|
280
|
+
if (i !== 0) {
|
|
281
|
+
hex += ' ';
|
|
282
|
+
}
|
|
283
|
+
hex += this.buffer[begin + i].toString(16).padStart(2, '0');
|
|
284
|
+
}
|
|
285
|
+
if (shown < len) {
|
|
286
|
+
hex += ` ... (${len - shown} more)`;
|
|
287
|
+
}
|
|
288
|
+
const str = this.buffer.toString('utf8', begin, begin + shown);
|
|
289
|
+
const truncated = shown < len ? '…' : '';
|
|
290
|
+
return `Slice(${len}): "${str}${truncated}" <${hex}>`;
|
|
24
291
|
}
|
|
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
|
-
sourceStart += this.byteOffset
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (sourceEnd === undefined) {
|
|
81
|
-
sourceEnd = sliceEnd
|
|
82
|
-
} else {
|
|
83
|
-
sourceEnd += this.byteOffset
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Clamp against the logical slice length so copy() cannot read past
|
|
87
|
-
// the slice's own end and leak adjacent (pool) memory.
|
|
88
|
-
if (sourceEnd > sliceEnd) {
|
|
89
|
-
sourceEnd = sliceEnd
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (target instanceof Slice) {
|
|
93
|
-
const targetEnd = target.byteOffset + target.byteLength
|
|
94
|
-
if (targetStart === undefined) {
|
|
95
|
-
targetStart = target.byteOffset
|
|
96
|
-
} else {
|
|
97
|
-
targetStart += target.byteOffset
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
target = target.buffer
|
|
101
|
-
if (sourceEnd - sourceStart > targetEnd - targetStart) {
|
|
102
|
-
sourceEnd = sourceStart + (targetEnd - targetStart)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
sourceStart === targetStart &&
|
|
108
|
-
this.buffer.buffer === target.buffer &&
|
|
109
|
-
this.buffer.byteOffset === target.byteOffset
|
|
110
|
-
) {
|
|
111
|
-
return sourceEnd - sourceStart
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return this.buffer.copy(target, targetStart, sourceStart, sourceEnd)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
compare(
|
|
118
|
-
target ,
|
|
119
|
-
targetStart ,
|
|
120
|
-
targetEnd ,
|
|
121
|
-
sourceStart ,
|
|
122
|
-
sourceEnd ,
|
|
123
|
-
) {
|
|
124
|
-
if (
|
|
125
|
-
target === this &&
|
|
126
|
-
targetStart === undefined &&
|
|
127
|
-
targetEnd === undefined &&
|
|
128
|
-
sourceStart === undefined &&
|
|
129
|
-
sourceEnd === undefined
|
|
130
|
-
) {
|
|
131
|
-
return 0
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const sliceEnd = this.byteOffset + this.byteLength
|
|
135
|
-
|
|
136
|
-
if (target instanceof Slice) {
|
|
137
|
-
const targetSliceEnd = target.byteOffset + target.byteLength
|
|
138
|
-
if (targetStart === undefined) {
|
|
139
|
-
targetStart = target.byteOffset
|
|
140
|
-
} else {
|
|
141
|
-
targetStart += target.byteOffset
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (targetEnd === undefined) {
|
|
145
|
-
targetEnd = targetSliceEnd
|
|
146
|
-
} else {
|
|
147
|
-
targetEnd += target.byteOffset
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (targetEnd > targetSliceEnd) {
|
|
151
|
-
targetEnd = targetSliceEnd
|
|
152
|
-
}
|
|
153
|
-
target = target.buffer
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (sourceStart === undefined) {
|
|
157
|
-
sourceStart = this.byteOffset
|
|
158
|
-
} else {
|
|
159
|
-
sourceStart += this.byteOffset
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (sourceEnd === undefined) {
|
|
163
|
-
sourceEnd = sliceEnd
|
|
164
|
-
} else {
|
|
165
|
-
sourceEnd += this.byteOffset
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (sourceEnd > sliceEnd) {
|
|
169
|
-
sourceEnd = sliceEnd
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return this.buffer.compare(target, targetStart, targetEnd, sourceStart, sourceEnd)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
write(string , offset , length , encoding ) {
|
|
176
|
-
const sliceEnd = this.byteOffset + this.byteLength
|
|
177
|
-
|
|
178
|
-
if (offset === undefined) {
|
|
179
|
-
offset = this.byteOffset
|
|
180
|
-
} else {
|
|
181
|
-
if (offset < 0 || offset > this.byteLength) {
|
|
182
|
-
throw new RangeError(`Invalid offset: ${offset}`)
|
|
183
|
-
}
|
|
184
|
-
offset += this.byteOffset
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const available = sliceEnd - offset
|
|
188
|
-
if (length === undefined) {
|
|
189
|
-
length = available
|
|
190
|
-
} else if (length > available) {
|
|
191
|
-
length = available
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return this.buffer.write(string, offset, length, encoding)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
set(source , offset ) {
|
|
198
|
-
if (source == null) {
|
|
199
|
-
return
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (offset === undefined) {
|
|
203
|
-
offset = this.byteOffset
|
|
204
|
-
} else {
|
|
205
|
-
offset += this.byteOffset
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const available = this.byteOffset + this.byteLength - offset
|
|
209
|
-
if (available <= 0) {
|
|
210
|
-
return
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const end = source.byteLength < available ? source.byteLength : available
|
|
214
|
-
source.copy(this.buffer, offset, 0, end)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
at(index ) {
|
|
218
|
-
if (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]
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
test(expr
|
|
227
|
-
|
|
228
|
-
) {
|
|
229
|
-
return expr.test(this.buffer, this.byteOffset, this.byteLength)
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
toString(encoding , start , end ) {
|
|
233
|
-
const sliceEnd = this.byteOffset + this.byteLength
|
|
234
|
-
|
|
235
|
-
if (start === undefined) {
|
|
236
|
-
start = this.byteOffset
|
|
237
|
-
} else {
|
|
238
|
-
start += this.byteOffset
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (end === undefined) {
|
|
242
|
-
end = sliceEnd
|
|
243
|
-
} else {
|
|
244
|
-
end += this.byteOffset
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (end > sliceEnd) {
|
|
248
|
-
end = sliceEnd
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return this.buffer.toString(encoding, start, end)
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
toBuffer(start , end ) {
|
|
255
|
-
const sliceEnd = this.byteOffset + this.byteLength
|
|
256
|
-
|
|
257
|
-
if (start === undefined) {
|
|
258
|
-
start = this.byteOffset
|
|
259
|
-
} else {
|
|
260
|
-
start += this.byteOffset
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (end === undefined) {
|
|
264
|
-
end = sliceEnd
|
|
265
|
-
} else {
|
|
266
|
-
end += this.byteOffset
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (end > sliceEnd) {
|
|
270
|
-
end = sliceEnd
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return start === 0 && end === this.buffer.byteLength
|
|
274
|
-
? this.buffer
|
|
275
|
-
: this.buffer.subarray(start, end)
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
get [Symbol.toStringTag]() {
|
|
279
|
-
return 'Slice'
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
[util.inspect.custom]() {
|
|
283
|
-
const MAX_BYTES = 32
|
|
284
|
-
const len = this.byteLength
|
|
285
|
-
const shown = len < MAX_BYTES ? len : MAX_BYTES
|
|
286
|
-
|
|
287
|
-
let hex = ''
|
|
288
|
-
for (let i = 0; i < shown; i++) {
|
|
289
|
-
if (i !== 0) {
|
|
290
|
-
hex += ' '
|
|
291
|
-
}
|
|
292
|
-
hex += this.buffer[this.byteOffset + i].toString(16).padStart(2, '0')
|
|
293
|
-
}
|
|
294
|
-
if (shown < len) {
|
|
295
|
-
hex += ` ... (${len - shown} more)`
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const strEnd = shown < len ? this.byteOffset + shown : this.byteOffset + len
|
|
299
|
-
const str = this.buffer.toString('utf8', this.byteOffset, strEnd)
|
|
300
|
-
const truncated = shown < len ? '…' : ''
|
|
301
|
-
|
|
302
|
-
return `Slice(${len}): "${str}${truncated}" <${hex}>`
|
|
303
|
-
}
|
|
304
292
|
}
|
|
305
|
-
|
|
306
293
|
export class PoolAllocator {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
poolTotalOrBuffer
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
size: this.#size,
|
|
450
|
-
padding: this.#padding,
|
|
451
|
-
ratio: this.#size > this.#padding ? this.#size / (this.#size - this.#padding) : 1,
|
|
452
|
-
poolTotal: this.#poolBuffer.byteLength,
|
|
453
|
-
poolUsed: this.#poolOffset,
|
|
454
|
-
poolSize: this.#poolSize,
|
|
455
|
-
poolCount: this.#poolCount,
|
|
456
|
-
buckets: this.#poolsBucket.map((pool, i) => ({
|
|
457
|
-
free: pool.length,
|
|
458
|
-
used: this.#poolsBucketUsed[i],
|
|
459
|
-
size: pool.length + this.#poolsBucketUsed[i],
|
|
460
|
-
})),
|
|
294
|
+
#size = 0;
|
|
295
|
+
#padding = 0;
|
|
296
|
+
#poolsBucket = [];
|
|
297
|
+
#poolsBucketUsed = [];
|
|
298
|
+
#poolBuffer;
|
|
299
|
+
#poolOffset = 0;
|
|
300
|
+
#poolSize = 0;
|
|
301
|
+
#poolCount = 0;
|
|
302
|
+
constructor(poolTotalOrBuffer = 128 *
|
|
303
|
+
1024 *
|
|
304
|
+
1024) {
|
|
305
|
+
if (typeof poolTotalOrBuffer === 'number') {
|
|
306
|
+
if (!Number.isInteger(poolTotalOrBuffer) || poolTotalOrBuffer < 0) {
|
|
307
|
+
throw new RangeError(`Invalid pool size: ${poolTotalOrBuffer}`);
|
|
308
|
+
}
|
|
309
|
+
this.#poolBuffer = Buffer.allocUnsafeSlow(poolTotalOrBuffer);
|
|
310
|
+
}
|
|
311
|
+
else if (poolTotalOrBuffer instanceof Buffer) {
|
|
312
|
+
this.#poolBuffer = poolTotalOrBuffer;
|
|
313
|
+
}
|
|
314
|
+
else if (ArrayBuffer.isView(poolTotalOrBuffer)) {
|
|
315
|
+
this.#poolBuffer = Buffer.from(poolTotalOrBuffer.buffer, poolTotalOrBuffer.byteOffset, poolTotalOrBuffer.byteLength);
|
|
316
|
+
}
|
|
317
|
+
else if (poolTotalOrBuffer instanceof ArrayBuffer ||
|
|
318
|
+
poolTotalOrBuffer instanceof SharedArrayBuffer) {
|
|
319
|
+
this.#poolBuffer = Buffer.from(poolTotalOrBuffer);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
throw new TypeError('Invalid poolTotalOrBuffer: must be a Buffer, ArrayBufferView, ArrayBuffer, SharedArrayBuffer, or number');
|
|
323
|
+
}
|
|
324
|
+
for (let n = 0; 2 ** n <= 256 * 1024; n++) {
|
|
325
|
+
this.#poolsBucket.push([]);
|
|
326
|
+
this.#poolsBucketUsed.push(0);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
get size() {
|
|
330
|
+
return this.#size;
|
|
331
|
+
}
|
|
332
|
+
isFromPool(slice) {
|
|
333
|
+
return slice != null && slice.buffer === this.#poolBuffer;
|
|
334
|
+
}
|
|
335
|
+
realloc(slice, byteLength) {
|
|
336
|
+
if (typeof slice === 'number') {
|
|
337
|
+
byteLength = slice;
|
|
338
|
+
slice = new Slice();
|
|
339
|
+
}
|
|
340
|
+
if (byteLength == null || !Number.isInteger(byteLength) || byteLength < 0) {
|
|
341
|
+
throw new TypeError(`Invalid byteLength: ${byteLength}`);
|
|
342
|
+
}
|
|
343
|
+
// 2^30 is the largest power-of-two that fits a 32-bit signed int; a
|
|
344
|
+
// larger request overflows `1 << dstIdx` to a negative bucket size.
|
|
345
|
+
if (byteLength > 1 << 30) {
|
|
346
|
+
throw new RangeError(`byteLength too large: ${byteLength} (max ${1 << 30})`);
|
|
347
|
+
}
|
|
348
|
+
if (slice.byteLength === byteLength) {
|
|
349
|
+
return slice;
|
|
350
|
+
}
|
|
351
|
+
// Ceil to nearest power of two — the destination bucket and its byte size.
|
|
352
|
+
const dstIdx = byteLength <= 8 ? 3 : 32 - Math.clz32(byteLength - 1);
|
|
353
|
+
const maxByteLength = 1 << dstIdx;
|
|
354
|
+
if (slice.buffer === this.#poolBuffer) {
|
|
355
|
+
const srcMaxByteLength = slice.maxByteLength;
|
|
356
|
+
// Same-bucket resize is the hot path: just update the logical length and
|
|
357
|
+
// adjust padding by the delta — no bucket bookkeeping, no second clz32,
|
|
358
|
+
// no net change to #size. A free (byteLength === 0) is deliberately
|
|
359
|
+
// excluded so it always falls through to the free-list path below:
|
|
360
|
+
// byteLength 0 maps to dstIdx 3 / maxByteLength 8, which would otherwise
|
|
361
|
+
// match a live bucket-3 slot here and "resize" it to 0 — leaking the slot
|
|
362
|
+
// (never returned to the free list, still counted in #size/#poolSize).
|
|
363
|
+
if (byteLength !== 0 && srcMaxByteLength === maxByteLength) {
|
|
364
|
+
this.#padding += slice.byteLength - byteLength;
|
|
365
|
+
slice.byteLength = byteLength;
|
|
366
|
+
return slice;
|
|
367
|
+
}
|
|
368
|
+
const srcIdx = 32 - Math.clz32(srcMaxByteLength - 1);
|
|
369
|
+
// Corruption tripwire for a foreign/double-freed slice. maxByteLength must
|
|
370
|
+
// be a power of two that maps to a real pool bucket — index in
|
|
371
|
+
// [3, poolsBucket.length). The pool never hands out a slot below bucket 3
|
|
372
|
+
// (8 bytes), so a smaller power of two (1/2/4 → srcIdx 0/1/2) is just as
|
|
373
|
+
// corrupt as an oversized one (e.g. 2^20 → srcIdx 20, out of range):
|
|
374
|
+
// `=== 1 << srcIdx` alone passes both, after which the bucket bookkeeping
|
|
375
|
+
// below would drive an always-empty bucket's `used` count negative (or
|
|
376
|
+
// index a non-existent bucket) and drift #size/#poolSize.
|
|
377
|
+
if (srcMaxByteLength !== 1 << srcIdx || srcIdx < 3 || srcIdx >= this.#poolsBucket.length) {
|
|
378
|
+
throw new Error(`Invalid pool state`);
|
|
379
|
+
}
|
|
380
|
+
this.#size -= srcMaxByteLength;
|
|
381
|
+
this.#padding -= srcMaxByteLength - slice.byteLength;
|
|
382
|
+
this.#poolsBucket[srcIdx].push(slice.byteOffset);
|
|
383
|
+
this.#poolsBucketUsed[srcIdx] -= 1;
|
|
384
|
+
this.#poolSize -= srcMaxByteLength;
|
|
385
|
+
}
|
|
386
|
+
slice.reset();
|
|
387
|
+
if (byteLength === 0) {
|
|
388
|
+
return slice;
|
|
389
|
+
}
|
|
390
|
+
if (dstIdx < this.#poolsBucket.length && this.#poolsBucket[dstIdx].length) {
|
|
391
|
+
slice.buffer = this.#poolBuffer;
|
|
392
|
+
slice.byteOffset = this.#poolsBucket[dstIdx].pop();
|
|
393
|
+
slice.byteLength = byteLength;
|
|
394
|
+
slice.maxByteLength = maxByteLength;
|
|
395
|
+
this.#poolsBucketUsed[dstIdx] += 1;
|
|
396
|
+
this.#poolSize += maxByteLength;
|
|
397
|
+
this.#size += maxByteLength;
|
|
398
|
+
this.#padding += maxByteLength - byteLength;
|
|
399
|
+
}
|
|
400
|
+
else if (dstIdx < this.#poolsBucket.length &&
|
|
401
|
+
this.#poolOffset + maxByteLength <= this.#poolBuffer.byteLength) {
|
|
402
|
+
slice.buffer = this.#poolBuffer;
|
|
403
|
+
slice.byteOffset = this.#poolOffset;
|
|
404
|
+
slice.byteLength = byteLength;
|
|
405
|
+
slice.maxByteLength = maxByteLength;
|
|
406
|
+
this.#poolOffset += maxByteLength;
|
|
407
|
+
this.#poolCount += 1;
|
|
408
|
+
this.#poolsBucketUsed[dstIdx] += 1;
|
|
409
|
+
this.#poolSize += maxByteLength;
|
|
410
|
+
this.#size += maxByteLength;
|
|
411
|
+
this.#padding += maxByteLength - byteLength;
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
slice.buffer = Buffer.allocUnsafeSlow(byteLength);
|
|
415
|
+
slice.byteOffset = 0;
|
|
416
|
+
slice.byteLength = byteLength;
|
|
417
|
+
slice.maxByteLength = byteLength;
|
|
418
|
+
}
|
|
419
|
+
return slice;
|
|
420
|
+
}
|
|
421
|
+
get stats() {
|
|
422
|
+
return {
|
|
423
|
+
size: this.#size,
|
|
424
|
+
padding: this.#padding,
|
|
425
|
+
ratio: this.#size > this.#padding ? this.#size / (this.#size - this.#padding) : 1,
|
|
426
|
+
poolTotal: this.#poolBuffer.byteLength,
|
|
427
|
+
poolUsed: this.#poolOffset,
|
|
428
|
+
poolSize: this.#poolSize,
|
|
429
|
+
poolCount: this.#poolCount,
|
|
430
|
+
buckets: this.#poolsBucket.map((pool, i) => ({
|
|
431
|
+
free: pool.length,
|
|
432
|
+
used: this.#poolsBucketUsed[i],
|
|
433
|
+
size: pool.length + this.#poolsBucketUsed[i],
|
|
434
|
+
})),
|
|
435
|
+
};
|
|
461
436
|
}
|
|
462
|
-
}
|
|
463
437
|
}
|
|
438
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -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.
|
|
3
|
+
"version": "1.1.11",
|
|
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
|
|
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": "
|
|
32
|
+
"gitHead": "7c9c7457c885c644c7a1e70ef894d4727ce240d6"
|
|
34
33
|
}
|