@daneren2005/shared-memory-objects 1.1.0 → 1.2.0
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 +78 -55
- package/dist/{src/allocated-memory.d.ts → allocated-memory.d.ts} +5 -4
- package/dist/allocated-memory.js +44 -37
- package/dist/allocated-memory.js.map +1 -1
- package/dist/{src/cached-item-list.d.ts → cached-item-list.d.ts} +3 -3
- package/dist/cached-item-list.js +70 -75
- package/dist/cached-item-list.js.map +1 -1
- package/dist/constant-string.d.ts +15 -0
- package/dist/constant-string.js +67 -0
- package/dist/constant-string.js.map +1 -0
- package/dist/interfaces/pow2.js +0 -2
- package/dist/interfaces/typed-array-constructor.js +0 -2
- package/dist/interfaces/typed-array.js +0 -2
- package/dist/{src/local-pool.d.ts → local-pool.d.ts} +2 -2
- package/dist/local-pool.js +89 -94
- package/dist/local-pool.js.map +1 -1
- package/dist/lock/read-write-lock.js +15 -21
- package/dist/lock/read-write-lock.js.map +1 -1
- package/dist/lock/simple-lock.js +9 -12
- package/dist/lock/simple-lock.js.map +1 -1
- package/dist/{src/memory-buffer.d.ts → memory-buffer.d.ts} +4 -4
- package/dist/memory-buffer.js +266 -326
- package/dist/memory-buffer.js.map +1 -1
- package/dist/{src/memory-heap.d.ts → memory-heap.d.ts} +2 -2
- package/dist/memory-heap.js +95 -115
- package/dist/memory-heap.js.map +1 -1
- package/dist/{src/serialize-object.d.ts → serialize-object.d.ts} +2 -2
- package/dist/serialize-object.js +43 -55
- package/dist/serialize-object.js.map +1 -1
- package/dist/{src/shared-list.d.ts → shared-list.d.ts} +3 -3
- package/dist/shared-list.js +124 -164
- package/dist/shared-list.js.map +1 -1
- package/dist/{src/shared-map.d.ts → shared-map.d.ts} +2 -2
- package/dist/shared-map.js +102 -138
- package/dist/shared-map.js.map +1 -1
- package/dist/{src/shared-pointer-list.d.ts → shared-pointer-list.d.ts} +3 -3
- package/dist/shared-pointer-list.js +45 -48
- package/dist/shared-pointer-list.js.map +1 -1
- package/dist/{src/shared-pool.d.ts → shared-pool.d.ts} +11 -8
- package/dist/shared-pool.js +144 -164
- package/dist/shared-pool.js.map +1 -1
- package/dist/shared-stack.d.ts +46 -0
- package/dist/shared-stack.js +144 -0
- package/dist/shared-stack.js.map +1 -0
- package/dist/{src/shared-string.d.ts → shared-string.d.ts} +2 -2
- package/dist/shared-string.js +72 -78
- package/dist/shared-string.js.map +1 -1
- package/dist/{src/shared-vector.d.ts → shared-vector.d.ts} +4 -4
- package/dist/shared-vector.js +146 -164
- package/dist/shared-vector.js.map +1 -1
- package/dist/utils/16-from-32-array.js +14 -16
- package/dist/utils/16-from-32-array.js.map +1 -1
- package/dist/utils/16-from-64-array.js +15 -10
- package/dist/utils/16-from-64-array.js.map +1 -1
- package/dist/utils/atomic-math.js +30 -32
- package/dist/utils/atomic-math.js.map +1 -1
- package/dist/utils/float32-atomics.js +18 -22
- package/dist/utils/float32-atomics.js.map +1 -1
- package/dist/utils/float64-atomics.js +18 -22
- package/dist/utils/float64-atomics.js.map +1 -1
- package/dist/utils/pointer.js +34 -44
- package/dist/utils/pointer.js.map +1 -1
- package/dist/{src/utils → utils}/typedarray.d.ts +47 -47
- package/dist/utils/typedarray.js +36 -43
- package/dist/utils/typedarray.js.map +1 -1
- package/package.json +22 -22
- package/dist/interfaces/pow2.js.map +0 -1
- package/dist/interfaces/typed-array-constructor.js.map +0 -1
- package/dist/interfaces/typed-array.js.map +0 -1
- /package/dist/{src/interfaces → interfaces}/pow2.d.ts +0 -0
- /package/dist/{src/interfaces → interfaces}/typed-array-constructor.d.ts +0 -0
- /package/dist/{src/interfaces → interfaces}/typed-array.d.ts +0 -0
- /package/dist/{src/lock → lock}/read-write-lock.d.ts +0 -0
- /package/dist/{src/lock → lock}/simple-lock.d.ts +0 -0
- /package/dist/{src/utils → utils}/16-from-32-array.d.ts +0 -0
- /package/dist/{src/utils → utils}/16-from-64-array.d.ts +0 -0
- /package/dist/{src/utils → utils}/atomic-math.d.ts +0 -0
- /package/dist/{src/utils → utils}/float32-atomics.d.ts +0 -0
- /package/dist/{src/utils → utils}/float64-atomics.d.ts +0 -0
- /package/dist/{src/utils → utils}/pointer.d.ts +0 -0
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@ A library to try to make making a multi-threaded game in Javascript possible. T
|
|
|
3
3
|
|
|
4
4
|
A demo can be found at https://daneren2005.github.io/ecs-sharedarraybuffer-playground/#/shared-memory-objects
|
|
5
5
|
The code is at https://github.com/daneren2005/ecs-sharedarraybuffer-playground/tree/dev/src/shared-memory-objects
|
|
6
|
+
This project is used as a base for an ECS framework at github.com/daneren2005/shared-memory-ecs
|
|
6
7
|
|
|
7
8
|
## Basics
|
|
8
9
|
The core of this package is the MemoryHeap. You should usually just have a single heap that is shared between all of your different threads. Each heap can have multiple MemoryBuffers. By default each buffer is only 8KB but it can be configured up to 1MB, and you can have up to 4k buffers for a total of 4GB. When you allocate memory, if there is not enough space it will allocate another buffers automatically. When allocating memory, you will get a AllocatedMemory object that is a wrapper around the allocated memory by calling `heap.allocUI32({count of 32 bit numbers})`. By default AllocatedMemory is backed by a Uint32Array but you can get any type of array from `AllocatedMemory.getArray(Int32Array);`.
|
|
@@ -61,17 +62,21 @@ let secondList = new SharedList(memory, mainList.getSharedMemory());
|
|
|
61
62
|
- SharedMap - growable hash map
|
|
62
63
|
- LocalPool - stable indexed data with a recycled pool that can only be pushed/deleted from main thread but can pass TypedArrays to other threads to operate on
|
|
63
64
|
- SharedPool - stable indexed data with a recycled pool and maximum internal array sizes
|
|
65
|
+
- SharedStack - push/pop with exponentially growing internal segments.
|
|
64
66
|
- SharedString
|
|
67
|
+
- ConstantString - an immutable SharedString: the value is written once and never changes, so it drops the lock word and all of SharedString's read/write locking
|
|
65
68
|
|
|
66
69
|
## Thread Safety
|
|
67
70
|
- Memory allocations is thread safe as long as it does not need to create a new buffer. Right now that can only be done from the main thread.
|
|
68
|
-
-
|
|
71
|
+
- SharedPool and SharedStack are thread safe
|
|
72
|
+
- SharedList, SharedVector, and SharedMap are *not* thread safe.
|
|
69
73
|
- SharedString is thread safe with a lock on read/write with a cached version of the string so it doesn't need to lock after the first read unless the string has changed.
|
|
74
|
+
- ConstantString is safe to read from any thread without a lock precisely because it is never written after construction
|
|
70
75
|
|
|
71
76
|
## TODO
|
|
72
77
|
- Make creating new buffers from allocations possible from multiple threads
|
|
73
78
|
- Make data structures thread safe
|
|
74
|
-
-
|
|
79
|
+
- Make map structure that isn't so slow as to be useless
|
|
75
80
|
|
|
76
81
|
## Performance
|
|
77
82
|
The tl;dr is that none of these data structures are close to what you can get by just using native data structures, but I wasn't expecting them to be with their overhead.
|
|
@@ -81,87 +86,105 @@ Since indexed access is about 1/4 the speed of just using a native JS array, the
|
|
|
81
86
|
|
|
82
87
|
Shared Data Structures: 10000 iterations
|
|
83
88
|
```
|
|
84
|
-
name
|
|
85
|
-
shared list
|
|
86
|
-
shared vector
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
90
|
+
shared list 755.39 0.7416 2.0011 1.3238 1.5941 1.9200 1.9620 2.0011 ±2.47% 378
|
|
91
|
+
shared vector 1,735.74 0.3005 2.0113 0.5761 0.6570 0.9432 1.0866 2.0113 ±1.75% 869
|
|
92
|
+
shared vector:getCurrentArray() 29,243.46 0.0316 0.2897 0.0342 0.0339 0.0463 0.0516 0.0921 ±0.22% 14622
|
|
93
|
+
local pool 1,590.94 0.3345 1.1394 0.6286 0.7300 0.9928 1.0538 1.1394 ±1.73% 796
|
|
94
|
+
shared pool 1,529.85 0.3597 1.2081 0.6537 0.7537 1.0264 1.0463 1.2081 ±1.66% 765
|
|
95
|
+
native array 212,637.57 0.0022 0.3723 0.0047 0.0056 0.0084 0.0090 0.0218 ±0.36% 106319
|
|
90
96
|
|
|
91
97
|
native array
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
7.27x faster than shared vector:getCurrentArray()
|
|
99
|
+
122.51x faster than shared vector
|
|
100
|
+
133.65x faster than local pool
|
|
101
|
+
138.99x faster than shared pool
|
|
102
|
+
281.50x faster than shared list
|
|
96
103
|
```
|
|
97
104
|
|
|
98
105
|
Shared Data Structures: 1000 indexed locations
|
|
99
106
|
```
|
|
100
|
-
name
|
|
101
|
-
shared vector
|
|
102
|
-
local pool
|
|
103
|
-
shared pool
|
|
104
|
-
native array
|
|
107
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
108
|
+
shared vector 20,541.58 0.0276 0.3767 0.0487 0.0567 0.0723 0.0787 0.2623 ±0.61% 10271
|
|
109
|
+
local pool 56,652.29 0.0100 0.3999 0.0177 0.0196 0.0284 0.0366 0.2630 ±0.73% 28327
|
|
110
|
+
shared pool 22,493.94 0.0257 0.4569 0.0445 0.0531 0.0680 0.0752 0.2056 ±0.63% 11248
|
|
111
|
+
native array 78,307.78 0.0076 0.3687 0.0128 0.0145 0.0196 0.0277 0.1941 ±0.66% 39154
|
|
105
112
|
|
|
106
113
|
native array
|
|
107
|
-
1.
|
|
108
|
-
3.
|
|
109
|
-
|
|
114
|
+
1.38x faster than local pool
|
|
115
|
+
3.48x faster than shared pool
|
|
116
|
+
3.81x faster than shared vector
|
|
110
117
|
```
|
|
111
118
|
|
|
112
119
|
Shared Data Structures: 1000 inserts
|
|
113
120
|
```
|
|
114
|
-
name hz min
|
|
115
|
-
shared list 1,
|
|
116
|
-
shared
|
|
117
|
-
shared vector
|
|
118
|
-
shared
|
|
119
|
-
local pool
|
|
120
|
-
shared pool
|
|
121
|
-
shared pool with already deleted elements 13,
|
|
122
|
-
native array
|
|
121
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
122
|
+
shared list 1,272.17 0.4398 1.3941 0.7861 0.9512 1.1298 1.1923 1.3941 ±1.72% 637
|
|
123
|
+
shared vector 9,683.24 0.0540 0.6074 0.1033 0.1197 0.1526 0.1682 0.4297 ±0.82% 4842
|
|
124
|
+
shared vector with correct amount initialized 14,788.92 0.0375 0.4177 0.0676 0.0821 0.1074 0.1267 0.3625 ±0.77% 7395
|
|
125
|
+
shared stack 11,462.41 0.0455 0.6411 0.0872 0.1002 0.1331 0.2250 0.3797 ±0.84% 5732
|
|
126
|
+
local pool 29,158.47 0.0177 0.4517 0.0343 0.0395 0.0555 0.0632 0.2701 ±0.65% 14580
|
|
127
|
+
shared pool 12,844.76 0.0429 0.4365 0.0779 0.0957 0.1330 0.1678 0.3488 ±0.82% 6423
|
|
128
|
+
shared pool with already deleted elements 13,185.21 0.0429 0.4298 0.0758 0.0876 0.1115 0.1737 0.3632 ±0.78% 6593
|
|
129
|
+
native array 63,492.15 0.0090 0.4731 0.0157 0.0172 0.0280 0.0373 0.2477 ±0.88% 31747
|
|
123
130
|
|
|
124
131
|
native array
|
|
125
|
-
2.
|
|
126
|
-
4.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
2.18x faster than local pool
|
|
133
|
+
4.29x faster than shared vector with correct amount initialized
|
|
134
|
+
4.82x faster than shared pool with already deleted elements
|
|
135
|
+
4.94x faster than shared pool
|
|
136
|
+
5.54x faster than shared stack
|
|
137
|
+
6.56x faster than shared vector
|
|
138
|
+
49.91x faster than shared list
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Shared Data Structures: 1000 deletes end element
|
|
142
|
+
```
|
|
143
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
144
|
+
shared list 151.97 4.6282 7.9438 6.5802 7.2367 7.9438 7.9438 7.9438 ±2.80% 76
|
|
145
|
+
shared vector 15,976.11 0.0322 0.4207 0.0626 0.0747 0.1032 0.3006 0.3641 ±1.00% 7989
|
|
146
|
+
shared stack 19,098.35 0.0294 0.3758 0.0524 0.0614 0.0794 0.0952 0.3304 ±0.74% 9550
|
|
147
|
+
shared pool 15,707.23 0.0354 0.4088 0.0637 0.0754 0.0953 0.1056 0.3452 ±0.73% 7854
|
|
148
|
+
native array 717,416.85 0.0009 0.2655 0.0014 0.0016 0.0022 0.0025 0.0092 ±0.24% 358709
|
|
149
|
+
|
|
150
|
+
native array
|
|
151
|
+
37.56x faster than shared stack
|
|
152
|
+
44.91x faster than shared vector
|
|
153
|
+
45.67x faster than shared pool
|
|
154
|
+
4720.76x faster than shared list
|
|
132
155
|
```
|
|
133
156
|
|
|
134
157
|
Shared Data Structures: 1000 deletes random element
|
|
135
158
|
NOTE: Local pool is faster than native because array slice is slower than push/pop to a native recycle array
|
|
136
159
|
```
|
|
137
|
-
name hz min
|
|
138
|
-
shared list
|
|
139
|
-
shared vector
|
|
140
|
-
local pool
|
|
141
|
-
shared pool
|
|
142
|
-
native array
|
|
160
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
161
|
+
shared list 9.6443 97.5153 111.98 103.69 107.47 111.98 111.98 111.98 ±3.26% 10
|
|
162
|
+
shared vector 313.84 2.7000 3.7852 3.1863 3.3988 3.7169 3.7852 3.7852 ±1.25% 157
|
|
163
|
+
local pool 32,625.26 0.0162 0.4183 0.0307 0.0336 0.0510 0.2434 0.3195 ±1.05% 16313
|
|
164
|
+
shared pool 8,120.56 0.0656 0.8481 0.1231 0.1427 0.1786 0.2318 0.4631 ±0.94% 4061
|
|
165
|
+
native array 7,462.53 0.0905 0.3646 0.1340 0.1527 0.1772 0.1888 0.2701 ±0.60% 3732
|
|
143
166
|
|
|
144
167
|
local pool
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
168
|
+
4.02x faster than shared pool
|
|
169
|
+
4.37x faster than native array
|
|
170
|
+
103.96x faster than shared vector
|
|
171
|
+
3382.86x faster than shared list
|
|
149
172
|
```
|
|
150
173
|
|
|
151
174
|
Shared Data Structures: 1000 insert and deleting random elements
|
|
152
175
|
```
|
|
153
176
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
154
|
-
shared list
|
|
155
|
-
shared vector
|
|
156
|
-
local pool
|
|
157
|
-
shared pool 5,
|
|
158
|
-
native array
|
|
177
|
+
shared list 14.1602 65.0318 77.6125 70.6203 71.9693 77.6125 77.6125 77.6125 ±3.81% 10
|
|
178
|
+
shared vector 525.78 1.1896 2.5440 1.9019 2.2080 2.4257 2.4653 2.5440 ±2.11% 264
|
|
179
|
+
local pool 13,953.14 0.0442 0.4062 0.0717 0.0783 0.1249 0.3229 0.3712 ±0.90% 6977
|
|
180
|
+
shared pool 5,439.53 0.1048 0.6860 0.1838 0.2188 0.3715 0.4840 0.5319 ±1.10% 2720
|
|
181
|
+
native array 7,400.28 0.0844 0.5230 0.1351 0.1494 0.2955 0.4118 0.4543 ±0.88% 3701
|
|
159
182
|
|
|
160
183
|
local pool
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
184
|
+
1.89x faster than native array
|
|
185
|
+
2.57x faster than shared pool
|
|
186
|
+
26.54x faster than shared vector
|
|
187
|
+
985.37x faster than shared list
|
|
165
188
|
```
|
|
166
189
|
|
|
167
190
|
## Credit
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { TypedArray } from './interfaces/typed-array';
|
|
2
|
-
import { TypedArrayConstructor } from './interfaces/typed-array-constructor';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import type { TypedArray } from './interfaces/typed-array';
|
|
2
|
+
import type { TypedArrayConstructor } from './interfaces/typed-array-constructor';
|
|
3
|
+
import type MemoryBuffer from './memory-buffer';
|
|
4
|
+
import type MemoryHeap from './memory-heap';
|
|
5
5
|
export default class AllocatedMemory {
|
|
6
6
|
private readonly memory;
|
|
7
7
|
readonly bufferPosition: number;
|
|
@@ -11,6 +11,7 @@ export default class AllocatedMemory {
|
|
|
11
11
|
data: Uint32Array;
|
|
12
12
|
constructor(memory: MemoryHeap, config: AllocatedMemoryConfig | SharedAllocatedMemory);
|
|
13
13
|
getArray<T extends TypedArray>(type: TypedArrayConstructor<T>, offset: number, length: number): T;
|
|
14
|
+
getSubAllocation(offset: number, length: number): AllocatedMemory;
|
|
14
15
|
getArrayMemory(offset: number, length: number): SharedAllocatedMemory;
|
|
15
16
|
free(): void;
|
|
16
17
|
getSharedMemory(): SharedAllocatedMemory;
|
package/dist/allocated-memory.js
CHANGED
|
@@ -1,38 +1,45 @@
|
|
|
1
|
-
import { createPointer as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
1
|
+
import { createPointer as e } from "./utils/pointer.js";
|
|
2
|
+
//#region src/allocated-memory.ts
|
|
3
|
+
var t = class t {
|
|
4
|
+
memory;
|
|
5
|
+
bufferPosition;
|
|
6
|
+
get bufferByteOffset() {
|
|
7
|
+
return this.data.byteOffset;
|
|
8
|
+
}
|
|
9
|
+
get pointer() {
|
|
10
|
+
return e(this.bufferPosition, this.bufferByteOffset);
|
|
11
|
+
}
|
|
12
|
+
buffer;
|
|
13
|
+
data;
|
|
14
|
+
constructor(e, t) {
|
|
15
|
+
this.memory = e, "buffer" in t ? (this.data = t.data, this.buffer = t.buffer, this.bufferPosition = this.memory.buffers.indexOf(t.buffer)) : (this.bufferPosition = t.bufferPosition, this.buffer = e.buffers[t.bufferPosition], this.data = new Uint32Array(this.buffer.buf, t.bufferByteOffset));
|
|
16
|
+
}
|
|
17
|
+
getArray(e, t, n) {
|
|
18
|
+
return new e(this.data.buffer, this.data.byteOffset + t * e.BYTES_PER_ELEMENT, n);
|
|
19
|
+
}
|
|
20
|
+
getSubAllocation(e, n) {
|
|
21
|
+
return new t(this.memory, {
|
|
22
|
+
data: new Uint32Array(this.data.buffer, this.bufferByteOffset + e * Uint32Array.BYTES_PER_ELEMENT, n),
|
|
23
|
+
buffer: this.buffer
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
getArrayMemory(e, t) {
|
|
27
|
+
return {
|
|
28
|
+
bufferPosition: this.bufferPosition,
|
|
29
|
+
bufferByteOffset: this.bufferByteOffset + e * this.data.BYTES_PER_ELEMENT
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
free() {
|
|
33
|
+
this.buffer.free(this.data.byteOffset);
|
|
34
|
+
}
|
|
35
|
+
getSharedMemory() {
|
|
36
|
+
return {
|
|
37
|
+
bufferPosition: this.bufferPosition,
|
|
38
|
+
bufferByteOffset: this.bufferByteOffset
|
|
39
|
+
};
|
|
40
|
+
}
|
|
37
41
|
};
|
|
38
|
-
//#
|
|
42
|
+
//#endregion
|
|
43
|
+
export { t as default };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=allocated-memory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allocated-memory.js","sources":["../src/allocated-memory.ts"],"sourcesContent":["import type { TypedArray } from './interfaces/typed-array';\nimport type { TypedArrayConstructor } from './interfaces/typed-array-constructor';\nimport type MemoryBuffer from './memory-buffer';\nimport type MemoryHeap from './memory-heap';\nimport { createPointer } from './utils/pointer';\n\nexport default class AllocatedMemory {\n\tprivate readonly memory: MemoryHeap;\n\n\treadonly bufferPosition: number;\n\tget bufferByteOffset(): number {\n\t\treturn this.data.byteOffset;\n\t}\n\tget pointer(): number {\n\t\treturn createPointer(this.bufferPosition, this.bufferByteOffset);\n\t}\n\tprivate buffer: MemoryBuffer;\n\tdata: Uint32Array;\n\n\tconstructor(memory: MemoryHeap, config: AllocatedMemoryConfig | SharedAllocatedMemory) {\n\t\tthis.memory = memory;\n\n\t\tif('buffer' in config) {\n\t\t\tthis.data = config.data;\n\t\t\tthis.buffer = config.buffer;\n\t\t\tthis.bufferPosition = this.memory.buffers.indexOf(config.buffer);\n\t\t} else {\n\t\t\tthis.bufferPosition = config.bufferPosition;\n\t\t\tthis.buffer = memory.buffers[config.bufferPosition];\n\n\t\t\t// Making sure these are the correct size is slow but in dev we want to make sure we aren't allowing to go out of bounds\n\t\t\tif(import.meta.env.MODE === 'production') {\n\t\t\t\tthis.data = new Uint32Array(this.buffer.buf, config.bufferByteOffset);\n\t\t\t} else {\n\t\t\t\tthis.data = new Uint32Array(this.buffer.buf, config.bufferByteOffset, this.buffer.lengthOf(config.bufferByteOffset));\n\t\t\t}\n\t\t}\n\t}\n\n\tgetArray<T extends TypedArray>(type: TypedArrayConstructor<T>, offset: number, length: number): T {\n\t\tif(import.meta.env.MODE === 'development' || import.meta.env.MODE === 'test') {\n\t\t\tif((offset + length) * type.BYTES_PER_ELEMENT > this.data.byteLength) {\n\t\t\t\tconst message =
|
|
1
|
+
{"version":3,"file":"allocated-memory.js","names":[],"sources":["../src/allocated-memory.ts"],"sourcesContent":["import type { TypedArray } from './interfaces/typed-array';\nimport type { TypedArrayConstructor } from './interfaces/typed-array-constructor';\nimport type MemoryBuffer from './memory-buffer';\nimport type MemoryHeap from './memory-heap';\nimport { createPointer } from './utils/pointer';\n\nexport default class AllocatedMemory {\n\tprivate readonly memory: MemoryHeap;\n\n\treadonly bufferPosition: number;\n\tget bufferByteOffset(): number {\n\t\treturn this.data.byteOffset;\n\t}\n\tget pointer(): number {\n\t\treturn createPointer(this.bufferPosition, this.bufferByteOffset);\n\t}\n\tprivate buffer: MemoryBuffer;\n\tdata: Uint32Array;\n\n\tconstructor(memory: MemoryHeap, config: AllocatedMemoryConfig | SharedAllocatedMemory) {\n\t\tthis.memory = memory;\n\n\t\tif('buffer' in config) {\n\t\t\tthis.data = config.data;\n\t\t\tthis.buffer = config.buffer;\n\t\t\tthis.bufferPosition = this.memory.buffers.indexOf(config.buffer);\n\t\t} else {\n\t\t\tthis.bufferPosition = config.bufferPosition;\n\t\t\tthis.buffer = memory.buffers[config.bufferPosition];\n\n\t\t\t// Making sure these are the correct size is slow but in dev we want to make sure we aren't allowing to go out of bounds\n\t\t\tif(import.meta.env.MODE === 'production') {\n\t\t\t\tthis.data = new Uint32Array(this.buffer.buf, config.bufferByteOffset);\n\t\t\t} else {\n\t\t\t\tthis.data = new Uint32Array(this.buffer.buf, config.bufferByteOffset, this.buffer.lengthOf(config.bufferByteOffset));\n\t\t\t}\n\t\t}\n\t}\n\n\tgetArray<T extends TypedArray>(type: TypedArrayConstructor<T>, offset: number, length: number): T {\n\t\tif(import.meta.env.MODE === 'development' || import.meta.env.MODE === 'test') {\n\t\t\tif((offset + length) * type.BYTES_PER_ELEMENT > this.data.byteLength) {\n\t\t\t\tconst message = 'Trying to grab more memory from AllocatedMemory.getArray then we have: '\n\t\t\t\t\t+ `${offset * type.BYTES_PER_ELEMENT} + ${length * type.BYTES_PER_ELEMENT} > ${this.data.byteLength}`;\n\t\t\t\tif(import.meta.env.MODE === 'test') {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(message);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn new type(this.data.buffer, this.data.byteOffset + offset * type.BYTES_PER_ELEMENT, length);\n\t}\n\t// A child AllocatedMemory over a slice of this block, sharing the same buffer. Built through the {data, buffer} path\n\t// (same as a fresh allocUI32) so callers stay on the cheap, monomorphic construction branch instead of re-resolving a\n\t// pointer. Used to inline sub-structures (e.g. SharedPool's stacks) inside one contiguous allocation.\n\tgetSubAllocation(offset: number, length: number): AllocatedMemory {\n\t\treturn new AllocatedMemory(this.memory, {\n\t\t\tdata: new Uint32Array(this.data.buffer, this.bufferByteOffset + offset * Uint32Array.BYTES_PER_ELEMENT, length),\n\t\t\tbuffer: this.buffer,\n\t\t});\n\t}\n\n\tgetArrayMemory(offset: number, length: number): SharedAllocatedMemory {\n\t\tif(import.meta.env.MODE === 'development') {\n\t\t\tif(offset + length > this.data.length) {\n\t\t\t\tconsole.warn(`Trying to grab more memory from AllocatedMemory.getArrayMemory then we have: ${offset} + ${length} > ${this.data.length}`);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tbufferPosition: this.bufferPosition,\n\t\t\tbufferByteOffset: this.bufferByteOffset + offset * this.data.BYTES_PER_ELEMENT,\n\t\t};\n\t}\n\n\tfree() {\n\t\t// NOTE: From worker thread you can't pass the array, you have to pass an explicit address to free\n\t\tthis.buffer.free(this.data.byteOffset);\n\t}\n\n\tgetSharedMemory(): SharedAllocatedMemory {\n\t\treturn {\n\t\t\tbufferPosition: this.bufferPosition,\n\t\t\tbufferByteOffset: this.bufferByteOffset,\n\t\t};\n\t}\n}\n\ninterface AllocatedMemoryConfig {\n\tdata: Uint32Array\n\tbuffer: MemoryBuffer\n}\n\ninterface SharedAllocatedMemory {\n\tbufferPosition: number\n\tbufferByteOffset: number\n}\nexport type { SharedAllocatedMemory };"],"mappings":";;AAMA,IAAqB,IAArB,MAAqB,EAAgB;CACpC;CAEA;CACA,IAAI,mBAA2B;EAC9B,OAAO,KAAK,KAAK;CAClB;CACA,IAAI,UAAkB;EACrB,OAAO,EAAc,KAAK,gBAAgB,KAAK,gBAAgB;CAChE;CACA;CACA;CAEA,YAAY,GAAoB,GAAuD;EAGtF,AAFA,KAAK,SAAS,GAEX,YAAY,KACd,KAAK,OAAO,EAAO,MACnB,KAAK,SAAS,EAAO,QACrB,KAAK,iBAAiB,KAAK,OAAO,QAAQ,QAAQ,EAAO,MAAM,MAE/D,KAAK,iBAAiB,EAAO,gBAC7B,KAAK,SAAS,EAAO,QAAQ,EAAO,iBAInC,KAAK,OAAO,IAAI,YAAY,KAAK,OAAO,KAAK,EAAO,gBAAgB;CAKvE;CAEA,SAA+B,GAAgC,GAAgB,GAAmB;EAajG,OAAO,IAAI,EAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,aAAa,IAAS,EAAK,mBAAmB,CAAM;CACjG;CAIA,iBAAiB,GAAgB,GAAiC;EACjE,OAAO,IAAI,EAAgB,KAAK,QAAQ;GACvC,MAAM,IAAI,YAAY,KAAK,KAAK,QAAQ,KAAK,mBAAmB,IAAS,YAAY,mBAAmB,CAAM;GAC9G,QAAQ,KAAK;EACd,CAAC;CACF;CAEA,eAAe,GAAgB,GAAuC;EAOrE,OAAO;GACN,gBAAgB,KAAK;GACrB,kBAAkB,KAAK,mBAAmB,IAAS,KAAK,KAAK;EAC9D;CACD;CAEA,OAAO;EAEN,KAAK,OAAO,KAAK,KAAK,KAAK,UAAU;CACtC;CAEA,kBAAyC;EACxC,OAAO;GACN,gBAAgB,KAAK;GACrB,kBAAkB,KAAK;EACxB;CACD;AACD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { SharedAllocatedMemory } from './allocated-memory';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import type { SharedAllocatedMemory } from './allocated-memory';
|
|
2
|
+
import type MemoryHeap from './memory-heap';
|
|
3
|
+
import SharedList, { type SharedListMemory } from './shared-list';
|
|
4
4
|
export default abstract class CachedItemList<T extends Item> implements Iterable<{
|
|
5
5
|
item: T;
|
|
6
6
|
deleteCurrent: () => void;
|
package/dist/cached-item-list.js
CHANGED
|
@@ -1,76 +1,71 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return this.list.getSharedMemory();
|
|
68
|
-
}
|
|
69
|
-
free() {
|
|
70
|
-
this.list.free(), this.cache.clear();
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
export {
|
|
74
|
-
c as default
|
|
1
|
+
import e from "./shared-list.js";
|
|
2
|
+
//#region src/cached-item-list.ts
|
|
3
|
+
var t = class {
|
|
4
|
+
static ALLOCATE_COUNT = e.ALLOCATE_COUNT;
|
|
5
|
+
heap;
|
|
6
|
+
list;
|
|
7
|
+
cache = /* @__PURE__ */ new Map();
|
|
8
|
+
constructor(t, n) {
|
|
9
|
+
this.list = n ? new e(t, n) : new e(t), this.heap = t, this.list.onDelete = (e) => {
|
|
10
|
+
let t = Atomics.load(e, 0);
|
|
11
|
+
if (t) {
|
|
12
|
+
let e = this.cache.get(t);
|
|
13
|
+
e ||= this.initItem(t), e && (e.free(), this.cache.delete(t));
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
get length() {
|
|
18
|
+
return this.list.length;
|
|
19
|
+
}
|
|
20
|
+
clear() {
|
|
21
|
+
this.list.clear(), this.cache.clear();
|
|
22
|
+
}
|
|
23
|
+
insert(e) {
|
|
24
|
+
this.list.insert(e.pointer), this.cache.set(e.pointer, e);
|
|
25
|
+
}
|
|
26
|
+
delete(e) {
|
|
27
|
+
return this.cache.delete(e.pointer), this.list.deleteValue(e.pointer);
|
|
28
|
+
}
|
|
29
|
+
getByPointer(e) {
|
|
30
|
+
let t = this.cache.get(e);
|
|
31
|
+
return t || (t = this.initItem(e), t && this.cache.set(e, t)), t;
|
|
32
|
+
}
|
|
33
|
+
*[Symbol.iterator]() {
|
|
34
|
+
let e = this.list[Symbol.iterator]();
|
|
35
|
+
for (let { data: t, deleteCurrent: n } of e) {
|
|
36
|
+
let e = Atomics.load(t, 0);
|
|
37
|
+
if (!e) continue;
|
|
38
|
+
let r = this.cache.get(e);
|
|
39
|
+
r || (r = this.initItem(e), r && this.cache.set(e, r)), r && (yield {
|
|
40
|
+
item: r,
|
|
41
|
+
deleteCurrent: n
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
forEach(e, t) {
|
|
46
|
+
for (let { item: n } of this) (!t || t(n)) && e(n);
|
|
47
|
+
}
|
|
48
|
+
find(e) {
|
|
49
|
+
for (let { item: t } of this) if (e(t)) return t;
|
|
50
|
+
}
|
|
51
|
+
filter(e) {
|
|
52
|
+
let t = [];
|
|
53
|
+
for (let { item: n } of this) e(n) && t.push(n);
|
|
54
|
+
return t;
|
|
55
|
+
}
|
|
56
|
+
map(e) {
|
|
57
|
+
let t = [];
|
|
58
|
+
for (let { item: n } of this) t.push(e(n));
|
|
59
|
+
return t;
|
|
60
|
+
}
|
|
61
|
+
getSharedMemory() {
|
|
62
|
+
return this.list.getSharedMemory();
|
|
63
|
+
}
|
|
64
|
+
free() {
|
|
65
|
+
this.list.free(), this.cache.clear();
|
|
66
|
+
}
|
|
75
67
|
};
|
|
76
|
-
//#
|
|
68
|
+
//#endregion
|
|
69
|
+
export { t as default };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=cached-item-list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cached-item-list.js","sources":["../src/cached-item-list.ts"],"sourcesContent":["import type { SharedAllocatedMemory } from './allocated-memory';\nimport type MemoryHeap from './memory-heap';\nimport SharedList, { type SharedListMemory } from './shared-list';\n\nexport default abstract class CachedItemList<T extends Item> implements Iterable<{ item: T, deleteCurrent: () => void }> {\n\tstatic readonly ALLOCATE_COUNT = SharedList.ALLOCATE_COUNT;\n\n\tprotected heap: MemoryHeap;\n\tprotected list: SharedList;\n\tprotected cache: Map<number, T> = new Map();\n\n\tconstructor(heap: MemoryHeap, config?: CachedListConfig | SharedListMemory) {\n\t\tif(config) {\n\t\t\tthis.list = new SharedList(heap, config);\n\t\t} else {\n\t\t\tthis.list = new SharedList(heap);\n\t\t}\n\t\tthis.heap = heap;\n\n\t\tthis.list.onDelete = (pointerData: Uint32Array) => {\n\t\t\tlet pointer = Atomics.load(pointerData, 0);\n\t\t\tif(pointer) {\n\t\t\t\tlet item = this.cache.get(pointer);\n\t\t\t\tif(!item) {\n\t\t\t\t\titem = this.initItem(pointer);\n\t\t\t\t}\n\n\t\t\t\tif(item) {\n\t\t\t\t\titem.free();\n\t\t\t\t\tthis.cache.delete(pointer);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tget length() {\n\t\treturn this.list.length;\n\t}\n\n\tclear() {\n\t\tthis.list.clear();\n\t\tthis.cache.clear();\n\t}\n\n\tinsert(item: T) {\n\t\tthis.list.insert(item.pointer);\n\t\tthis.cache.set(item.pointer, item);\n\t}\n\tdelete(item: T) {\n\t\tthis.cache.delete(item.pointer);\n\t\treturn this.list.deleteValue(item.pointer);\n\t}\n\n\tgetByPointer(pointer: number): T | undefined {\n\t\tlet item = this.cache.get(pointer);\n\t\tif(!item) {\n\t\t\titem = this.initItem(pointer);\n\t\t\tif(item) {\n\t\t\t\tthis.cache.set(pointer, item);\n\t\t\t}\n\t\t}\n\n\t\treturn item;\n\t}\n\tprotected abstract initItem(pointer: number): T | undefined
|
|
1
|
+
{"version":3,"file":"cached-item-list.js","names":[],"sources":["../src/cached-item-list.ts"],"sourcesContent":["import type { SharedAllocatedMemory } from './allocated-memory';\nimport type MemoryHeap from './memory-heap';\nimport SharedList, { type SharedListMemory } from './shared-list';\n\nexport default abstract class CachedItemList<T extends Item> implements Iterable<{ item: T, deleteCurrent: () => void }> {\n\tstatic readonly ALLOCATE_COUNT = SharedList.ALLOCATE_COUNT;\n\n\tprotected heap: MemoryHeap;\n\tprotected list: SharedList;\n\tprotected cache: Map<number, T> = new Map();\n\n\tconstructor(heap: MemoryHeap, config?: CachedListConfig | SharedListMemory) {\n\t\tif(config) {\n\t\t\tthis.list = new SharedList(heap, config);\n\t\t} else {\n\t\t\tthis.list = new SharedList(heap);\n\t\t}\n\t\tthis.heap = heap;\n\n\t\tthis.list.onDelete = (pointerData: Uint32Array) => {\n\t\t\tlet pointer = Atomics.load(pointerData, 0);\n\t\t\tif(pointer) {\n\t\t\t\tlet item = this.cache.get(pointer);\n\t\t\t\tif(!item) {\n\t\t\t\t\titem = this.initItem(pointer);\n\t\t\t\t}\n\n\t\t\t\tif(item) {\n\t\t\t\t\titem.free();\n\t\t\t\t\tthis.cache.delete(pointer);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tget length() {\n\t\treturn this.list.length;\n\t}\n\n\tclear() {\n\t\tthis.list.clear();\n\t\tthis.cache.clear();\n\t}\n\n\tinsert(item: T) {\n\t\tthis.list.insert(item.pointer);\n\t\tthis.cache.set(item.pointer, item);\n\t}\n\tdelete(item: T) {\n\t\tthis.cache.delete(item.pointer);\n\t\treturn this.list.deleteValue(item.pointer);\n\t}\n\n\tgetByPointer(pointer: number): T | undefined {\n\t\tlet item = this.cache.get(pointer);\n\t\tif(!item) {\n\t\t\titem = this.initItem(pointer);\n\t\t\tif(item) {\n\t\t\t\tthis.cache.set(pointer, item);\n\t\t\t}\n\t\t}\n\n\t\treturn item;\n\t}\n\tprotected abstract initItem(pointer: number): T | undefined;\n\n\t*[Symbol.iterator]() {\n\t\tlet iterator = this.list[Symbol.iterator]();\n\n\t\tfor(let { data: pointerData, deleteCurrent } of iterator) {\n\t\t\tlet pointer = Atomics.load(pointerData, 0);\n\t\t\tif(!pointer) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet item = this.cache.get(pointer);\n\t\t\tif(!item) {\n\t\t\t\titem = this.initItem(pointer);\n\t\t\t\tif(item) {\n\t\t\t\t\tthis.cache.set(pointer, item);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(item) {\n\t\t\t\tyield {\n\t\t\t\t\titem,\n\t\t\t\t\tdeleteCurrent,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\tforEach(callback: (item: T) => void, filter?: (item: T) => boolean) {\n\t\tfor(let { item } of this) {\n\t\t\tif(!filter || filter(item)) {\n\t\t\t\tcallback(item);\n\t\t\t}\n\t\t}\n\t}\n\n\tfind(callback: (item: T) => boolean): T | undefined {\n\t\tfor(let { item } of this) {\n\t\t\tif(callback(item)) {\n\t\t\t\treturn item;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\tfilter(callback: (entity: T) => boolean): Array<T> {\n\t\tlet items = [];\n\t\tfor(let { item } of this) {\n\t\t\tif(callback(item)) {\n\t\t\t\titems.push(item);\n\t\t\t}\n\t\t}\n\n\t\treturn items;\n\t}\n\tmap<X>(callback: (item: T) => X): Array<X> {\n\t\tconst array: Array<X> = [];\n\t\tfor(let { item } of this) {\n\t\t\tarray.push(callback(item));\n\t\t}\n\n\t\treturn array;\n\t}\n\n\tgetSharedMemory() {\n\t\treturn this.list.getSharedMemory();\n\t}\n\n\tfree() {\n\t\tthis.list.free();\n\t\tthis.cache.clear();\n\t}\n}\n\nexport interface CachedListConfig {\n\tinitWithBlock: SharedAllocatedMemory\n}\n\ninterface Item {\n\tpointer: number\n\tfree: () => void\n}"],"mappings":";;AAIA,IAA8B,IAA9B,MAAyH;CACxH,OAAgB,iBAAiB,EAAW;CAE5C;CACA;CACA,wBAAkC,IAAI,IAAI;CAE1C,YAAY,GAAkB,GAA8C;EAQ3E,AAPA,AAGC,KAAK,OAHH,IACU,IAAI,EAAW,GAAM,CAAM,IAE3B,IAAI,EAAW,CAAI,GAEhC,KAAK,OAAO,GAEZ,KAAK,KAAK,YAAY,MAA6B;GAClD,IAAI,IAAU,QAAQ,KAAK,GAAa,CAAC;GACzC,IAAG,GAAS;IACX,IAAI,IAAO,KAAK,MAAM,IAAI,CAAO;IAKjC,AAJA,AACC,MAAO,KAAK,SAAS,CAAO,GAG1B,MACF,EAAK,KAAK,GACV,KAAK,MAAM,OAAO,CAAO;GAE3B;EACD;CACD;CAEA,IAAI,SAAS;EACZ,OAAO,KAAK,KAAK;CAClB;CAEA,QAAQ;EAEP,AADA,KAAK,KAAK,MAAM,GAChB,KAAK,MAAM,MAAM;CAClB;CAEA,OAAO,GAAS;EAEf,AADA,KAAK,KAAK,OAAO,EAAK,OAAO,GAC7B,KAAK,MAAM,IAAI,EAAK,SAAS,CAAI;CAClC;CACA,OAAO,GAAS;EAEf,OADA,KAAK,MAAM,OAAO,EAAK,OAAO,GACvB,KAAK,KAAK,YAAY,EAAK,OAAO;CAC1C;CAEA,aAAa,GAAgC;EAC5C,IAAI,IAAO,KAAK,MAAM,IAAI,CAAO;EAQjC,OAPI,MACH,IAAO,KAAK,SAAS,CAAO,GACzB,KACF,KAAK,MAAM,IAAI,GAAS,CAAI,IAIvB;CACR;CAGA,EAAE,OAAO,YAAY;EACpB,IAAI,IAAW,KAAK,KAAK,OAAO,SAAS,CAAC;EAE1C,KAAI,IAAI,EAAE,MAAM,GAAa,sBAAmB,GAAU;GACzD,IAAI,IAAU,QAAQ,KAAK,GAAa,CAAC;GACzC,IAAG,CAAC,GACH;GAGD,IAAI,IAAO,KAAK,MAAM,IAAI,CAAO;GAQjC,AAPI,MACH,IAAO,KAAK,SAAS,CAAO,GACzB,KACF,KAAK,MAAM,IAAI,GAAS,CAAI,IAI3B,MACF,MAAM;IACL;IACA;GACD;EAEF;CACD;CACA,QAAQ,GAA6B,GAA+B;EACnE,KAAI,IAAI,EAAE,aAAU,MACnB,CAAG,CAAC,KAAU,EAAO,CAAI,MACxB,EAAS,CAAI;CAGhB;CAEA,KAAK,GAA+C;EACnD,KAAI,IAAI,EAAE,aAAU,MACnB,IAAG,EAAS,CAAI,GACf,OAAO;CAKV;CACA,OAAO,GAA4C;EAClD,IAAI,IAAQ,CAAC;EACb,KAAI,IAAI,EAAE,aAAU,MACnB,AAAG,EAAS,CAAI,KACf,EAAM,KAAK,CAAI;EAIjB,OAAO;CACR;CACA,IAAO,GAAoC;EAC1C,IAAM,IAAkB,CAAC;EACzB,KAAI,IAAI,EAAE,aAAU,MACnB,EAAM,KAAK,EAAS,CAAI,CAAC;EAG1B,OAAO;CACR;CAEA,kBAAkB;EACjB,OAAO,KAAK,KAAK,gBAAgB;CAClC;CAEA,OAAO;EAEN,AADA,KAAK,KAAK,KAAK,GACf,KAAK,MAAM,MAAM;CAClB;AACD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { SharedAllocatedMemory } from './allocated-memory';
|
|
2
|
+
import type MemoryHeap from './memory-heap';
|
|
3
|
+
export default class ConstantString {
|
|
4
|
+
static readonly ALLOCATE_COUNT = 3;
|
|
5
|
+
private memory;
|
|
6
|
+
private allocatedMemory;
|
|
7
|
+
readonly value: string;
|
|
8
|
+
constructor(memory: MemoryHeap, value: string | SharedAllocatedMemory);
|
|
9
|
+
private writeString;
|
|
10
|
+
private readString;
|
|
11
|
+
private createString;
|
|
12
|
+
getSharedMemory(): SharedAllocatedMemory;
|
|
13
|
+
get pointer(): number;
|
|
14
|
+
free(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { getPointer as e, loadRawPointer as t, storeRawPointer as n } from "./utils/pointer.js";
|
|
2
|
+
import r from "./allocated-memory.js";
|
|
3
|
+
//#region src/constant-string.ts
|
|
4
|
+
var i = {
|
|
5
|
+
1: Uint8Array,
|
|
6
|
+
2: Uint16Array
|
|
7
|
+
}, a = 0, o = 1, s = 2, c = class c {
|
|
8
|
+
static ALLOCATE_COUNT = 3;
|
|
9
|
+
memory;
|
|
10
|
+
allocatedMemory;
|
|
11
|
+
value;
|
|
12
|
+
constructor(e, t) {
|
|
13
|
+
this.memory = e, typeof t == "string" ? (this.allocatedMemory = this.memory.allocUI32(c.ALLOCATE_COUNT), this.writeString(t), this.value = t) : (this.allocatedMemory = new r(e, t), this.value = this.readString());
|
|
14
|
+
}
|
|
15
|
+
writeString(e) {
|
|
16
|
+
let t = this.createString(e);
|
|
17
|
+
n(this.allocatedMemory.data, a, t.pointer), Atomics.store(this.allocatedMemory.data, o, e.length), Atomics.store(this.allocatedMemory.data, s, t.charType);
|
|
18
|
+
}
|
|
19
|
+
readString() {
|
|
20
|
+
let n = t(this.allocatedMemory.data, a);
|
|
21
|
+
if (n === 0) return "";
|
|
22
|
+
let { bufferPosition: r, bufferByteOffset: c } = e(n), u = i[Atomics.load(this.allocatedMemory.data, s)], d = Atomics.load(this.allocatedMemory.data, o);
|
|
23
|
+
return l(new u(this.memory.buffers[r].buf, c, d));
|
|
24
|
+
}
|
|
25
|
+
createString(e) {
|
|
26
|
+
if (e === "") return {
|
|
27
|
+
pointer: 0,
|
|
28
|
+
charType: 1
|
|
29
|
+
};
|
|
30
|
+
let t = 0;
|
|
31
|
+
for (let n = 0; n < e.length; n++) {
|
|
32
|
+
let r = e.charCodeAt(n);
|
|
33
|
+
r > t && (t = r);
|
|
34
|
+
}
|
|
35
|
+
let n = t > 255 ? 2 : 1, r = i[n], a = this.memory.allocUI32(Math.ceil(e.length / (4 / r.BYTES_PER_ELEMENT))), o = new r(a.data.buffer, a.data.byteOffset, e.length);
|
|
36
|
+
for (let t = 0; t < e.length; t++) o[t] = e.charCodeAt(t);
|
|
37
|
+
return {
|
|
38
|
+
pointer: a.pointer,
|
|
39
|
+
charType: n
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
getSharedMemory() {
|
|
43
|
+
return this.allocatedMemory.getSharedMemory();
|
|
44
|
+
}
|
|
45
|
+
get pointer() {
|
|
46
|
+
return this.allocatedMemory.pointer;
|
|
47
|
+
}
|
|
48
|
+
free() {
|
|
49
|
+
let n = t(this.allocatedMemory.data, a);
|
|
50
|
+
if (n) {
|
|
51
|
+
let { bufferPosition: t, bufferByteOffset: r } = e(n);
|
|
52
|
+
this.memory.buffers[t].free(r);
|
|
53
|
+
}
|
|
54
|
+
this.allocatedMemory.free();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
function l(e) {
|
|
58
|
+
let t = 8192;
|
|
59
|
+
if (e.length <= t) return String.fromCharCode.apply(null, e);
|
|
60
|
+
let n = "";
|
|
61
|
+
for (let r = 0; r < e.length; r += t) n += String.fromCharCode.apply(null, e.subarray(r, r + t));
|
|
62
|
+
return n;
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { c as default };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=constant-string.js.map
|