@daneren2005/shared-memory-objects 1.6.1 → 1.6.3
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 +3 -2
- package/dist/allocated-memory.js +1 -2
- package/dist/cached-item-list.js +1 -2
- package/dist/constant-string.js +13 -14
- package/dist/local-pool.js +5 -6
- package/dist/lock/read-write-lock.js +0 -1
- package/dist/lock/simple-lock.js +0 -1
- package/dist/memory-buffer.js +1 -2
- package/dist/memory-heap.js +24 -25
- package/dist/serialize-object.js +4 -5
- package/dist/shared-list.js +43 -44
- package/dist/shared-map.js +74 -75
- package/dist/shared-pointer-list.js +15 -16
- package/dist/shared-pool.d.ts +1 -0
- package/dist/shared-pool.js +36 -32
- package/dist/shared-pool.js.map +1 -1
- package/dist/shared-stack.js +33 -34
- package/dist/shared-string.js +19 -20
- package/dist/shared-vector.js +23 -24
- package/dist/spatial/shared-quadtree.js +81 -82
- package/dist/spatial/shared-quadtree.js.map +1 -1
- package/dist/spatial/shared-spatial-grid.js +104 -110
- package/dist/spatial/shared-spatial-grid.js.map +1 -1
- package/dist/spatial/shared-spatial-map.d.ts +2 -0
- package/dist/spatial/shared-spatial-map.js +205 -202
- package/dist/spatial/shared-spatial-map.js.map +1 -1
- package/dist/spatial/spatial-entity.js +1 -2
- package/dist/spatial/spatial-neighbors.js +1 -2
- package/dist/utils/16-from-32-array.js +1 -2
- package/dist/utils/16-from-32-float.js +1 -2
- package/dist/utils/16-from-32-int.js +1 -2
- package/dist/utils/16-from-32-uint.js +1 -2
- package/dist/utils/16-from-64-array.js +1 -2
- package/dist/utils/16-from-64-float.js +1 -2
- package/dist/utils/16-from-64-int.js +1 -2
- package/dist/utils/16-from-64-uint.js +1 -2
- package/dist/utils/32-from-64-float.js +1 -2
- package/dist/utils/32-from-64-int.js +1 -2
- package/dist/utils/32-from-64-uint.js +1 -2
- package/dist/utils/array-type.js +1 -2
- package/dist/utils/atomic-math.js +1 -2
- package/dist/utils/float32-atomics.js +1 -2
- package/dist/utils/float64-atomics.js +1 -2
- package/dist/utils/hash.js +1 -2
- package/dist/utils/pointer.js +1 -2
- package/dist/utils/typedarray.js +1 -2
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ Freshly allocated with the default options:
|
|
|
78
78
|
|
|
79
79
|
| Structure | Used Memory |
|
|
80
80
|
| ------------------------------- | ----------- |
|
|
81
|
-
| SharedList |
|
|
81
|
+
| SharedList | 32 bytes |
|
|
82
82
|
| SharedVector | 32 bytes |
|
|
83
83
|
| SharedStack | 144 bytes |
|
|
84
84
|
| SharedPool | 664 bytes |
|
|
@@ -88,13 +88,14 @@ Freshly allocated with the default options:
|
|
|
88
88
|
| SharedSpatialGrid (20x20 cells) | 8816 bytes |
|
|
89
89
|
| SharedSpatialGrid (80x80 cells) | 56816 bytes |
|
|
90
90
|
| SharedSpatialMap (default) | 8984 bytes |
|
|
91
|
+
| SharedSpatialMap (Float64) | 14984 bytes |
|
|
91
92
|
| SharedSpatialMap (2048 buckets) | 23384 bytes |
|
|
92
93
|
|
|
93
94
|
`SharedQuadtree`'s footprint is dominated by its fixed node array, which is allocated once up front and never grows. The default `maxLevels` of 4 is a complete tree of 341 nodes (`(4^(maxLevels+1) - 1) / 3`), so the number scales with `maxLevels`: a deeper tree resolves smaller entities but costs `~2 u32` per node. The rest is its internal `SharedPool` of entity records and the `SharedMap` that indexes entities by id, whose header blocks are inlined into the tree's own allocation (the same way `SharedPool` inlines its two stacks) so the whole spine is one contiguous block instead of three separate pointer resources. The record (id, `x/y/w/h`, node, bucket link) is stored at the configured precision, defaulting to `Float32` to match a physics engine that keeps positions in `Float32`. `Float32` stays exact as long as entity ids and the entity count both stay under 2^24 (~16.7M); pass `type: Float64Array` if you need ids or a capacity beyond that (constructing a `Float32` tree with `maxEntities` over 2^24 throws), at the cost of more memory per entity.
|
|
94
95
|
|
|
95
96
|
`SharedSpatialGrid`'s footprint is likewise dominated by its fixed cell array (`cols x rows` cells at `~2 u32` each), so it scales with cell count rather than `maxLevels`: `cols = ceil(width / gridSize)` and `rows = ceil(height / gridSize)`, so a smaller `gridSize` resolves finer at the cost of more cells (the 20x20 grid above is a 1000x1000 world at `gridSize` 50; the 80x80 grid is a 4000x4000 world at `gridSize` 50). The rest is two inlined `SharedPool`s - one of entity records (the occupied cell rectangle, keyed by an inlined `SharedMap` of id -> index) and one of per-cell "slot" records (`id`, anchor cell, bucket link) - since a multi-cell entity needs one slot per cell it overlaps. `maxSlots` therefore defaults to `maxEntities * 4` to leave headroom for spanning entities. Coordinate precision follows the same `Float32`-default rule as the quadtree (ids, both pools' indices, and cell indices must stay under 2^24 for `Float32`; pass `type: Float64Array` otherwise).
|
|
96
97
|
|
|
97
|
-
`SharedSpatialMap` starts at 8984 bytes with its default 256 buckets, about 87% less than the former fixed 8192-bucket table's 70312 bytes. When the number of allocated slots exceeds half the active bucket count, it doubles the count and rebuilds the bucket chains. Its 256-bucket pages remain at stable addresses, while their pointers live in a `SharedStack` that grows in segments. `buckets` is therefore an initial size hint rather than a permanent sizing decision; `map.buckets` reports the current count. `maxBuckets` can stop growth for a deliberately collision-heavy or memory-capped table and otherwise defaults high enough to preserve the target load through `maxSlots`. The rest is the same two inlined `SharedPool`s as the grid - one of entity records and one of per-cell slot records. `maxSlots` defaults to `maxEntities * 4`, and coordinate precision follows the same `Float32`-default rule.
|
|
98
|
+
`SharedSpatialMap` starts at 8984 bytes with its default 256 buckets, about 87% less than the former fixed 8192-bucket table's 70312 bytes. When the number of allocated slots exceeds half the active bucket count, it doubles the count and rebuilds the bucket chains. Its 256-bucket pages remain at stable addresses, while their pointers live in a `SharedStack` that grows in segments. `buckets` is therefore an initial size hint rather than a permanent sizing decision; `map.buckets` reports the current count. `maxBuckets` can stop growth for a deliberately collision-heavy or memory-capped table and otherwise defaults high enough to preserve the target load through `maxSlots`. The rest is the same two inlined `SharedPool`s as the grid - one of entity records and one of per-cell slot records. `maxSlots` defaults to `maxEntities * 4`, and coordinate precision follows the same `Float32`-default rule. Ids must be integers in `[0, 2^24)` for `Float32` or `[0, 2^32)` for `Float64` (the id map's keys are uint32); `insert`, `update`, and `bulkInsert` throw on anything else rather than storing an entity that could never be found or removed again.
|
|
98
99
|
|
|
99
100
|
All three spatial indexes accept `bulkInsert(entities)`, where each entity has `{ id, x, y, width?, height? }`. Duplicate ids keep their last value. The method retains the normal thread-safety guarantees while reserving entity and slot ranges with one atomic operation, sizing the ID map once, and writing records directly into their pool blocks; `SharedSpatialMap` also sizes its bucket table once before linking a new batch. When an explicit entity or slot capacity is at most 16384, its pool uses one bounded contiguous chunk instead of a series of 100-record chunks. Larger and default capacities retain incremental allocation so an empty index does not reserve excessive memory.
|
|
100
101
|
|
package/dist/allocated-memory.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createPointer as e } from "./utils/pointer.js";
|
|
2
|
-
|
|
2
|
+
// src/allocated-memory.ts
|
|
3
3
|
var t = class t {
|
|
4
4
|
memory;
|
|
5
5
|
bufferPosition;
|
|
@@ -49,7 +49,6 @@ var t = class t {
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
|
-
//#endregion
|
|
53
52
|
export { t as default };
|
|
54
53
|
|
|
55
54
|
//# sourceMappingURL=allocated-memory.js.map
|
package/dist/cached-item-list.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import e from "./shared-list.js";
|
|
2
|
-
|
|
2
|
+
// src/cached-item-list.ts
|
|
3
3
|
var t = class {
|
|
4
4
|
static ALLOCATE_COUNT = e.ALLOCATE_COUNT;
|
|
5
5
|
heap;
|
|
@@ -70,7 +70,6 @@ var t = class {
|
|
|
70
70
|
this.list.free(), this.cache.clear();
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
|
-
//#endregion
|
|
74
73
|
export { t as default };
|
|
75
74
|
|
|
76
75
|
//# sourceMappingURL=cached-item-list.js.map
|
package/dist/constant-string.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import r from "./
|
|
3
|
-
|
|
1
|
+
import e from "./allocated-memory.js";
|
|
2
|
+
import { getPointer as t, loadRawPointer as n, storeRawPointer as r } from "./utils/pointer.js";
|
|
3
|
+
// src/constant-string.ts
|
|
4
4
|
var i = {
|
|
5
5
|
1: Uint8Array,
|
|
6
6
|
2: Uint16Array
|
|
@@ -9,17 +9,17 @@ var i = {
|
|
|
9
9
|
memory;
|
|
10
10
|
allocatedMemory;
|
|
11
11
|
value;
|
|
12
|
-
constructor(
|
|
13
|
-
this.memory =
|
|
12
|
+
constructor(t, n) {
|
|
13
|
+
this.memory = t, typeof n == "string" ? (this.allocatedMemory = this.memory.allocUI32(c.ALLOCATE_COUNT), this.writeString(n), this.value = n) : (this.allocatedMemory = new e(t, n), this.value = this.readString());
|
|
14
14
|
}
|
|
15
15
|
writeString(e) {
|
|
16
16
|
let t = this.createString(e);
|
|
17
|
-
|
|
17
|
+
r(this.allocatedMemory.data, a, t.pointer), Atomics.store(this.allocatedMemory.data, o, e.length), Atomics.store(this.allocatedMemory.data, s, t.charType);
|
|
18
18
|
}
|
|
19
19
|
readString() {
|
|
20
|
-
let
|
|
21
|
-
if (
|
|
22
|
-
let { bufferPosition: r, bufferByteOffset: c } = e
|
|
20
|
+
let e = n(this.allocatedMemory.data, a);
|
|
21
|
+
if (e === 0) return "";
|
|
22
|
+
let { bufferPosition: r, bufferByteOffset: c } = t(e, this.memory.positionBits), u = i[Atomics.load(this.allocatedMemory.data, s)], d = Atomics.load(this.allocatedMemory.data, o);
|
|
23
23
|
return l(new u(this.memory.buffers[r].buf, c, d));
|
|
24
24
|
}
|
|
25
25
|
createString(e) {
|
|
@@ -46,10 +46,10 @@ var i = {
|
|
|
46
46
|
return this.allocatedMemory.pointer;
|
|
47
47
|
}
|
|
48
48
|
free() {
|
|
49
|
-
let
|
|
50
|
-
if (
|
|
51
|
-
let { bufferPosition:
|
|
52
|
-
this.memory.buffers[
|
|
49
|
+
let e = n(this.allocatedMemory.data, a);
|
|
50
|
+
if (e) {
|
|
51
|
+
let { bufferPosition: n, bufferByteOffset: r } = t(e, this.memory.positionBits);
|
|
52
|
+
this.memory.buffers[n].free(r);
|
|
53
53
|
}
|
|
54
54
|
this.allocatedMemory.free();
|
|
55
55
|
}
|
|
@@ -61,7 +61,6 @@ function l(e) {
|
|
|
61
61
|
for (let r = 0; r < e.length; r += t) n += String.fromCharCode.apply(null, e.subarray(r, r + t));
|
|
62
62
|
return n;
|
|
63
63
|
}
|
|
64
|
-
//#endregion
|
|
65
64
|
export { c as default };
|
|
66
65
|
|
|
67
66
|
//# sourceMappingURL=constant-string.js.map
|
package/dist/local-pool.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import t from "./
|
|
1
|
+
import e from "./allocated-memory.js";
|
|
2
|
+
import { getPointer as t } from "./utils/pointer.js";
|
|
3
3
|
import { getArrayTypeCode as n, getByteMultipler as r } from "./utils/array-type.js";
|
|
4
|
-
|
|
4
|
+
// src/local-pool.ts
|
|
5
5
|
var i = class {
|
|
6
6
|
memory;
|
|
7
7
|
pointers = [];
|
|
@@ -75,7 +75,7 @@ var i = class {
|
|
|
75
75
|
let e = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);
|
|
76
76
|
this.pointers.push(e.pointer);
|
|
77
77
|
}
|
|
78
|
-
let a = new
|
|
78
|
+
let a = new e(this.memory, t(this.pointers[r], this.memory.positionBits)), o = new this.typeConstructor(a.data.buffer, a.bufferByteOffset, this.dataLength * this.maxChunkSize);
|
|
79
79
|
return this.fullDataBlocks[r] = o, o;
|
|
80
80
|
}
|
|
81
81
|
getDataBlock(e, t) {
|
|
@@ -83,11 +83,10 @@ var i = class {
|
|
|
83
83
|
return e.subarray(n, n + this.dataLength);
|
|
84
84
|
}
|
|
85
85
|
free() {
|
|
86
|
-
for (let n of this.pointers) new
|
|
86
|
+
for (let n of this.pointers) new e(this.memory, t(n, this.memory.positionBits)).free();
|
|
87
87
|
this.pointers = [], this.recycledIndexes = [], this.totalLength = 0, this.fullDataBlocks = {};
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
|
-
//#endregion
|
|
91
90
|
export { i as default };
|
|
92
91
|
|
|
93
92
|
//# sourceMappingURL=local-pool.js.map
|
|
@@ -30,7 +30,6 @@ function a(e, t = 0) {
|
|
|
30
30
|
Atomics.compareExchange(e, t, -1, 0) !== -1 && console.warn("We are unlocking when it was not write locked!"), Atomics.notify(e, t), Atomics.notify(e, t + 1);
|
|
31
31
|
}
|
|
32
32
|
var o = 2;
|
|
33
|
-
//#endregion
|
|
34
33
|
export { o as READ_WRITE_LOCK_ALLOCATE_COUNT, t as readLock, i as readUnlock, r as tryWriteLock, n as writeLock, a as writeUnlock };
|
|
35
34
|
|
|
36
35
|
//# sourceMappingURL=read-write-lock.js.map
|
package/dist/lock/simple-lock.js
CHANGED
package/dist/memory-buffer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { lock as e, unlock as t } from "./lock/simple-lock.js";
|
|
2
2
|
import { typedArray as n } from "./utils/typedarray.js";
|
|
3
|
-
|
|
3
|
+
// src/memory-buffer.ts
|
|
4
4
|
var r = 0, i = 1, a = 2, o = 3, s = 4, c = 5, l = 6, u = 7, d = 1, f = 2, p = {
|
|
5
5
|
u8: 1,
|
|
6
6
|
u8c: 1,
|
|
@@ -260,7 +260,6 @@ function T(e, t) {
|
|
|
260
260
|
return t--, e + t & ~t;
|
|
261
261
|
}
|
|
262
262
|
var E = T(52, 8);
|
|
263
|
-
//#endregion
|
|
264
263
|
export { E as FIRST_BLOCK_DATA_BYTE_OFFSET, y as SIZEOF_MEM_BLOCK, m as SIZEOF_STATE, S as default };
|
|
265
264
|
|
|
266
265
|
//# sourceMappingURL=memory-buffer.js.map
|
package/dist/memory-heap.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import n from "./
|
|
1
|
+
import e from "./allocated-memory.js";
|
|
2
|
+
import { MAX_BYTE_OFFSET_LENGTH as t, positionBitsForBufferSize as n } from "./utils/pointer.js";
|
|
3
3
|
import r, { FIRST_BLOCK_DATA_BYTE_OFFSET as i } from "./memory-buffer.js";
|
|
4
|
-
|
|
5
|
-
var a =
|
|
4
|
+
// src/memory-heap.ts
|
|
5
|
+
var a = t, o = 2 ** 31, s = 0, c = 1, l = 2, u = 3, d = 4, f = class {
|
|
6
6
|
buffers;
|
|
7
7
|
onGrowBufferHandlers = [];
|
|
8
8
|
isClone;
|
|
@@ -18,29 +18,29 @@ var a = e, o = 2 ** 31, s = 0, c = 1, l = 2, u = 3, d = 4, f = class {
|
|
|
18
18
|
get maxAllocationLength() {
|
|
19
19
|
return Math.floor((this.bufferSize - 36 - 16) / Uint32Array.BYTES_PER_ELEMENT);
|
|
20
20
|
}
|
|
21
|
-
constructor(
|
|
22
|
-
if (
|
|
21
|
+
constructor(t) {
|
|
22
|
+
if (t && "buffers" in t) this.buffers = t.buffers.map((e) => new r({
|
|
23
23
|
buf: e,
|
|
24
24
|
skipInitialization: !0
|
|
25
|
-
})), this.memory = new
|
|
25
|
+
})), this.memory = new e(this, {
|
|
26
26
|
bufferPosition: 0,
|
|
27
27
|
bufferByteOffset: i
|
|
28
28
|
}), this.positionBits = this.memory.data[u], this.isClone = !0;
|
|
29
29
|
else {
|
|
30
30
|
"SharedArrayBuffer" in globalThis || console.warn("SharedArrayBuffer is not working: falling back to ArrayBuffer");
|
|
31
|
-
let r =
|
|
31
|
+
let r = t?.bufferSize ?? a;
|
|
32
32
|
if (r > o) throw Error(`Buffer size ${r} is greater than max ${o} that we can reference with pointers`);
|
|
33
|
-
this.positionBits =
|
|
33
|
+
this.positionBits = n(r);
|
|
34
34
|
let i = this.createBuffer(r);
|
|
35
35
|
this.buffers = [i];
|
|
36
36
|
let f = i.callocAs("u32", d);
|
|
37
|
-
if (f) this.memory = new
|
|
37
|
+
if (f) this.memory = new e(this, {
|
|
38
38
|
bufferPosition: 0,
|
|
39
39
|
bufferByteOffset: f.byteOffset
|
|
40
40
|
});
|
|
41
41
|
else throw Error("Failed to initialize first byte from buffer");
|
|
42
|
-
this.memory.data[s] = r, this.memory.data[l] =
|
|
43
|
-
for (let
|
|
42
|
+
this.memory.data[s] = r, this.memory.data[l] = t?.autoGrowSize ?? 100, this.memory.data[u] = this.positionBits, this.isClone = !1;
|
|
43
|
+
for (let e = 1; e < (t?.initialBuffers ?? 1); e++) this.buffers.push(this.createBuffer(r));
|
|
44
44
|
this.memory.data[c] = this.buffers.length;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -75,28 +75,28 @@ var a = e, o = 2 ** 31, s = 0, c = 1, l = 2, u = 3, d = 4, f = class {
|
|
|
75
75
|
}
|
|
76
76
|
return this.growBuffer(), !0;
|
|
77
77
|
}
|
|
78
|
-
allocUI32(
|
|
79
|
-
|
|
80
|
-
let
|
|
81
|
-
for (let r = 0; r <
|
|
82
|
-
let i = (this.allocCursor + r) %
|
|
78
|
+
allocUI32(t) {
|
|
79
|
+
t = Math.ceil(t);
|
|
80
|
+
let n = this.buffers.length;
|
|
81
|
+
for (let r = 0; r < n; r++) {
|
|
82
|
+
let i = (this.allocCursor + r) % n, a = this.buffers[i];
|
|
83
83
|
if (!a) continue;
|
|
84
|
-
let o = a.callocAs("u32",
|
|
85
|
-
if (o) return this.allocCursor = i, i === this.buffers.length - 1 && Atomics.load(this.memory.data, c) === this.buffers.length && this.memory.data[l] < 100 && this.memory.data[l] > 0 && a.top / a.end > this.memory.data[l] / 100 && this.growBuffer(), new
|
|
84
|
+
let o = a.callocAs("u32", t);
|
|
85
|
+
if (o) return this.allocCursor = i, i === this.buffers.length - 1 && Atomics.load(this.memory.data, c) === this.buffers.length && this.memory.data[l] < 100 && this.memory.data[l] > 0 && a.top / a.end > this.memory.data[l] / 100 && this.growBuffer(), new e(this, {
|
|
86
86
|
data: o,
|
|
87
87
|
buffer: a
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
90
|
if (this.buffers.length >= this.maxBuffers) throw Error(`Can't initialize a new buffer since it would have a position greater than the max of ${this.maxBuffers}`);
|
|
91
|
-
let r = this.growBuffer(), i = r.callocAs("u32",
|
|
92
|
-
if (i) return this.allocCursor = this.buffers.indexOf(r), new
|
|
91
|
+
let r = this.growBuffer(), i = r.callocAs("u32", t);
|
|
92
|
+
if (i) return this.allocCursor = this.buffers.indexOf(r), new e(this, {
|
|
93
93
|
data: i,
|
|
94
94
|
buffer: r
|
|
95
95
|
});
|
|
96
|
-
throw Error(`Unable to allocate ${
|
|
96
|
+
throw Error(`Unable to allocate ${t} numbers even after adding a new buffer`);
|
|
97
97
|
}
|
|
98
|
-
getSharedAlloc(
|
|
99
|
-
if (this.buffers[
|
|
98
|
+
getSharedAlloc(t) {
|
|
99
|
+
if (this.buffers[t.bufferPosition] !== void 0) return new e(this, t);
|
|
100
100
|
}
|
|
101
101
|
get currentUsed() {
|
|
102
102
|
return this.totalAllocated - this.buffers.reduce((e, t) => e + t.stats().available, 0);
|
|
@@ -108,7 +108,6 @@ var a = e, o = 2 ** 31, s = 0, c = 1, l = 2, u = 3, d = 4, f = class {
|
|
|
108
108
|
return { buffers: this.buffers.map((e) => e.buf) };
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
|
-
//#endregion
|
|
112
111
|
export { f as default };
|
|
113
112
|
|
|
114
113
|
//# sourceMappingURL=memory-heap.js.map
|
package/dist/serialize-object.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import t from "./
|
|
3
|
-
|
|
1
|
+
import e from "./allocated-memory.js";
|
|
2
|
+
import { getPointer as t } from "./utils/pointer.js";
|
|
3
|
+
// src/serialize-object.ts
|
|
4
4
|
var n = 52361700;
|
|
5
5
|
function r(e, t) {
|
|
6
6
|
let r = [], i = Object.keys(t);
|
|
@@ -16,7 +16,7 @@ function r(e, t) {
|
|
|
16
16
|
return s.getArray(Float32Array, 0, r.length).set(r), s;
|
|
17
17
|
}
|
|
18
18
|
function i(n, r) {
|
|
19
|
-
return a(new
|
|
19
|
+
return a(new e(n, t(r, n.positionBits)));
|
|
20
20
|
}
|
|
21
21
|
function a(e) {
|
|
22
22
|
let t = new Float32Array(e.data.buffer, e.bufferByteOffset);
|
|
@@ -41,7 +41,6 @@ function a(e) {
|
|
|
41
41
|
function o(e, t) {
|
|
42
42
|
for (let n = 0; n < t.length; n++) e.push(t.charCodeAt(n));
|
|
43
43
|
}
|
|
44
|
-
//#endregion
|
|
45
44
|
export { a as createObjectFromMemory, i as createObjectFromPointer, r as serializeObjectToMemory };
|
|
46
45
|
|
|
47
46
|
//# sourceMappingURL=serialize-object.js.map
|
package/dist/shared-list.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import i from "./
|
|
1
|
+
import e from "./allocated-memory.js";
|
|
2
|
+
import { loadPointer as t, loadRawPointer as n, replaceRawPointer as r, storeRawPointer as i } from "./utils/pointer.js";
|
|
3
3
|
import { readLock as a, readUnlock as o, tryWriteLock as s, writeLock as c, writeUnlock as l } from "./lock/read-write-lock.js";
|
|
4
4
|
import { getArrayTypeCode as u, getByteMultipler as d, isBigIntType as f, isFloatType as p, makeArrayView as m } from "./utils/array-type.js";
|
|
5
|
-
|
|
5
|
+
// src/shared-list.ts
|
|
6
6
|
var h = 7, g = 2, _ = g * Uint32Array.BYTES_PER_ELEMENT, v = 0, y = 1, b = 2, x = 4, S = 5, C = 0, w = 1, T = 16, E = class {
|
|
7
7
|
static ALLOCATE_COUNT = h;
|
|
8
8
|
memory;
|
|
@@ -22,15 +22,15 @@ var h = 7, g = 2, _ = g * Uint32Array.BYTES_PER_ELEMENT, v = 0, y = 1, b = 2, x
|
|
|
22
22
|
return Atomics.load(this.firstBlock.data, b);
|
|
23
23
|
}
|
|
24
24
|
get usedMemory() {
|
|
25
|
-
let
|
|
26
|
-
for (;
|
|
27
|
-
let a = new
|
|
28
|
-
bufferPosition:
|
|
29
|
-
bufferByteOffset:
|
|
25
|
+
let n = this.firstBlock.usedMemory, { bufferPosition: r, bufferByteOffset: i } = t(this.firstBlock.data, v, this.positionBits);
|
|
26
|
+
for (; i;) {
|
|
27
|
+
let a = new e(this.memory, {
|
|
28
|
+
bufferPosition: r,
|
|
29
|
+
bufferByteOffset: i
|
|
30
30
|
});
|
|
31
|
-
|
|
31
|
+
n += a.usedMemory, {bufferPosition: r, bufferByteOffset: i} = t(a.data, C, this.positionBits);
|
|
32
32
|
}
|
|
33
|
-
return
|
|
33
|
+
return n;
|
|
34
34
|
}
|
|
35
35
|
get type() {
|
|
36
36
|
return this.cachedType;
|
|
@@ -44,27 +44,27 @@ var h = 7, g = 2, _ = g * Uint32Array.BYTES_PER_ELEMENT, v = 0, y = 1, b = 2, x
|
|
|
44
44
|
set dataLength(e) {
|
|
45
45
|
Atomics.store(this.uint16Array, 1, e);
|
|
46
46
|
}
|
|
47
|
-
constructor(
|
|
48
|
-
this.memory =
|
|
47
|
+
constructor(t, n) {
|
|
48
|
+
this.memory = t, this.positionBits = t.positionBits, this.positionMask = (1 << this.positionBits) - 1, n && "firstBlock" in n ? (this.firstBlock = new e(t, n.firstBlock), this.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + 3 * Uint32Array.BYTES_PER_ELEMENT, 2)) : (this.firstBlock = n && n.initWithBlock ? new e(t, n.initWithBlock) : t.allocUI32(h), this.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + 3 * Uint32Array.BYTES_PER_ELEMENT, 2), i(this.firstBlock.data, y, this.firstBlock.pointer), this.type = u(n?.type ?? Uint32Array), this.dataLength = n?.dataLength ?? 1), this.lockArray = new Int32Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + S * Uint32Array.BYTES_PER_ELEMENT, 2), this.cachedType = Atomics.load(this.uint16Array, 0), this.cachedDataLength = Math.max(1, Atomics.load(this.uint16Array, 1)), this.cachedByteMultipler = d(this.cachedType), this.cachedIsBigInt = f(this.cachedType), this.cachedIsFloat = p(this.cachedType);
|
|
49
49
|
}
|
|
50
50
|
insert(e) {
|
|
51
51
|
Array.isArray(e) || (e = [e]);
|
|
52
|
-
let
|
|
53
|
-
if (e.length >
|
|
54
|
-
let i = this.memory.allocUI32(g +
|
|
52
|
+
let t = this.cachedDataLength;
|
|
53
|
+
if (e.length > t) throw Error(`Can't insert ${e.length} array into shared list of ${t} dataLength`);
|
|
54
|
+
let i = this.memory.allocUI32(g + t * this.cachedByteMultipler), a = this.getDataBlock(i.data.buffer, i.data.byteOffset), o = i.pointer, s = a;
|
|
55
55
|
for (let t = 0; t < e.length; t++) this.cachedIsFloat ? s[t] = e[t] : (this.cachedIsBigInt, Atomics.store(a, t, e[t]));
|
|
56
56
|
let c = this.positionBits, l = this.positionMask;
|
|
57
57
|
for (;;) {
|
|
58
|
-
let e =
|
|
59
|
-
if (!
|
|
60
|
-
let i = (e >>> c >>> 2) + C, a = Atomics.load(
|
|
61
|
-
if (e ===
|
|
58
|
+
let e = n(this.firstBlock.data, y), t = this.getBufferView(e & l);
|
|
59
|
+
if (!t) continue;
|
|
60
|
+
let i = (e >>> c >>> 2) + C, a = Atomics.load(t, i);
|
|
61
|
+
if (e === n(this.firstBlock.data, y)) {
|
|
62
62
|
if (a === 0) {
|
|
63
|
-
if (Atomics.compareExchange(
|
|
64
|
-
|
|
63
|
+
if (Atomics.compareExchange(t, i, 0, o) === 0) {
|
|
64
|
+
r(this.firstBlock.data, y, o, e);
|
|
65
65
|
break;
|
|
66
66
|
}
|
|
67
|
-
} else
|
|
67
|
+
} else r(this.firstBlock.data, y, a, e);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
Atomics.add(this.firstBlock.data, b, 1);
|
|
@@ -110,18 +110,18 @@ var h = 7, g = 2, _ = g * Uint32Array.BYTES_PER_ELEMENT, v = 0, y = 1, b = 2, x
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
reclaimTombstones(e) {
|
|
113
|
-
let
|
|
113
|
+
let t = this.firstBlock.pointer, a = this.firstBlock.data, o = C, s = this.positionBits, c = this.positionMask, l = 0, u = n(a, o);
|
|
114
114
|
for (; u;) {
|
|
115
|
-
let
|
|
115
|
+
let n = u & c, d = this.memory.buffers[n];
|
|
116
116
|
if (!d) break;
|
|
117
|
-
let f = this.getBufferView(
|
|
117
|
+
let f = this.getBufferView(n), p = u >>> s, m = p >>> 2, h = Atomics.load(f, m + C);
|
|
118
118
|
if (Atomics.load(f, m + w)) {
|
|
119
119
|
if (h === 0 && !e) break;
|
|
120
|
-
|
|
121
|
-
} else
|
|
120
|
+
i(a, o, h), r(this.firstBlock.data, y, t, u), d.free(p), l++;
|
|
121
|
+
} else t = u, a = f, o = m + C;
|
|
122
122
|
u = h;
|
|
123
123
|
}
|
|
124
|
-
return e &&
|
|
124
|
+
return e && i(this.firstBlock.data, y, t), l && Atomics.sub(this.firstBlock.data, x, l), l;
|
|
125
125
|
}
|
|
126
126
|
clear() {
|
|
127
127
|
c(this.lockArray);
|
|
@@ -132,13 +132,13 @@ var h = 7, g = 2, _ = g * Uint32Array.BYTES_PER_ELEMENT, v = 0, y = 1, b = 2, x
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
clearLocked() {
|
|
135
|
-
let e,
|
|
136
|
-
for (; !
|
|
137
|
-
if (e =
|
|
138
|
-
|
|
135
|
+
let e, t = !1;
|
|
136
|
+
for (; !t;) {
|
|
137
|
+
if (e = n(this.firstBlock.data, v), !e) return;
|
|
138
|
+
t = r(this.firstBlock.data, v, 0, e);
|
|
139
139
|
}
|
|
140
140
|
if (!e) return;
|
|
141
|
-
|
|
141
|
+
i(this.firstBlock.data, y, this.firstBlock.pointer);
|
|
142
142
|
let a = 0, o = this.positionBits, s = this.positionMask, c = e;
|
|
143
143
|
for (; c;) {
|
|
144
144
|
let e = c & s, t = this.memory.buffers[e];
|
|
@@ -149,14 +149,14 @@ var h = 7, g = 2, _ = g * Uint32Array.BYTES_PER_ELEMENT, v = 0, y = 1, b = 2, x
|
|
|
149
149
|
Atomics.sub(this.firstBlock.data, b, a), Atomics.store(this.firstBlock.data, x, 0);
|
|
150
150
|
}
|
|
151
151
|
*[Symbol.iterator]() {
|
|
152
|
-
let e = 0,
|
|
152
|
+
let e = 0, t = this.positionBits, r = this.positionMask;
|
|
153
153
|
a(this.lockArray);
|
|
154
154
|
try {
|
|
155
|
-
let i =
|
|
155
|
+
let i = n(this.firstBlock.data, v);
|
|
156
156
|
for (; i;) {
|
|
157
|
-
let
|
|
157
|
+
let n = i & r, a = this.getBufferView(n);
|
|
158
158
|
if (!a) return;
|
|
159
|
-
let o = i >>>
|
|
159
|
+
let o = i >>> t, s = o >>> 2;
|
|
160
160
|
if (i = Atomics.load(a, s + C), Atomics.load(a, s + w)) continue;
|
|
161
161
|
let c = a.buffer, l = s + w;
|
|
162
162
|
yield {
|
|
@@ -186,18 +186,17 @@ var h = 7, g = 2, _ = g * Uint32Array.BYTES_PER_ELEMENT, v = 0, y = 1, b = 2, x
|
|
|
186
186
|
return m(this.cachedType, e, n, this.cachedDataLength);
|
|
187
187
|
}
|
|
188
188
|
free() {
|
|
189
|
-
let { bufferPosition:
|
|
190
|
-
for (;
|
|
191
|
-
let
|
|
192
|
-
bufferPosition:
|
|
193
|
-
bufferByteOffset:
|
|
189
|
+
let { bufferPosition: n, bufferByteOffset: r } = t(this.firstBlock.data, v, this.positionBits);
|
|
190
|
+
for (; r;) {
|
|
191
|
+
let i = new e(this.memory, {
|
|
192
|
+
bufferPosition: n,
|
|
193
|
+
bufferByteOffset: r
|
|
194
194
|
});
|
|
195
|
-
({bufferPosition:
|
|
195
|
+
({bufferPosition: n, bufferByteOffset: r} = t(i.data, C, this.positionBits)), this.onDelete && !Atomics.load(i.data, w) && this.onDelete(this.getDataBlock(i.data.buffer, i.data.byteOffset)), i.free();
|
|
196
196
|
}
|
|
197
197
|
this.firstBlock.free();
|
|
198
198
|
}
|
|
199
199
|
};
|
|
200
|
-
//#endregion
|
|
201
200
|
export { E as default };
|
|
202
201
|
|
|
203
202
|
//# sourceMappingURL=shared-list.js.map
|