@daneren2005/shared-memory-objects 1.4.0 → 1.5.1

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 (54) hide show
  1. package/README.md +137 -8
  2. package/dist/allocated-memory.d.ts +7 -2
  3. package/dist/allocated-memory.js +11 -4
  4. package/dist/allocated-memory.js.map +1 -1
  5. package/dist/constant-string.js +2 -2
  6. package/dist/constant-string.js.map +1 -1
  7. package/dist/local-pool.js +2 -2
  8. package/dist/local-pool.js.map +1 -1
  9. package/dist/lock/read-write-lock.js +25 -11
  10. package/dist/lock/read-write-lock.js.map +1 -1
  11. package/dist/memory-buffer.d.ts +11 -5
  12. package/dist/memory-buffer.js +70 -74
  13. package/dist/memory-buffer.js.map +1 -1
  14. package/dist/memory-heap.d.ts +3 -0
  15. package/dist/memory-heap.js +37 -29
  16. package/dist/memory-heap.js.map +1 -1
  17. package/dist/serialize-object.js +1 -1
  18. package/dist/serialize-object.js.map +1 -1
  19. package/dist/shared-list.d.ts +2 -0
  20. package/dist/shared-list.js +32 -29
  21. package/dist/shared-list.js.map +1 -1
  22. package/dist/shared-map.d.ts +11 -3
  23. package/dist/shared-map.js +93 -47
  24. package/dist/shared-map.js.map +1 -1
  25. package/dist/shared-pointer-list.js +3 -3
  26. package/dist/shared-pointer-list.js.map +1 -1
  27. package/dist/shared-pool.d.ts +11 -2
  28. package/dist/shared-pool.js +58 -26
  29. package/dist/shared-pool.js.map +1 -1
  30. package/dist/shared-stack.js +19 -8
  31. package/dist/shared-stack.js.map +1 -1
  32. package/dist/shared-string.js +3 -3
  33. package/dist/shared-string.js.map +1 -1
  34. package/dist/shared-vector.js +10 -7
  35. package/dist/shared-vector.js.map +1 -1
  36. package/dist/spatial/shared-quadtree.d.ts +67 -0
  37. package/dist/spatial/shared-quadtree.js +361 -0
  38. package/dist/spatial/shared-quadtree.js.map +1 -0
  39. package/dist/spatial/shared-spatial-grid.d.ts +78 -0
  40. package/dist/spatial/shared-spatial-grid.js +426 -0
  41. package/dist/spatial/shared-spatial-grid.js.map +1 -0
  42. package/dist/spatial/shared-spatial-map.d.ts +87 -0
  43. package/dist/spatial/shared-spatial-map.js +555 -0
  44. package/dist/spatial/shared-spatial-map.js.map +1 -0
  45. package/dist/spatial/spatial-entity.d.ts +11 -0
  46. package/dist/spatial/spatial-entity.js +19 -0
  47. package/dist/spatial/spatial-entity.js.map +1 -0
  48. package/dist/spatial/spatial-neighbors.d.ts +21 -0
  49. package/dist/spatial/spatial-neighbors.js +55 -0
  50. package/dist/spatial/spatial-neighbors.js.map +1 -0
  51. package/dist/utils/pointer.d.ts +8 -6
  52. package/dist/utils/pointer.js +22 -17
  53. package/dist/utils/pointer.js.map +1 -1
  54. package/package.json +6 -1
@@ -0,0 +1,87 @@
1
+ import type { SharedAllocatedMemory } from '../allocated-memory';
2
+ import type MemoryHeap from '../memory-heap';
3
+ import { type SpatialEntity } from './spatial-entity';
4
+ type CoordArrayConstructor = Float32ArrayConstructor | Float64ArrayConstructor;
5
+ export default class SharedSpatialMap {
6
+ static readonly ALLOCATE_COUNT = 11;
7
+ private memory;
8
+ private firstBlock;
9
+ private entityPool;
10
+ private slotPool;
11
+ private idMap;
12
+ private bucketPointers;
13
+ private entityScratch;
14
+ private slotScratch;
15
+ private bucketSegments;
16
+ private bucketHeadSegments;
17
+ private tableLock;
18
+ private readonly coordType;
19
+ private readonly nullIndex;
20
+ private bucketCount;
21
+ private readonly maxBucketCount;
22
+ private bucketMask;
23
+ private readonly cellSize;
24
+ get size(): number;
25
+ get gridSize(): number;
26
+ get buckets(): number;
27
+ get maxBuckets(): number;
28
+ get type(): number;
29
+ constructor(memory: MemoryHeap, config?: SharedSpatialMapConfig | SharedSpatialMapMemory);
30
+ get pointer(): number;
31
+ get usedMemory(): number;
32
+ insert(id: number, x: number, y: number, width?: number, height?: number): void;
33
+ bulkInsert(entities: Iterable<SpatialEntity>): void;
34
+ private insertLocked;
35
+ update(id: number, x: number, y: number, width?: number, height?: number): void;
36
+ private updateLocked;
37
+ remove(id: number): boolean;
38
+ private removeLocked;
39
+ has(id: number): boolean;
40
+ search(x: number, y: number, width: number, height: number, filter?: (id: number) => boolean): Array<number>;
41
+ searchInto(out: Array<number>, x: number, y: number, width: number, height: number, filter?: (id: number) => boolean): Array<number>;
42
+ private searchIntoLocked;
43
+ neighbors(x: number, y: number, maxResults: number, maxDistance: number, filter?: (id: number) => boolean): Array<number>;
44
+ private neighborsLocked;
45
+ clear(): void;
46
+ free(): void;
47
+ getSharedMemory(): SharedSpatialMapMemory;
48
+ private getConfigView;
49
+ private colOf;
50
+ private rowOf;
51
+ private mapRingDistanceSquared;
52
+ private bucketOf;
53
+ private bucketOffset;
54
+ private getBucketSegment;
55
+ private appendBucketSegments;
56
+ private syncBucketCount;
57
+ private growBucketsIfNeeded;
58
+ private ensureBucketCapacity;
59
+ private resizeBuckets;
60
+ private growBucketsForBulk;
61
+ private linkRange;
62
+ private linkIntoBucket;
63
+ private linkReservedBucket;
64
+ private relinkRange;
65
+ private refreshAnchorInBucket;
66
+ private unlinkRange;
67
+ private collectBucket;
68
+ private collectNeighborBucket;
69
+ private collectNearestBucket;
70
+ private collectNeighborCandidates;
71
+ private addEntityCandidate;
72
+ private entityDistanceSquared;
73
+ private entityBlockDistanceSquared;
74
+ private unlinkFromBucket;
75
+ }
76
+ interface SharedSpatialMapConfig {
77
+ gridSize?: number;
78
+ buckets?: number;
79
+ maxBuckets?: number;
80
+ maxEntities?: number;
81
+ maxSlots?: number;
82
+ type?: CoordArrayConstructor;
83
+ }
84
+ interface SharedSpatialMapMemory {
85
+ firstBlock: SharedAllocatedMemory;
86
+ }
87
+ export type { SharedSpatialMapConfig, SharedSpatialMapMemory, SpatialEntity };
@@ -0,0 +1,555 @@
1
+ import { getPointer as e, loadRawPointer as t, storeRawPointer as n } from "../utils/pointer.js";
2
+ import r from "../allocated-memory.js";
3
+ import { ARRAY_TYPE as i, getArrayTypeCode as a, getByteMultipler as o, makeArrayView as s } from "../utils/array-type.js";
4
+ import { lock as c, unlock as l } from "../lock/simple-lock.js";
5
+ import u from "../shared-map.js";
6
+ import d from "../shared-stack.js";
7
+ import f from "../shared-pool.js";
8
+ import { readLock as p, readUnlock as m, writeLock as h, writeUnlock as g } from "../lock/read-write-lock.js";
9
+ import { addCandidate as _, candidateLimit as v, distanceSquaredToRect as y } from "./spatial-neighbors.js";
10
+ import { getSpatialMapCapacity as ee, getSpatialPoolChunkSize as te } from "./spatial-entity.js";
11
+ //#region src/spatial/shared-spatial-map.ts
12
+ var b = 0, x = 1, S = 2, C = 3, w = 4, T = 5, E = 6, D = 8, ne = 10, O = 0, k = 1, A = 2, j = 8, M = 256, re = 255, N = 0, P = 1, F = 2, I = 3, L = 4, R = 5, z = 6, B = 7, V = 0, H = 1, U = 2, W = 3, G = 4, K = 5, q = 6, J = 7, Y = 8, X = 16777216, ie = X, ae = 4294967295, oe = 73856093, se = 19349663, ce = 50, le = 256, Z = 1, Q = 2, ue = 1e6, de = 4, fe = Float32Array, pe = class a {
13
+ static ALLOCATE_COUNT = 11;
14
+ memory;
15
+ firstBlock;
16
+ entityPool;
17
+ slotPool;
18
+ idMap;
19
+ bucketPointers;
20
+ entityScratch = [
21
+ 0,
22
+ 0,
23
+ 0,
24
+ 0,
25
+ 0,
26
+ 0,
27
+ 0,
28
+ 0
29
+ ];
30
+ slotScratch = [
31
+ 0,
32
+ 0,
33
+ 0,
34
+ 0,
35
+ 0,
36
+ 0,
37
+ 0
38
+ ];
39
+ bucketSegments = [];
40
+ bucketHeadSegments = [];
41
+ tableLock;
42
+ coordType;
43
+ nullIndex;
44
+ bucketCount;
45
+ maxBucketCount;
46
+ bucketMask;
47
+ cellSize;
48
+ get size() {
49
+ return this.idMap.length;
50
+ }
51
+ get gridSize() {
52
+ return this.cellSize;
53
+ }
54
+ get buckets() {
55
+ return Atomics.load(this.firstBlock.data, w);
56
+ }
57
+ get maxBuckets() {
58
+ return this.maxBucketCount;
59
+ }
60
+ get type() {
61
+ return this.coordType;
62
+ }
63
+ constructor(s, c) {
64
+ if (this.memory = s, c && "firstBlock" in c) this.firstBlock = new r(s, c.firstBlock), this.coordType = this.firstBlock.data[T], this.bucketPointers = new d(s, { firstBlock: e(t(this.firstBlock.data, b), s.positionBits) }), this.entityPool = new f(s, { firstBlock: e(t(this.firstBlock.data, x), s.positionBits) }), this.slotPool = new f(s, { firstBlock: e(t(this.firstBlock.data, S), s.positionBits) }), this.idMap = new u(s, { firstBlock: e(t(this.firstBlock.data, C), s.positionBits) }), this.bucketCount = Atomics.load(this.firstBlock.data, w), this.maxBucketCount = this.firstBlock.data[ne], this.nullIndex = ge(this.coordType);
65
+ else {
66
+ let e = c?.gridSize ?? ce;
67
+ this.bucketCount = Math.min(1073741824, Math.max(1, Math.floor(c?.buckets ?? le)));
68
+ let t = c?.maxEntities ?? ue, r = c?.maxSlots ?? t * de;
69
+ if (this.maxBucketCount = Math.min(1073741824, Math.max(this.bucketCount, Math.floor(c?.maxBuckets ?? _e(r * 2)))), this.coordType = me(c?.type), this.nullIndex = ge(this.coordType), this.coordType === i.float32 && (t > X || r > X)) throw Error(`Float32 SharedSpatialMap supports at most ${X} entities and slots; pass type: Float64Array for more`);
70
+ let l = {
71
+ type: he(this.coordType),
72
+ dataLength: Y,
73
+ maxLength: t,
74
+ maxChunkSize: te(t, Y, o(this.coordType), s.maxAllocationLength)
75
+ }, p = {
76
+ type: he(this.coordType),
77
+ dataLength: B,
78
+ maxLength: r,
79
+ maxChunkSize: te(r, B, o(this.coordType), s.maxAllocationLength)
80
+ }, m = f.getAllocateCount(s, l), h = f.getAllocateCount(s, p), g = u.ALLOCATE_COUNT, _ = a.ALLOCATE_COUNT;
81
+ this.firstBlock = s.allocUI32(_ + m + h + g), this.firstBlock.data[w] = this.bucketCount, this.firstBlock.data[T] = this.coordType, this.firstBlock.data[ne] = this.maxBucketCount;
82
+ let v = this.getConfigView();
83
+ v[0] = e, this.bucketPointers = new d(s), n(this.firstBlock.data, b, this.bucketPointers.pointer), this.appendBucketSegments(this.bucketCount);
84
+ let y = this.firstBlock.getSubAllocation(_, m);
85
+ this.entityPool = new f(s, {
86
+ firstBlock: y,
87
+ ...l
88
+ }), n(this.firstBlock.data, x, y.pointer);
89
+ let E = this.firstBlock.getSubAllocation(_ + m, h);
90
+ this.slotPool = new f(s, {
91
+ firstBlock: E,
92
+ ...p
93
+ }), n(this.firstBlock.data, S, E.pointer);
94
+ let D = this.firstBlock.getSubAllocation(_ + m + h, g);
95
+ this.idMap = new u(s, {
96
+ firstBlock: D,
97
+ capacity: ee(t, s.maxAllocationLength)
98
+ }), n(this.firstBlock.data, C, D.pointer);
99
+ }
100
+ this.bucketMask = $(this.bucketCount), this.tableLock = new Int32Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + D * Uint32Array.BYTES_PER_ELEMENT, 2);
101
+ let l = this.getConfigView();
102
+ this.cellSize = l[0];
103
+ }
104
+ get pointer() {
105
+ return this.firstBlock.pointer;
106
+ }
107
+ get usedMemory() {
108
+ let t = this.firstBlock.usedMemory + this.bucketPointers.usedMemory + this.entityPool.usedMemory + this.slotPool.usedMemory + this.idMap.usedMemory;
109
+ for (let n of this.bucketPointers) t += new r(this.memory, e(n, this.memory.positionBits)).usedMemory;
110
+ return t;
111
+ }
112
+ insert(e, t, n, r = 0, i = 0) {
113
+ p(this.tableLock);
114
+ try {
115
+ this.syncBucketCount(), this.insertLocked(e, t, n, r, i);
116
+ } finally {
117
+ m(this.tableLock);
118
+ }
119
+ this.growBucketsIfNeeded();
120
+ }
121
+ bulkInsert(e) {
122
+ let t = /* @__PURE__ */ new Map();
123
+ for (let n of e) t.set(n.id, n);
124
+ let n = Array.from(t.values()), r = this.idMap.getAll(n.map((e) => e.id)), i = [], a = 0, o = 0;
125
+ for (let e = 0; e < n.length; e++) if (r[e] === void 0) {
126
+ let t = n[e];
127
+ o++, a += (this.colOf(t.x + (t.width ?? 0)) - this.colOf(t.x) + 1) * (this.rowOf(t.y + (t.height ?? 0)) - this.rowOf(t.y) + 1);
128
+ }
129
+ this.ensureBucketCapacity(this.slotPool.length + a);
130
+ let s = this.entityPool.reserveContiguous(o), c = this.slotPool.reserveContiguous(a);
131
+ p(this.tableLock);
132
+ try {
133
+ this.syncBucketCount();
134
+ for (let e = 0; e < n.length; e++) {
135
+ let t = n[e], a = t.width ?? 0, o = t.height ?? 0;
136
+ if (r[e] !== void 0) {
137
+ this.updateLocked(t.id, t.x, t.y, a, o);
138
+ continue;
139
+ }
140
+ let l = this.colOf(t.x), u = this.rowOf(t.y), d = this.colOf(t.x + a), f = this.rowOf(t.y + o), p = s++, m = this.entityPool.blockFor(p), h = this.entityPool.blockOffset(p);
141
+ m[h + V] = l, m[h + H] = u, m[h + U] = d, m[h + W] = f, m[h + G] = t.x, m[h + K] = t.y, m[h + q] = a, m[h + J] = o, i.push([t.id, p]);
142
+ for (let e = u; e <= f; e++) for (let n = l; n <= d; n++) this.linkReservedBucket(n, e, c++, t.id, p, l, u);
143
+ }
144
+ this.idMap.setAll(i);
145
+ } finally {
146
+ m(this.tableLock);
147
+ }
148
+ this.growBucketsForBulk();
149
+ }
150
+ insertLocked(e, t, n, r, i) {
151
+ if (this.idMap.get(e) !== void 0) {
152
+ this.updateLocked(e, t, n, r, i);
153
+ return;
154
+ }
155
+ let a = this.colOf(t), o = this.rowOf(n), s = this.colOf(t + r), c = this.rowOf(n + i), l = this.entityScratch;
156
+ l[V] = a, l[H] = o, l[U] = s, l[W] = c, l[G] = t, l[K] = n, l[q] = r, l[J] = i;
157
+ let u = this.entityPool.push(l);
158
+ this.idMap.set(e, u), this.linkRange(e, u, a, o, s, c);
159
+ }
160
+ update(e, t, n, r = 0, i = 0) {
161
+ let a = this.idMap.get(e);
162
+ if (a !== void 0) {
163
+ let e = this.entityPool.blockFor(a), o = this.entityPool.blockOffset(a), s = this.colOf(t), c = this.rowOf(n), l = this.colOf(t + r), u = this.rowOf(n + i);
164
+ if (s === e[o + V] && c === e[o + H] && l === e[o + U] && u === e[o + W]) {
165
+ e[o + G] = t, e[o + K] = n, e[o + q] = r, e[o + J] = i;
166
+ return;
167
+ }
168
+ }
169
+ p(this.tableLock);
170
+ try {
171
+ this.syncBucketCount(), this.updateLocked(e, t, n, r, i);
172
+ } finally {
173
+ m(this.tableLock);
174
+ }
175
+ this.growBucketsIfNeeded();
176
+ }
177
+ updateLocked(e, t, n, r, i) {
178
+ let a = this.idMap.get(e);
179
+ if (a === void 0) {
180
+ this.insertLocked(e, t, n, r, i);
181
+ return;
182
+ }
183
+ let o = this.entityPool.blockFor(a), s = this.entityPool.blockOffset(a), c = o[s + V], l = o[s + H], u = o[s + U], d = o[s + W], f = this.colOf(t), p = this.rowOf(n), m = this.colOf(t + r), h = this.rowOf(n + i);
184
+ if (f === c && p === l && m === u && h === d) {
185
+ o[s + G] = t, o[s + K] = n, o[s + q] = r, o[s + J] = i;
186
+ return;
187
+ }
188
+ this.relinkRange(e, a, f, p, m, h, c, l, u, d), o[s + V] = f, o[s + H] = p, o[s + U] = m, o[s + W] = h, o[s + G] = t, o[s + K] = n, o[s + q] = r, o[s + J] = i;
189
+ }
190
+ remove(e) {
191
+ p(this.tableLock);
192
+ try {
193
+ return this.syncBucketCount(), this.removeLocked(e);
194
+ } finally {
195
+ m(this.tableLock);
196
+ }
197
+ }
198
+ removeLocked(e) {
199
+ let t = this.idMap.get(e);
200
+ if (t === void 0) return !1;
201
+ let n = this.entityPool.blockFor(t), r = this.entityPool.blockOffset(t);
202
+ return this.unlinkRange(e, n[r + V], n[r + H], n[r + U], n[r + W]), this.entityPool.deleteIndex(t), this.idMap.delete(e), !0;
203
+ }
204
+ has(e) {
205
+ return this.idMap.get(e) !== void 0;
206
+ }
207
+ search(e, t, n, r, i) {
208
+ let a = [];
209
+ return this.searchInto(a, e, t, n, r, i), a;
210
+ }
211
+ searchInto(e, t, n, r, i, a) {
212
+ p(this.tableLock);
213
+ try {
214
+ return this.syncBucketCount(), this.searchIntoLocked(e, t, n, r, i, a);
215
+ } finally {
216
+ m(this.tableLock);
217
+ }
218
+ }
219
+ searchIntoLocked(e, t, n, r, i, a) {
220
+ let o = e.length, s = this.colOf(t), c = this.rowOf(n), l = this.colOf(t + r), u = this.rowOf(n + i), d = this.nullIndex;
221
+ for (let t = c; t <= u; t++) for (let n = s; n <= l; n++) {
222
+ let r = this.bucketOf(n, t), i = this.getBucketSegment(r), a = this.bucketOffset(r), o = this.bucketHeadSegments[r >>> j];
223
+ o[a + k] !== d && this.collectBucket(e, i, o, a, n, t, s, c);
224
+ }
225
+ if (a !== void 0) {
226
+ let t = o;
227
+ for (let n = o; n < e.length; n++) {
228
+ let r = e[n];
229
+ a(r) && (e[t++] = r);
230
+ }
231
+ e.length = t;
232
+ }
233
+ return e;
234
+ }
235
+ neighbors(e, t, n, r, i) {
236
+ p(this.tableLock);
237
+ try {
238
+ return this.syncBucketCount(), this.neighborsLocked(e, t, n, r, i);
239
+ } finally {
240
+ m(this.tableLock);
241
+ }
242
+ }
243
+ neighborsLocked(e, t, n, r, i) {
244
+ if (n <= 0 || r < 0 || Number.isNaN(n) || Number.isNaN(r) || (n = Math.floor(n), n === 0)) return [];
245
+ let a = r * r, o = [];
246
+ if (!Number.isFinite(r)) {
247
+ for (let [r, s] of this.idMap) (i === void 0 || i(r)) && this.addEntityCandidate(o, r, s, e, t, n, a);
248
+ return o.map((e) => e.id);
249
+ }
250
+ let s = [], c = i !== void 0 && n > 1 ? /* @__PURE__ */ new Set() : void 0, l = this.colOf(e), u = this.rowOf(t), d = {
251
+ id: void 0,
252
+ distance: a
253
+ }, f = (r, f) => {
254
+ if (i === void 0) {
255
+ n === 1 ? this.collectNearestBucket(d, r, f, e, t) : this.collectNeighborCandidates(o, r, f, l, u, e, t, n, a);
256
+ return;
257
+ }
258
+ s.length = 0, this.collectNeighborBucket(s, r, f);
259
+ for (let r of s) {
260
+ if (c?.has(r)) continue;
261
+ c?.add(r);
262
+ let s = this.idMap.get(r);
263
+ if (s !== void 0 && (i === void 0 || i(r))) {
264
+ if (n === 1) {
265
+ let n = this.entityDistanceSquared(s, e, t);
266
+ (n < d.distance || n === d.distance && (d.id === void 0 || r < d.id)) && (d.id = r, d.distance = n);
267
+ } else this.addEntityCandidate(o, r, s, e, t, n, a);
268
+ }
269
+ }
270
+ };
271
+ for (let r = 0;; r++) {
272
+ let i = n === 1 ? d.distance : v(o, n, a);
273
+ if (this.mapRingDistanceSquared(e, t, l, u, r) > i) break;
274
+ if (r === 0) {
275
+ f(l, u);
276
+ continue;
277
+ }
278
+ let s = l - r, c = l + r, p = u - r, m = u + r;
279
+ for (let e = s; e <= c; e++) f(e, p), f(e, m);
280
+ for (let e = p + 1; e < m; e++) f(s, e), f(c, e);
281
+ }
282
+ return n === 1 ? d.id === void 0 ? [] : [d.id] : o.map((e) => e.id);
283
+ }
284
+ clear() {
285
+ h(this.tableLock);
286
+ try {
287
+ this.syncBucketCount();
288
+ for (let e = 0; e < this.bucketPointers.length; e++) {
289
+ this.getBucketSegment(e << j);
290
+ let t = this.bucketHeadSegments[e];
291
+ for (let e = k; e < t.length; e += A) t[e] = this.nullIndex;
292
+ }
293
+ this.entityPool.clear(), this.slotPool.clear();
294
+ let e = [];
295
+ for (let [t] of this.idMap) e.push(t);
296
+ for (let t of e) this.idMap.delete(t);
297
+ } finally {
298
+ g(this.tableLock);
299
+ }
300
+ }
301
+ free() {
302
+ for (let t of this.bucketPointers) new r(this.memory, e(t, this.memory.positionBits)).free();
303
+ this.bucketPointers.free(), this.entityPool.free(), this.slotPool.free(), this.idMap.free(), this.firstBlock.free();
304
+ }
305
+ getSharedMemory() {
306
+ return { firstBlock: this.firstBlock.getSharedMemory() };
307
+ }
308
+ getConfigView() {
309
+ return s(this.coordType, this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + E * Uint32Array.BYTES_PER_ELEMENT, 1);
310
+ }
311
+ colOf(e) {
312
+ return Math.floor(e / this.cellSize);
313
+ }
314
+ rowOf(e) {
315
+ return Math.floor(e / this.cellSize);
316
+ }
317
+ mapRingDistanceSquared(e, t, n, r, i) {
318
+ if (i === 0) return 0;
319
+ let a = this.cellSize, o = e - (n - i + 1) * a, s = (n + i) * a - e, c = t - (r - i + 1) * a, l = (r + i) * a - t, u = Math.min(o, s, c, l);
320
+ return u * u;
321
+ }
322
+ bucketOf(e, t) {
323
+ let n = (Math.imul(e, oe) ^ Math.imul(t, se)) >>> 0, r = this.bucketMask;
324
+ return r >= 0 ? n & r : n % this.bucketCount;
325
+ }
326
+ bucketOffset(e) {
327
+ return (e & re) * A;
328
+ }
329
+ getBucketSegment(t) {
330
+ let n = t >>> j, i = this.bucketSegments[n];
331
+ if (i !== void 0) return i;
332
+ let a = this.bucketPointers.at(n), o = new r(this.memory, e(a, this.memory.positionBits)), s = new Int32Array(o.data.buffer, o.bufferByteOffset, M * A);
333
+ return this.bucketHeadSegments[n] = new Uint32Array(o.data.buffer, o.bufferByteOffset, M * A), this.bucketSegments[n] = s, s;
334
+ }
335
+ appendBucketSegments(e) {
336
+ let t = Math.ceil(e / M);
337
+ for (; this.bucketPointers.length < t;) {
338
+ let e = this.memory.allocUI32(M * A), t = new Uint32Array(e.data.buffer, e.bufferByteOffset, M * A);
339
+ for (let e = k; e < t.length; e += A) t[e] = this.nullIndex;
340
+ this.bucketPointers.push(e.pointer);
341
+ }
342
+ }
343
+ syncBucketCount() {
344
+ let e = Atomics.load(this.firstBlock.data, w);
345
+ e !== this.bucketCount && (this.bucketCount = e, this.bucketMask = $(e));
346
+ }
347
+ growBucketsIfNeeded() {
348
+ let e = Atomics.load(this.firstBlock.data, w);
349
+ if (!(e >= this.maxBucketCount || this.slotPool.length * Q <= e * Z)) {
350
+ h(this.tableLock);
351
+ try {
352
+ if (this.syncBucketCount(), this.slotPool.length * Q <= this.bucketCount * Z) return;
353
+ let e = Math.min(this.bucketCount * 2, this.maxBucketCount);
354
+ if (e === this.bucketCount) return;
355
+ this.resizeBuckets(e);
356
+ } finally {
357
+ g(this.tableLock);
358
+ }
359
+ }
360
+ }
361
+ ensureBucketCapacity(e) {
362
+ let t = Math.ceil(e * Q / Z), n = Math.min(_e(t), this.maxBucketCount);
363
+ if (!(n <= Atomics.load(this.firstBlock.data, w))) {
364
+ h(this.tableLock);
365
+ try {
366
+ this.syncBucketCount(), n > this.bucketCount && this.resizeBuckets(n);
367
+ } finally {
368
+ g(this.tableLock);
369
+ }
370
+ }
371
+ }
372
+ resizeBuckets(e) {
373
+ this.appendBucketSegments(e);
374
+ for (let e = 0; e < this.bucketPointers.length; e++) {
375
+ this.getBucketSegment(e << j);
376
+ let t = this.bucketHeadSegments[e];
377
+ for (let e = k; e < t.length; e += A) t[e] = this.nullIndex;
378
+ }
379
+ this.bucketCount = e, this.bucketMask = $(e);
380
+ for (let [e, t] of this.slotPool.entries()) {
381
+ let n = this.bucketOf(t[P], t[F]), r = this.bucketHeadSegments[n >>> j], i = this.bucketOffset(n) + k;
382
+ t[R] = r[i], r[i] = e;
383
+ }
384
+ Atomics.store(this.firstBlock.data, w, e);
385
+ }
386
+ growBucketsForBulk() {
387
+ for (;;) {
388
+ let e = Atomics.load(this.firstBlock.data, w);
389
+ if (this.growBucketsIfNeeded(), Atomics.load(this.firstBlock.data, w) === e) return;
390
+ }
391
+ }
392
+ linkRange(e, t, n, r, i, a) {
393
+ let o = this.slotScratch;
394
+ o[N] = e, o[I] = n, o[L] = r, o[R] = this.nullIndex, o[z] = t;
395
+ for (let e = r; e <= a; e++) for (let t = n; t <= i; t++) this.linkIntoBucket(t, e, o);
396
+ }
397
+ linkIntoBucket(e, t, n) {
398
+ n[P] = e, n[F] = t;
399
+ let r = this.slotPool, i = r.push(n), a = this.bucketOf(e, t), o = this.getBucketSegment(a), s = this.bucketHeadSegments[a >>> j], u = this.bucketOffset(a), d = u + O;
400
+ c(o, d);
401
+ let f = u + k;
402
+ r.set(i, R, s[f]), s[f] = i, l(o, d);
403
+ }
404
+ linkReservedBucket(e, t, n, r, i, a, o) {
405
+ let s = this.slotPool, u = s.blockFor(n), d = s.blockOffset(n);
406
+ u[d + N] = r, u[d + P] = e, u[d + F] = t, u[d + I] = a, u[d + L] = o, u[d + z] = i;
407
+ let f = this.bucketOf(e, t), p = this.getBucketSegment(f), m = this.bucketHeadSegments[f >>> j], h = this.bucketOffset(f), g = h + O;
408
+ c(p, g);
409
+ let _ = h + k;
410
+ u[d + R] = m[_], m[_] = n, l(p, g);
411
+ }
412
+ relinkRange(e, t, n, r, i, a, o, s, c, l) {
413
+ let u = n > o ? n : o, d = i < c ? i : c, f = r > s ? r : s, p = a < l ? a : l, m = u <= d && f <= p, h = this.slotScratch;
414
+ h[N] = e, h[I] = n, h[L] = r, h[R] = this.nullIndex, h[z] = t;
415
+ for (let t = r; t <= a; t++) {
416
+ let a = m && t >= f && t <= p;
417
+ for (let o = n; o <= i; o++) a && o >= u && o <= d ? this.refreshAnchorInBucket(this.bucketOf(o, t), e, o, t, n, r) : this.linkIntoBucket(o, t, h);
418
+ }
419
+ let g = this.nullIndex, _ = this.slotPool;
420
+ for (let t = s; t <= l; t++) {
421
+ let n = m && t >= f && t <= p;
422
+ for (let r = o; r <= c; r++) {
423
+ if (n && r >= u && r <= d) continue;
424
+ let i = this.unlinkFromBucket(this.bucketOf(r, t), e, r, t);
425
+ i !== g && _.deleteIndex(i);
426
+ }
427
+ }
428
+ }
429
+ refreshAnchorInBucket(e, t, n, r, i, a) {
430
+ let o = this.nullIndex, s = this.getBucketSegment(e), u = this.bucketOffset(e), d = u + O;
431
+ c(s, d);
432
+ let f = this.slotPool, p = this.bucketHeadSegments[e >>> j][u + k];
433
+ for (; p !== o;) {
434
+ let e = f.blockFor(p), o = f.blockOffset(p);
435
+ if (e[o + N] === t && e[o + P] === n && e[o + F] === r) {
436
+ e[o + I] = i, e[o + L] = a;
437
+ break;
438
+ }
439
+ p = e[o + R];
440
+ }
441
+ l(s, d);
442
+ }
443
+ unlinkRange(e, t, n, r, i) {
444
+ let a = this.nullIndex, o = this.slotPool;
445
+ for (let s = n; s <= i; s++) for (let n = t; n <= r; n++) {
446
+ let t = this.unlinkFromBucket(this.bucketOf(n, s), e, n, s);
447
+ t !== a && o.deleteIndex(t);
448
+ }
449
+ }
450
+ collectBucket(e, t, n, r, i, a, o, s) {
451
+ let u = this.nullIndex, d = r + k, f = r + O;
452
+ c(t, f);
453
+ let p = n[d], m = this.slotPool;
454
+ for (; p !== u;) {
455
+ let t = m.blockFor(p), n = m.blockOffset(p);
456
+ if (t[n + P] === i && t[n + F] === a) {
457
+ let r = t[n + I], c = t[n + L];
458
+ i === (r > o ? r : o) && a === (c > s ? c : s) && e.push(t[n + N]);
459
+ }
460
+ p = t[n + R];
461
+ }
462
+ l(t, f);
463
+ }
464
+ collectNeighborBucket(e, t, n) {
465
+ let r = this.bucketOf(t, n), i = this.getBucketSegment(r), a = this.bucketHeadSegments[r >>> j], o = this.bucketOffset(r), s = o + k;
466
+ if (a[s] === this.nullIndex) return;
467
+ let u = o + O;
468
+ c(i, u);
469
+ let d = a[s];
470
+ for (; d !== this.nullIndex;) {
471
+ let r = this.slotPool.blockFor(d), i = this.slotPool.blockOffset(d);
472
+ r[i + P] === t && r[i + F] === n && e.push(r[i + N]), d = r[i + R];
473
+ }
474
+ l(i, u);
475
+ }
476
+ collectNearestBucket(e, t, n, r, i) {
477
+ let a = this.bucketOf(t, n), o = this.getBucketSegment(a), s = this.bucketHeadSegments[a >>> j], u = this.bucketOffset(a), d = u + k;
478
+ if (s[d] === this.nullIndex) return;
479
+ let f = u + O;
480
+ c(o, f);
481
+ let p = s[d];
482
+ for (; p !== this.nullIndex;) {
483
+ let a = this.slotPool.blockFor(p), o = this.slotPool.blockOffset(p);
484
+ if (a[o + P] === t && a[o + F] === n) {
485
+ let t = a[o + z], n = this.entityPool.blockFor(t), s = this.entityPool.blockOffset(t), c = a[o + N], l = this.entityBlockDistanceSquared(n, s, r, i);
486
+ (l < e.distance || l === e.distance && (e.id === void 0 || c < e.id)) && (e.id = c, e.distance = l);
487
+ }
488
+ p = a[o + R];
489
+ }
490
+ l(o, f);
491
+ }
492
+ collectNeighborCandidates(e, t, n, r, i, a, o, s, u) {
493
+ let d = this.bucketOf(t, n), f = this.getBucketSegment(d), p = this.bucketHeadSegments[d >>> j], m = this.bucketOffset(d), h = m + k;
494
+ if (p[h] === this.nullIndex) return;
495
+ let g = m + O;
496
+ c(f, g);
497
+ let v = p[h];
498
+ for (; v !== this.nullIndex;) {
499
+ let c = this.slotPool.blockFor(v), l = this.slotPool.blockOffset(v);
500
+ if (c[l + P] === t && c[l + F] === n) {
501
+ let d = c[l + z], f = this.entityPool.blockFor(d), p = this.entityPool.blockOffset(d), m = f[p + V], h = f[p + U], g = f[p + H], v = f[p + W];
502
+ if (t === (r < m ? m : r > h ? h : r) && n === (i < g ? g : i > v ? v : i)) {
503
+ let t = this.entityBlockDistanceSquared(f, p, a, o);
504
+ t <= u && _(e, c[l + N], t, s);
505
+ }
506
+ }
507
+ v = c[l + R];
508
+ }
509
+ l(f, g);
510
+ }
511
+ addEntityCandidate(e, t, n, r, i, a, o) {
512
+ let s = this.entityDistanceSquared(n, r, i);
513
+ s <= o && _(e, t, s, a);
514
+ }
515
+ entityDistanceSquared(e, t, n) {
516
+ let r = this.entityPool.blockFor(e), i = this.entityPool.blockOffset(e);
517
+ return this.entityBlockDistanceSquared(r, i, t, n);
518
+ }
519
+ entityBlockDistanceSquared(e, t, n, r) {
520
+ let i = e[t + G], a = e[t + K];
521
+ return y(n, r, i, a, i + e[t + q], a + e[t + J]);
522
+ }
523
+ unlinkFromBucket(e, t, n, r) {
524
+ let i = this.nullIndex, a = this.getBucketSegment(e), o = this.bucketHeadSegments[e >>> j], s = this.bucketOffset(e), u = s + O;
525
+ c(a, u);
526
+ let d = s + k, f = this.slotPool, p = i, m = o[d];
527
+ for (; m !== i;) {
528
+ let e = f.blockFor(m), s = f.blockOffset(m), c = e[s + R];
529
+ if (e[s + N] === t && e[s + P] === n && e[s + F] === r) return p === i ? o[d] = c : f.set(p, R, c), l(a, u), m;
530
+ p = m, m = c;
531
+ }
532
+ return l(a, u), i;
533
+ }
534
+ };
535
+ function me(e) {
536
+ let t = a(e ?? fe);
537
+ if (t !== i.float32 && t !== i.float64) throw Error("SharedSpatialMap must be Float32Array or Float64Array");
538
+ return t;
539
+ }
540
+ function he(e) {
541
+ return o(e) === 2 ? Float64Array : Float32Array;
542
+ }
543
+ function ge(e) {
544
+ return e === i.float32 ? ie : ae;
545
+ }
546
+ function $(e) {
547
+ return e & e - 1 ? -1 : e - 1;
548
+ }
549
+ function _e(e) {
550
+ return 2 ** Math.ceil(Math.log2(Math.max(1, e)));
551
+ }
552
+ //#endregion
553
+ export { pe as default };
554
+
555
+ //# sourceMappingURL=shared-spatial-map.js.map