@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.
Files changed (80) hide show
  1. package/README.md +78 -55
  2. package/dist/{src/allocated-memory.d.ts → allocated-memory.d.ts} +5 -4
  3. package/dist/allocated-memory.js +44 -37
  4. package/dist/allocated-memory.js.map +1 -1
  5. package/dist/{src/cached-item-list.d.ts → cached-item-list.d.ts} +3 -3
  6. package/dist/cached-item-list.js +70 -75
  7. package/dist/cached-item-list.js.map +1 -1
  8. package/dist/constant-string.d.ts +15 -0
  9. package/dist/constant-string.js +67 -0
  10. package/dist/constant-string.js.map +1 -0
  11. package/dist/interfaces/pow2.js +0 -2
  12. package/dist/interfaces/typed-array-constructor.js +0 -2
  13. package/dist/interfaces/typed-array.js +0 -2
  14. package/dist/{src/local-pool.d.ts → local-pool.d.ts} +2 -2
  15. package/dist/local-pool.js +89 -94
  16. package/dist/local-pool.js.map +1 -1
  17. package/dist/lock/read-write-lock.js +15 -21
  18. package/dist/lock/read-write-lock.js.map +1 -1
  19. package/dist/lock/simple-lock.js +9 -12
  20. package/dist/lock/simple-lock.js.map +1 -1
  21. package/dist/{src/memory-buffer.d.ts → memory-buffer.d.ts} +4 -4
  22. package/dist/memory-buffer.js +266 -326
  23. package/dist/memory-buffer.js.map +1 -1
  24. package/dist/{src/memory-heap.d.ts → memory-heap.d.ts} +2 -2
  25. package/dist/memory-heap.js +95 -115
  26. package/dist/memory-heap.js.map +1 -1
  27. package/dist/{src/serialize-object.d.ts → serialize-object.d.ts} +2 -2
  28. package/dist/serialize-object.js +43 -55
  29. package/dist/serialize-object.js.map +1 -1
  30. package/dist/{src/shared-list.d.ts → shared-list.d.ts} +3 -3
  31. package/dist/shared-list.js +124 -164
  32. package/dist/shared-list.js.map +1 -1
  33. package/dist/{src/shared-map.d.ts → shared-map.d.ts} +2 -2
  34. package/dist/shared-map.js +102 -138
  35. package/dist/shared-map.js.map +1 -1
  36. package/dist/{src/shared-pointer-list.d.ts → shared-pointer-list.d.ts} +3 -3
  37. package/dist/shared-pointer-list.js +45 -48
  38. package/dist/shared-pointer-list.js.map +1 -1
  39. package/dist/{src/shared-pool.d.ts → shared-pool.d.ts} +11 -8
  40. package/dist/shared-pool.js +144 -164
  41. package/dist/shared-pool.js.map +1 -1
  42. package/dist/shared-stack.d.ts +46 -0
  43. package/dist/shared-stack.js +144 -0
  44. package/dist/shared-stack.js.map +1 -0
  45. package/dist/{src/shared-string.d.ts → shared-string.d.ts} +2 -2
  46. package/dist/shared-string.js +72 -78
  47. package/dist/shared-string.js.map +1 -1
  48. package/dist/{src/shared-vector.d.ts → shared-vector.d.ts} +4 -4
  49. package/dist/shared-vector.js +146 -164
  50. package/dist/shared-vector.js.map +1 -1
  51. package/dist/utils/16-from-32-array.js +14 -16
  52. package/dist/utils/16-from-32-array.js.map +1 -1
  53. package/dist/utils/16-from-64-array.js +15 -10
  54. package/dist/utils/16-from-64-array.js.map +1 -1
  55. package/dist/utils/atomic-math.js +30 -32
  56. package/dist/utils/atomic-math.js.map +1 -1
  57. package/dist/utils/float32-atomics.js +18 -22
  58. package/dist/utils/float32-atomics.js.map +1 -1
  59. package/dist/utils/float64-atomics.js +18 -22
  60. package/dist/utils/float64-atomics.js.map +1 -1
  61. package/dist/utils/pointer.js +34 -44
  62. package/dist/utils/pointer.js.map +1 -1
  63. package/dist/{src/utils → utils}/typedarray.d.ts +47 -47
  64. package/dist/utils/typedarray.js +36 -43
  65. package/dist/utils/typedarray.js.map +1 -1
  66. package/package.json +22 -22
  67. package/dist/interfaces/pow2.js.map +0 -1
  68. package/dist/interfaces/typed-array-constructor.js.map +0 -1
  69. package/dist/interfaces/typed-array.js.map +0 -1
  70. /package/dist/{src/interfaces → interfaces}/pow2.d.ts +0 -0
  71. /package/dist/{src/interfaces → interfaces}/typed-array-constructor.d.ts +0 -0
  72. /package/dist/{src/interfaces → interfaces}/typed-array.d.ts +0 -0
  73. /package/dist/{src/lock → lock}/read-write-lock.d.ts +0 -0
  74. /package/dist/{src/lock → lock}/simple-lock.d.ts +0 -0
  75. /package/dist/{src/utils → utils}/16-from-32-array.d.ts +0 -0
  76. /package/dist/{src/utils → utils}/16-from-64-array.d.ts +0 -0
  77. /package/dist/{src/utils → utils}/atomic-math.d.ts +0 -0
  78. /package/dist/{src/utils → utils}/float32-atomics.d.ts +0 -0
  79. /package/dist/{src/utils → utils}/float64-atomics.d.ts +0 -0
  80. /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
- - SharedList, SharedVector, SharedPool, and SharedMap are all not thread safe.
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
- - Add basic thread safe object example
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 hz min max mean p75 p99 p995 p999 rme samples
85
- shared list 1,040.61 0.7898 2.1673 0.9610 1.0080 1.6299 1.7740 2.1673 ±1.49% 521
86
- shared vector 2,447.08 0.3489 0.8944 0.4086 0.4369 0.7289 0.7887 0.8457 ±1.12% 1224
87
- local pool 2,661.05 0.3266 0.9810 0.3758 0.3751 0.6516 0.7423 0.9332 ±1.05% 1331
88
- shared pool 2,052.60 0.4255 1.1583 0.4872 0.4878 0.8323 0.8735 1.0186 ±1.10% 1027
89
- native array 379,950.63 0.0021 0.1505 0.0026 0.0023 0.0062 0.0070 0.0218 ±0.28% 189976
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
- 142.78x faster than local pool
93
- 155.27x faster than shared vector
94
- 185.11x faster than shared pool
95
- 365.12x faster than shared list
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 hz min max mean p75 p99 p995 p999 rme samples
101
- shared vector 28,713.93 0.0276 1.1649 0.0348 0.0335 0.0767 0.1276 0.2245 ±0.86% 14357
102
- local pool 88,708.78 0.0099 0.2418 0.0113 0.0105 0.0192 0.0261 0.1700 ±0.62% 44369
103
- shared pool 33,795.16 0.0270 0.1868 0.0296 0.0287 0.0536 0.0631 0.1376 ±0.36% 16898
104
- native array 126,855.06 0.0072 0.2046 0.0079 0.0076 0.0129 0.0146 0.0993 ±0.42% 63428
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.43x faster than local pool
108
- 3.75x faster than shared pool
109
- 4.42x faster than shared vector
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 max mean p75 p99 p995 p999 rme samples
115
- shared list 1,989.04 0.4176 1.2361 0.5028 0.5238 0.9547 1.0934 1.2361 ±1.49% 995
116
- shared map 98.3711 8.8636 13.3231 10.1656 10.7163 13.3231 13.3231 13.3231 ±3.14% 50
117
- shared vector 15,559.65 0.0529 0.4758 0.0643 0.0609 0.1405 0.1849 0.2850 ±0.71% 7780
118
- shared vector with correct amount initialized 22,386.17 0.0372 0.3258 0.0447 0.0415 0.0968 0.1167 0.2119 ±0.61% 11194
119
- local pool 43,012.42 0.0173 0.3407 0.0232 0.0210 0.0706 0.0933 0.2009 ±0.79% 21507
120
- shared pool 9,873.77 0.0794 0.5068 0.1013 0.1013 0.2696 0.3232 0.4319 ±1.06% 4937
121
- shared pool with already deleted elements 13,396.59 0.0643 0.3341 0.0746 0.0700 0.1830 0.2322 0.2799 ±0.70% 6699
122
- native array 94,368.06 0.0084 0.4662 0.0106 0.0101 0.0236 0.0498 0.1181 ±0.61% 47186
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.19x faster than local pool
126
- 4.22x faster than shared vector with correct amount initialized
127
- 6.06x faster than shared vector
128
- 7.04x faster than shared pool with already deleted elements
129
- 9.56x faster than shared pool
130
- 47.44x faster than shared list
131
- 959.31x faster than shared map
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 max mean p75 p99 p995 p999 rme samples
138
- shared list 13.1818 68.1220 83.8157 75.8622 79.3236 83.8157 83.8157 83.8157 ±4.40% 10
139
- shared vector 387.53 2.3857 3.0819 2.5804 2.6409 3.0624 3.0819 3.0819 ±0.70% 194
140
- local pool 71,370.27 0.0105 0.5406 0.0140 0.0122 0.1055 0.1351 0.1960 ±1.07% 35686
141
- shared pool 13,049.38 0.0689 0.2990 0.0766 0.0746 0.1439 0.1681 0.2269 ±0.51% 6525
142
- native array 10,559.95 0.0827 0.2363 0.0947 0.0941 0.1532 0.1693 0.2037 ±0.45% 5281
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
- 5.47x faster than shared pool
146
- 6.76x faster than native array
147
- 184.17x faster than shared vector
148
- 5414.30x faster than shared list
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 20.5573 43.7463 57.7009 48.6445 50.4710 57.7009 57.7009 57.7009 ±5.73% 11
155
- shared vector 752.07 1.0805 2.4937 1.3297 1.3769 2.1734 2.3537 2.4937 ±1.81% 377
156
- local pool 22,453.72 0.0388 0.3417 0.0445 0.0417 0.1214 0.1574 0.2231 ±0.63% 11227
157
- shared pool 5,684.68 0.1490 1.7416 0.1759 0.1703 0.4351 0.5387 0.9790 ±1.37% 2843
158
- native array 11,030.10 0.0793 0.2980 0.0907 0.0866 0.1808 0.1976 0.2412 ±0.54% 5516
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
- 2.04x faster than native array
162
- 3.95x faster than shared pool
163
- 29.86x faster than shared vector
164
- 1092.25x faster than shared list
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 { default as MemoryBuffer } from './memory-buffer';
4
- import { default as MemoryHeap } from './memory-heap';
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;
@@ -1,38 +1,45 @@
1
- import { createPointer as r } from "./utils/pointer.js";
2
- class u {
3
- memory;
4
- bufferPosition;
5
- get bufferByteOffset() {
6
- return this.data.byteOffset;
7
- }
8
- get pointer() {
9
- return r(this.bufferPosition, this.bufferByteOffset);
10
- }
11
- buffer;
12
- data;
13
- constructor(t, e) {
14
- this.memory = t, "buffer" in e ? (this.data = e.data, this.buffer = e.buffer, this.bufferPosition = this.memory.buffers.indexOf(e.buffer)) : (this.bufferPosition = e.bufferPosition, this.buffer = t.buffers[e.bufferPosition], this.data = new Uint32Array(this.buffer.buf, e.bufferByteOffset));
15
- }
16
- getArray(t, e, f) {
17
- return new t(this.data.buffer, this.data.byteOffset + e * t.BYTES_PER_ELEMENT, f);
18
- }
19
- getArrayMemory(t, e) {
20
- return {
21
- bufferPosition: this.bufferPosition,
22
- bufferByteOffset: this.bufferByteOffset + t * this.data.BYTES_PER_ELEMENT
23
- };
24
- }
25
- free() {
26
- this.buffer.free(this.data.byteOffset);
27
- }
28
- getSharedMemory() {
29
- return {
30
- bufferPosition: this.bufferPosition,
31
- bufferByteOffset: this.bufferByteOffset
32
- };
33
- }
34
- }
35
- export {
36
- u as default
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
- //# sourceMappingURL=allocated-memory.js.map
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 = `Trying to grab more memory from AllocatedMemory.getArray then we have: ${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\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 };"],"names":["AllocatedMemory","createPointer","memory","config","type","offset","length"],"mappings":";AAMA,MAAqBA,EAAgB;AAAA,EACnB;AAAA,EAER;AAAA,EACT,IAAI,mBAA2B;AAC9B,WAAO,KAAK,KAAK;AAAA,EAClB;AAAA,EACA,IAAI,UAAkB;AACrB,WAAOC,EAAc,KAAK,gBAAgB,KAAK,gBAAgB;AAAA,EAChE;AAAA,EACQ;AAAA,EACR;AAAA,EAEA,YAAYC,GAAoBC,GAAuD;AACtF,SAAK,SAASD,GAEX,YAAYC,KACd,KAAK,OAAOA,EAAO,MACnB,KAAK,SAASA,EAAO,QACrB,KAAK,iBAAiB,KAAK,OAAO,QAAQ,QAAQA,EAAO,MAAM,MAE/D,KAAK,iBAAiBA,EAAO,gBAC7B,KAAK,SAASD,EAAO,QAAQC,EAAO,cAAc,GAIjD,KAAK,OAAO,IAAI,YAAY,KAAK,OAAO,KAAKA,EAAO,gBAAgB;AAAA,EAKvE;AAAA,EAEA,SAA+BC,GAAgCC,GAAgBC,GAAmB;AAYjG,WAAO,IAAIF,EAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,aAAaC,IAASD,EAAK,mBAAmBE,CAAM;AAAA,EACjG;AAAA,EACA,eAAeD,GAAgBC,GAAuC;AAOrE,WAAO;AAAA,MACN,gBAAgB,KAAK;AAAA,MACrB,kBAAkB,KAAK,mBAAmBD,IAAS,KAAK,KAAK;AAAA,IAAA;AAAA,EAE/D;AAAA,EAEA,OAAO;AAEN,SAAK,OAAO,KAAK,KAAK,KAAK,UAAU;AAAA,EACtC;AAAA,EAEA,kBAAyC;AACxC,WAAO;AAAA,MACN,gBAAgB,KAAK;AAAA,MACrB,kBAAkB,KAAK;AAAA,IAAA;AAAA,EAEzB;AACD;"}
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 { default as MemoryHeap } from './memory-heap';
3
- import { default as SharedList, SharedListMemory } from './shared-list';
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;
@@ -1,76 +1,71 @@
1
- import h from "./shared-list.js";
2
- class c {
3
- static ALLOCATE_COUNT = h.ALLOCATE_COUNT;
4
- heap;
5
- list;
6
- cache = /* @__PURE__ */ new Map();
7
- constructor(t, e) {
8
- e ? this.list = new h(t, e) : this.list = new h(t), this.heap = t, this.list.onDelete = (i) => {
9
- let r = Atomics.load(i, 0);
10
- if (r) {
11
- let s = this.cache.get(r);
12
- s || (s = this.initItem(r)), s && (s.free(), this.cache.delete(r));
13
- }
14
- };
15
- }
16
- get length() {
17
- return this.list.length;
18
- }
19
- clear() {
20
- this.list.clear(), this.cache.clear();
21
- }
22
- insert(t) {
23
- this.list.insert(t.pointer), this.cache.set(t.pointer, t);
24
- }
25
- delete(t) {
26
- return this.cache.delete(t.pointer), this.list.deleteValue(t.pointer);
27
- }
28
- getByPointer(t) {
29
- let e = this.cache.get(t);
30
- return e || (e = this.initItem(t), e && this.cache.set(t, e)), e;
31
- }
32
- *[Symbol.iterator]() {
33
- let t = this.list[Symbol.iterator]();
34
- for (let { data: e, deleteCurrent: i } of t) {
35
- let r = Atomics.load(e, 0);
36
- if (!r)
37
- continue;
38
- let s = this.cache.get(r);
39
- s || (s = this.initItem(r), s && this.cache.set(r, s)), s && (yield {
40
- item: s,
41
- deleteCurrent: i
42
- });
43
- }
44
- }
45
- forEach(t, e) {
46
- for (let { item: i } of this)
47
- (!e || e(i)) && t(i);
48
- }
49
- find(t) {
50
- for (let { item: e } of this)
51
- if (t(e))
52
- return e;
53
- }
54
- filter(t) {
55
- let e = [];
56
- for (let { item: i } of this)
57
- t(i) && e.push(i);
58
- return e;
59
- }
60
- map(t) {
61
- const e = [];
62
- for (let { item: i } of this)
63
- e.push(t(i));
64
- return e;
65
- }
66
- getSharedMemory() {
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
- //# sourceMappingURL=cached-item-list.js.map
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\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\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}"],"names":["CachedItemList","SharedList","heap","config","pointerData","pointer","item","iterator","deleteCurrent","callback","filter","items","array"],"mappings":";AAIA,MAA8BA,EAA2F;AAAA,EACxH,OAAgB,iBAAiBC,EAAW;AAAA,EAElC;AAAA,EACA;AAAA,EACA,4BAA4B,IAAA;AAAA,EAEtC,YAAYC,GAAkBC,GAA8C;AAC3E,IAAGA,IACF,KAAK,OAAO,IAAIF,EAAWC,GAAMC,CAAM,IAEvC,KAAK,OAAO,IAAIF,EAAWC,CAAI,GAEhC,KAAK,OAAOA,GAEZ,KAAK,KAAK,WAAW,CAACE,MAA6B;AAClD,UAAIC,IAAU,QAAQ,KAAKD,GAAa,CAAC;AACzC,UAAGC,GAAS;AACX,YAAIC,IAAO,KAAK,MAAM,IAAID,CAAO;AACjC,QAAIC,MACHA,IAAO,KAAK,SAASD,CAAO,IAG1BC,MACFA,EAAK,KAAA,GACL,KAAK,MAAM,OAAOD,CAAO;AAAA,MAE3B;AAAA,IACD;AAAA,EACD;AAAA,EAEA,IAAI,SAAS;AACZ,WAAO,KAAK,KAAK;AAAA,EAClB;AAAA,EAEA,QAAQ;AACP,SAAK,KAAK,MAAA,GACV,KAAK,MAAM,MAAA;AAAA,EACZ;AAAA,EAEA,OAAOC,GAAS;AACf,SAAK,KAAK,OAAOA,EAAK,OAAO,GAC7B,KAAK,MAAM,IAAIA,EAAK,SAASA,CAAI;AAAA,EAClC;AAAA,EACA,OAAOA,GAAS;AACf,gBAAK,MAAM,OAAOA,EAAK,OAAO,GACvB,KAAK,KAAK,YAAYA,EAAK,OAAO;AAAA,EAC1C;AAAA,EAEA,aAAaD,GAAgC;AAC5C,QAAIC,IAAO,KAAK,MAAM,IAAID,CAAO;AACjC,WAAIC,MACHA,IAAO,KAAK,SAASD,CAAO,GACzBC,KACF,KAAK,MAAM,IAAID,GAASC,CAAI,IAIvBA;AAAA,EACR;AAAA,EAGA,EAAE,OAAO,QAAQ,IAAI;AACpB,QAAIC,IAAW,KAAK,KAAK,OAAO,QAAQ,EAAA;AAExC,aAAQ,EAAE,MAAMH,GAAa,eAAAI,EAAA,KAAmBD,GAAU;AACzD,UAAIF,IAAU,QAAQ,KAAKD,GAAa,CAAC;AACzC,UAAG,CAACC;AACH;AAGD,UAAIC,IAAO,KAAK,MAAM,IAAID,CAAO;AACjC,MAAIC,MACHA,IAAO,KAAK,SAASD,CAAO,GACzBC,KACF,KAAK,MAAM,IAAID,GAASC,CAAI,IAI3BA,MACF,MAAM;AAAA,QACL,MAAAA;AAAA,QACA,eAAAE;AAAA,MAAA;AAAA,IAGH;AAAA,EACD;AAAA,EACA,QAAQC,GAA6BC,GAA+B;AACnE,aAAQ,EAAE,MAAAJ,EAAA,KAAU;AACnB,OAAG,CAACI,KAAUA,EAAOJ,CAAI,MACxBG,EAASH,CAAI;AAAA,EAGhB;AAAA,EAEA,KAAKG,GAA+C;AACnD,aAAQ,EAAE,MAAAH,EAAA,KAAU;AACnB,UAAGG,EAASH,CAAI;AACf,eAAOA;AAAA,EAGV;AAAA,EACA,OAAOG,GAA4C;AAClD,QAAIE,IAAQ,CAAA;AACZ,aAAQ,EAAE,MAAAL,EAAA,KAAU;AACnB,MAAGG,EAASH,CAAI,KACfK,EAAM,KAAKL,CAAI;AAIjB,WAAOK;AAAA,EACR;AAAA,EACA,IAAOF,GAAoC;AAC1C,UAAMG,IAAkB,CAAA;AACxB,aAAQ,EAAE,MAAAN,EAAA,KAAU;AACnB,MAAAM,EAAM,KAAKH,EAASH,CAAI,CAAC;AAG1B,WAAOM;AAAA,EACR;AAAA,EAEA,kBAAkB;AACjB,WAAO,KAAK,KAAK,gBAAA;AAAA,EAClB;AAAA,EAEA,OAAO;AACN,SAAK,KAAK,KAAA,GACV,KAAK,MAAM,MAAA;AAAA,EACZ;AACD;"}
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