@daneren2005/shared-memory-objects 1.3.0 → 1.4.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 +56 -6
- package/dist/local-pool.d.ts +5 -5
- package/dist/local-pool.js +13 -10
- package/dist/local-pool.js.map +1 -1
- package/dist/lock/simple-lock.js +7 -2
- package/dist/lock/simple-lock.js.map +1 -1
- package/dist/shared-list.d.ts +9 -6
- package/dist/shared-list.js +43 -50
- package/dist/shared-list.js.map +1 -1
- package/dist/shared-map.d.ts +25 -10
- package/dist/shared-map.js +140 -80
- package/dist/shared-map.js.map +1 -1
- package/dist/shared-pool.d.ts +5 -5
- package/dist/shared-pool.js +35 -47
- package/dist/shared-pool.js.map +1 -1
- package/dist/shared-stack.d.ts +9 -8
- package/dist/shared-stack.js +65 -78
- package/dist/shared-stack.js.map +1 -1
- package/dist/shared-vector.d.ts +8 -6
- package/dist/shared-vector.js +34 -57
- package/dist/shared-vector.js.map +1 -1
- package/dist/utils/array-type.d.ts +20 -0
- package/dist/utils/array-type.js +36 -0
- package/dist/utils/array-type.js.map +1 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.js +21 -0
- package/dist/utils/hash.js.map +1 -0
- package/package.json +3 -2
package/dist/shared-vector.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { getPointer as e, loadPointer as t, storePointer as n, storeRawPointer as r } from "./utils/pointer.js";
|
|
2
2
|
import i from "./allocated-memory.js";
|
|
3
|
+
import { getArrayTypeCode as a, getByteMultipler as o, makeArrayView as s } from "./utils/array-type.js";
|
|
3
4
|
//#region src/shared-vector.ts
|
|
4
|
-
var
|
|
5
|
+
var c = 0, l = 1, u = 2, d = 3, f = 4, p = class p {
|
|
5
6
|
static ALLOCATE_COUNT = 4;
|
|
6
7
|
memory;
|
|
7
8
|
firstBlock;
|
|
8
9
|
uint16Array;
|
|
10
|
+
cachedByteMultipler = 1;
|
|
9
11
|
get length() {
|
|
10
|
-
return Atomics.load(this.firstBlock.data,
|
|
12
|
+
return Atomics.load(this.firstBlock.data, l);
|
|
11
13
|
}
|
|
12
14
|
get type() {
|
|
13
15
|
return this.uint16Array[0];
|
|
@@ -15,6 +17,9 @@ var a = 0, o = 1, s = 2, c = 3, l = 4, u = class u {
|
|
|
15
17
|
set type(e) {
|
|
16
18
|
Atomics.store(this.uint16Array, 0, e);
|
|
17
19
|
}
|
|
20
|
+
get byteMultipler() {
|
|
21
|
+
return this.cachedByteMultipler;
|
|
22
|
+
}
|
|
18
23
|
get dataLength() {
|
|
19
24
|
return this.uint16Array[1] || 1;
|
|
20
25
|
}
|
|
@@ -22,38 +27,32 @@ var a = 0, o = 1, s = 2, c = 3, l = 4, u = class u {
|
|
|
22
27
|
Atomics.store(this.uint16Array, 1, e);
|
|
23
28
|
}
|
|
24
29
|
get bufferLength() {
|
|
25
|
-
return Atomics.load(this.firstBlock.data,
|
|
30
|
+
return Atomics.load(this.firstBlock.data, u);
|
|
26
31
|
}
|
|
27
32
|
set bufferLength(e) {
|
|
28
|
-
Atomics.store(this.firstBlock.data,
|
|
33
|
+
Atomics.store(this.firstBlock.data, u, e);
|
|
29
34
|
}
|
|
30
35
|
get pointer() {
|
|
31
36
|
return this.firstBlock.pointer;
|
|
32
37
|
}
|
|
33
38
|
get usedMemory() {
|
|
34
|
-
let e = new i(this.memory, t(this.firstBlock.data,
|
|
39
|
+
let e = new i(this.memory, t(this.firstBlock.data, c));
|
|
35
40
|
return this.firstBlock.usedMemory + e.usedMemory;
|
|
36
41
|
}
|
|
37
42
|
cachedFullDataBlock;
|
|
38
43
|
cachedPointer;
|
|
39
44
|
constructor(e, t) {
|
|
40
45
|
if (this.memory = e, t && "firstBlock" in t) {
|
|
41
|
-
if (this.firstBlock = new i(e, t.firstBlock), this.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset +
|
|
42
|
-
let r = t.
|
|
43
|
-
n(this.firstBlock.data,
|
|
44
|
-
}
|
|
45
|
-
if ("type" in t) {
|
|
46
|
-
let e = t?.type ?? Uint32Array;
|
|
47
|
-
e === Uint32Array ? this.type = 0 : e === Int32Array ? this.type = 1 : e === Float32Array && (this.type = 2);
|
|
46
|
+
if (this.firstBlock = new i(e, t.firstBlock), this.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + d * Uint32Array.BYTES_PER_ELEMENT, 2), "type" in t || "dataLength" in t) {
|
|
47
|
+
let r = a(t.type ?? Uint32Array), i = o(r), s = t.bufferLength ?? f, l = e.allocUI32(s * (t.dataLength ?? 1) * i);
|
|
48
|
+
n(this.firstBlock.data, c, l.bufferPosition, l.bufferByteOffset), this.bufferLength = s, this.dataLength = t.dataLength ?? 1, this.type = r;
|
|
48
49
|
}
|
|
49
50
|
} else {
|
|
50
|
-
this.firstBlock = e.allocUI32(
|
|
51
|
-
let r = t?.dataLength ?? 1, i = t?.bufferLength ??
|
|
52
|
-
n(this.firstBlock.data,
|
|
53
|
-
let s = t?.type ?? Uint32Array;
|
|
54
|
-
s === Uint32Array ? this.type = 0 : s === Int32Array ? this.type = 1 : s === Float32Array && (this.type = 2), this.dataLength = r;
|
|
51
|
+
this.firstBlock = e.allocUI32(p.ALLOCATE_COUNT), this.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + d * Uint32Array.BYTES_PER_ELEMENT, 2);
|
|
52
|
+
let r = t?.dataLength ?? 1, i = t?.bufferLength ?? f, s = a(t?.type ?? Uint32Array), l = e.allocUI32(i * r * o(s));
|
|
53
|
+
n(this.firstBlock.data, c, l.bufferPosition, l.bufferByteOffset), this.bufferLength = i, this.type = s, this.dataLength = r;
|
|
55
54
|
}
|
|
56
|
-
this.cachedPointer = this.firstBlock.data[0], this.cachedFullDataBlock = this.getFullDataBlock();
|
|
55
|
+
this.cachedByteMultipler = o(this.type), this.cachedPointer = this.firstBlock.data[0], this.cachedFullDataBlock = this.getFullDataBlock();
|
|
57
56
|
}
|
|
58
57
|
at(e) {
|
|
59
58
|
let t = this.length;
|
|
@@ -67,17 +66,19 @@ var a = 0, o = 1, s = 2, c = 3, l = 4, u = class u {
|
|
|
67
66
|
return this.getFullDataBlock()[e * this.dataLength + t];
|
|
68
67
|
}
|
|
69
68
|
push(e) {
|
|
70
|
-
let t = this.dataLength, n = typeof e
|
|
69
|
+
let t = this.dataLength, n = typeof e != "object";
|
|
71
70
|
if (!n && e.length > t) throw Error(`Can't insert ${e.length} array into shared list of ${t} dataLength`);
|
|
72
71
|
let r = this.getFullDataBlock(), i = this.length, a = t * i;
|
|
73
|
-
|
|
72
|
+
if (n) r[a] = e;
|
|
73
|
+
else for (let t = 0; t < e.length; t++) r[a + t] = e[t];
|
|
74
|
+
return Atomics.add(this.firstBlock.data, l, 1) + 1 >= this.bufferLength && this.growBuffer(), i;
|
|
74
75
|
}
|
|
75
76
|
pop() {
|
|
76
|
-
let e = Atomics.sub(this.firstBlock.data,
|
|
77
|
+
let e = Atomics.sub(this.firstBlock.data, l, 1), t = this.getFullDataBlock();
|
|
77
78
|
return this.getDataBlock(t, e - 1);
|
|
78
79
|
}
|
|
79
80
|
popNumber() {
|
|
80
|
-
let e = Atomics.sub(this.firstBlock.data,
|
|
81
|
+
let e = Atomics.sub(this.firstBlock.data, l, 1);
|
|
81
82
|
return this.getFullDataBlock()[(e - 1) * this.dataLength];
|
|
82
83
|
}
|
|
83
84
|
deleteIndex(e) {
|
|
@@ -85,10 +86,10 @@ var a = 0, o = 1, s = 2, c = 3, l = 4, u = class u {
|
|
|
85
86
|
if (e >= t || e < 0) throw Error(`${e} is out of bounds ${t}`);
|
|
86
87
|
let n = this.dataLength, r = this.getFullDataBlock();
|
|
87
88
|
for (let i = e; i < t; i++) for (let e = 0; e < n; e++) r[i * n + e] = r[(i + 1) * n + e];
|
|
88
|
-
Atomics.sub(this.firstBlock.data,
|
|
89
|
+
Atomics.sub(this.firstBlock.data, l, 1);
|
|
89
90
|
}
|
|
90
91
|
clear() {
|
|
91
|
-
this.firstBlock.data[
|
|
92
|
+
this.firstBlock.data[l] = 0;
|
|
92
93
|
}
|
|
93
94
|
*[Symbol.iterator]() {
|
|
94
95
|
let e = this.getFullDataBlock(), t = this.dataLength, n = this.length * t;
|
|
@@ -98,47 +99,23 @@ var a = 0, o = 1, s = 2, c = 3, l = 4, u = class u {
|
|
|
98
99
|
return this.getFullDataBlock().subarray(0, this.length * this.dataLength);
|
|
99
100
|
}
|
|
100
101
|
getFullDataBlock() {
|
|
101
|
-
let t = Atomics.load(this.firstBlock.data,
|
|
102
|
+
let t = Atomics.load(this.firstBlock.data, c);
|
|
102
103
|
if (this.cachedPointer === t && this.cachedFullDataBlock) return this.cachedFullDataBlock;
|
|
103
|
-
let n = e(t), r = new i(this.memory, n),
|
|
104
|
-
|
|
105
|
-
case 1:
|
|
106
|
-
o = new Int32Array(r.data.buffer, r.bufferByteOffset, this.dataLength * this.bufferLength);
|
|
107
|
-
break;
|
|
108
|
-
case 0:
|
|
109
|
-
o = new Uint32Array(r.data.buffer, r.bufferByteOffset, this.dataLength * this.bufferLength);
|
|
110
|
-
break;
|
|
111
|
-
case 2:
|
|
112
|
-
o = new Float32Array(r.data.buffer, r.bufferByteOffset, this.dataLength * this.bufferLength);
|
|
113
|
-
break;
|
|
114
|
-
default: throw Error(`Unknown data block type ${this.type}`);
|
|
115
|
-
}
|
|
116
|
-
return this.cachedPointer = t, this.cachedFullDataBlock = o, o;
|
|
104
|
+
let n = e(t), r = new i(this.memory, n), a = s(this.type, r.data.buffer, r.bufferByteOffset, this.dataLength * this.bufferLength);
|
|
105
|
+
return this.cachedPointer = t, this.cachedFullDataBlock = a, a;
|
|
117
106
|
}
|
|
118
107
|
getDataBlock(e, t) {
|
|
119
108
|
let n = t * this.dataLength;
|
|
120
109
|
return e.subarray(n, n + this.dataLength);
|
|
121
110
|
}
|
|
122
111
|
growBuffer() {
|
|
123
|
-
let e = this.bufferLength * 2, n = this.dataLength,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
break;
|
|
128
|
-
case 0:
|
|
129
|
-
u = new Uint32Array(l.data.buffer, l.bufferByteOffset, n * e);
|
|
130
|
-
break;
|
|
131
|
-
case 2:
|
|
132
|
-
u = new Float32Array(l.data.buffer, l.bufferByteOffset, n * e);
|
|
133
|
-
break;
|
|
134
|
-
default: throw Error(`Unknown data block type ${this.type}`);
|
|
135
|
-
}
|
|
136
|
-
u.set(c);
|
|
137
|
-
let d = l.pointer;
|
|
138
|
-
r(this.firstBlock.data, a, d), this.bufferLength = e, s.free(), this.cachedPointer = d, this.cachedFullDataBlock = u;
|
|
112
|
+
let e = this.bufferLength * 2, n = this.dataLength, a = t(this.firstBlock.data, c), o = new i(this.memory, a), l = this.getFullDataBlock(), u = this.memory.allocUI32(e * n * this.cachedByteMultipler), d = s(this.type, u.data.buffer, u.bufferByteOffset, n * e);
|
|
113
|
+
d.set(l);
|
|
114
|
+
let f = u.pointer;
|
|
115
|
+
r(this.firstBlock.data, c, f), this.bufferLength = e, o.free(), this.cachedPointer = f, this.cachedFullDataBlock = d;
|
|
139
116
|
}
|
|
140
117
|
free() {
|
|
141
|
-
let e = t(this.firstBlock.data,
|
|
118
|
+
let e = t(this.firstBlock.data, c);
|
|
142
119
|
new i(this.memory, e).free(), this.firstBlock.free();
|
|
143
120
|
}
|
|
144
121
|
getSharedMemory() {
|
|
@@ -146,6 +123,6 @@ var a = 0, o = 1, s = 2, c = 3, l = 4, u = class u {
|
|
|
146
123
|
}
|
|
147
124
|
};
|
|
148
125
|
//#endregion
|
|
149
|
-
export {
|
|
126
|
+
export { p as default };
|
|
150
127
|
|
|
151
128
|
//# sourceMappingURL=shared-vector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-vector.js","names":[],"sources":["../src/shared-vector.ts"],"sourcesContent":["import type { SharedAllocatedMemory } from './allocated-memory';\nimport AllocatedMemory from './allocated-memory';\nimport type { TypedArrayConstructor } from './interfaces/typed-array-constructor';\nimport type MemoryHeap from './memory-heap';\nimport { getPointer, loadPointer, storePointer, storeRawPointer } from './utils/pointer';\n\nenum TYPE {\n\tuint32,\n\tint32,\n\tfloat32,\n}\n\nconst VECTOR_INDEX = 0;\nconst LENGTH_INDEX = 1;\nconst BUFFER_LENGTH_INDEX = 2;\nconst TYPE_INDEX = 3;\nconst DEFAULT_SIZE = 4;\nexport default class SharedVector<T extends Uint32Array | Int32Array | Float32Array = Uint32Array> implements Iterable<T> {\n\tstatic readonly ALLOCATE_COUNT = 4;\n\tprivate memory: MemoryHeap;\n\n\t// Pointer, List Length, Buffer Length, Type/DataLength\n\tprivate firstBlock: AllocatedMemory;\n\tprivate uint16Array: Uint16Array;\n\n\tget length(): number {\n\t\treturn Atomics.load(this.firstBlock.data, LENGTH_INDEX);\n\t}\n\t\n\tget type(): number {\n\t\treturn this.uint16Array[0];\n\t}\n\tprivate set type(value: number) {\n\t\tAtomics.store(this.uint16Array, 0, value);\n\t}\n\tget dataLength(): number {\n\t\t// Can technically be initialized by passing memory without actually every being called - need to make sure dataLength is always at least one\n\t\treturn this.uint16Array[1] || 1;\n\t}\n\tprivate set dataLength(value: number) {\n\t\tAtomics.store(this.uint16Array, 1, value);\n\t}\n\n\tget bufferLength(): number {\n\t\treturn Atomics.load(this.firstBlock.data, BUFFER_LENGTH_INDEX);\n\t}\n\tprivate set bufferLength(value: number) {\n\t\tAtomics.store(this.firstBlock.data, BUFFER_LENGTH_INDEX, value);\n\t}\n\n\tget pointer() {\n\t\treturn this.firstBlock.pointer;\n\t}\n\n\tget usedMemory(): number {\n\t\tlet dataMemory = new AllocatedMemory(this.memory, loadPointer(this.firstBlock.data, VECTOR_INDEX));\n\t\treturn this.firstBlock.usedMemory + dataMemory.usedMemory;\n\t}\n\n\tprivate cachedFullDataBlock?: T;\n\tprivate cachedPointer: number;\n\n\tconstructor(memory: MemoryHeap, config?: SharedVectorConfig<T> | SharedVectorMemory | SharedVectorMemory & SharedVectorConfig<T>) {\n\t\tthis.memory = memory;\n\n\t\tif(config && 'firstBlock' in config) {\n\t\t\tthis.firstBlock = new AllocatedMemory(memory, config.firstBlock);\n\t\t\tthis.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + TYPE_INDEX * Uint32Array.BYTES_PER_ELEMENT, 2);\n\n\t\t\t// Pre-allocating memory and setting up in specific memory location\n\t\t\tif('type' in config || 'dataLength' in config) {\n\t\t\t\tconst bufferLength = config.bufferLength ?? DEFAULT_SIZE;\n\t\t\t\tlet dataBlock = memory.allocUI32(bufferLength * (config.dataLength ?? 1));\n\t\t\t\tstorePointer(this.firstBlock.data, VECTOR_INDEX, dataBlock.bufferPosition, dataBlock.bufferByteOffset);\n\t\t\t\tthis.bufferLength = bufferLength;\n\t\t\t\tthis.dataLength = (config.dataLength ?? 1);\n\t\t\t}\n\t\t\tif('type' in config) {\n\t\t\t\tconst type = config?.type ?? Uint32Array;\n\t\t\t\tif(type === Uint32Array) {\n\t\t\t\t\tthis.type = TYPE.uint32;\n\t\t\t\t// @ts-expect-error\n\t\t\t\t} else if(type === Int32Array) {\n\t\t\t\t\tthis.type = TYPE.int32;\n\t\t\t\t// @ts-expect-error\n\t\t\t\t} else if(type === Float32Array) {\n\t\t\t\t\tthis.type = TYPE.float32;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.firstBlock = memory.allocUI32(SharedVector.ALLOCATE_COUNT);\n\t\t\tthis.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + TYPE_INDEX * Uint32Array.BYTES_PER_ELEMENT, 2);\n\n\t\t\tlet dataLength = config?.dataLength ?? 1;\n\t\t\tlet bufferLength = config?.bufferLength ?? DEFAULT_SIZE;\n\t\t\tlet dataBlock = memory.allocUI32(bufferLength * dataLength);\n\t\t\tstorePointer(this.firstBlock.data, VECTOR_INDEX, dataBlock.bufferPosition, dataBlock.bufferByteOffset);\n\t\t\tthis.bufferLength = bufferLength;\n\n\t\t\tconst type = config?.type ?? Uint32Array;\n\t\t\tif(type === Uint32Array) {\n\t\t\t\tthis.type = TYPE.uint32;\n\t\t\t// @ts-expect-error\n\t\t\t} else if(type === Int32Array) {\n\t\t\t\tthis.type = TYPE.int32;\n\t\t\t// @ts-expect-error\n\t\t\t} else if(type === Float32Array) {\n\t\t\t\tthis.type = TYPE.float32;\n\t\t\t}\n\t\t\tthis.dataLength = dataLength;\n\t\t}\n\n\t\tthis.cachedPointer = this.firstBlock.data[0];\n\t\tthis.cachedFullDataBlock = this.getFullDataBlock();\n\t}\n\n\tat(index: number): T {\n\t\tlet length = this.length;\n\t\tif(index >= length || index < 0) {\n\t\t\tthrow new Error(`${index} is out of bounds ${length}`);\n\t\t}\n\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\treturn this.getDataBlock(dataBlock, index);\n\t}\n\tget(index: number, dataIndex = 0): number {\n\t\tif(dataIndex >= this.dataLength) {\n\t\t\tthrow new Error(`${dataIndex} is out of dataLength bounds ${this.dataLength}`);\n\t\t} else if(index >= this.length || index < 0) {\n\t\t\tthrow new Error(`${index} is out of bounds ${this.length}`);\n\t\t}\n\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\treturn dataBlock[index * this.dataLength + dataIndex];\n\t}\n\n\tpush(values: number | Array<number>): number {\n\t\tlet dataLength = this.dataLength;\n\t\tconst isSingleNumber = typeof values === 'number';\n\t\tif(!isSingleNumber && values.length > dataLength) {\n\t\t\tthrow new Error(`Can't insert ${values.length} array into shared list of ${dataLength} dataLength`);\n\t\t}\n\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\tlet currentLength = this.length;\n\t\tlet startIndex = dataLength * currentLength;\n\t\tif(isSingleNumber) {\n\t\t\tdataBlock[startIndex] = values;\n\t\t} else {\n\t\t\tdataBlock.set(values, startIndex);\n\t\t}\n\n\t\tlet newLength = Atomics.add(this.firstBlock.data, LENGTH_INDEX, 1) + 1;\n\t\tif(newLength >= this.bufferLength) {\n\t\t\tthis.growBuffer();\n\t\t}\n\n\t\treturn currentLength;\n\t}\n\n\tpop(): T {\n\t\tlet oldLength = Atomics.sub(this.firstBlock.data, LENGTH_INDEX, 1);\n\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\treturn this.getDataBlock(dataBlock, oldLength - 1);\n\t}\n\n\t// Returns the first number irregardless of dataLength - faster way to pop if you don't care about the rest of the data block\n\tpopNumber(): number {\n\t\tconst oldLength = Atomics.sub(this.firstBlock.data, LENGTH_INDEX, 1);\n\t\tconst dataBlock = this.getFullDataBlock();\n\t\treturn dataBlock[(oldLength - 1) * this.dataLength];\n\t}\n\n\tdeleteIndex(index: number) {\n\t\tlet length = this.length;\n\t\tif(index >= length || index < 0) {\n\t\t\tthrow new Error(`${index} is out of bounds ${length}`);\n\t\t}\n\n\t\tlet dataLength = this.dataLength;\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\tfor(let i = index; i < length; i++) {\n\t\t\tfor(let j = 0; j < dataLength; j++) {\n\t\t\t\tdataBlock[i * dataLength + j] = dataBlock[(i + 1) * dataLength + j];\n\t\t\t}\n\t\t}\n\n\t\tAtomics.sub(this.firstBlock.data, LENGTH_INDEX, 1);\n\t}\n\n\tclear() {\n\t\tthis.firstBlock.data[LENGTH_INDEX] = 0;\n\t}\n\n\t*[Symbol.iterator]() {\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\tlet dataLength = this.dataLength;\n\t\tlet totalDataEntries = this.length * dataLength;\n\n\t\tfor(let i = 0; i < totalDataEntries; i += dataLength) {\n\t\t\tyield dataBlock.subarray(i, i + dataLength) as T;\n\t\t}\n\t}\n\n\t// Significantly faster but won't be thread safe if anything is removing/adding to it during iteration\n\tgetCurrentArray(): T {\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\treturn dataBlock.subarray(0, this.length * this.dataLength) as T;\n\t}\n\n\tprivate getFullDataBlock(): T {\n\t\tlet pointerNumber = Atomics.load(this.firstBlock.data, VECTOR_INDEX);\n\t\tif(this.cachedPointer === pointerNumber && this.cachedFullDataBlock) {\n\t\t\treturn this.cachedFullDataBlock;\n\t\t}\n\n\t\tlet pointer = getPointer(pointerNumber);\n\t\tlet rawData = new AllocatedMemory(this.memory, pointer);\n\n\t\tlet data: T;\n\t\tswitch(this.type) {\n\t\t\tcase TYPE.int32:\n\t\t\t\tdata = new Int32Array(rawData.data.buffer, rawData.bufferByteOffset, this.dataLength * this.bufferLength) as T;\n\t\t\t\tbreak;\n\t\t\tcase TYPE.uint32:\n\t\t\t\tdata = new Uint32Array(rawData.data.buffer, rawData.bufferByteOffset, this.dataLength * this.bufferLength) as T;\n\t\t\t\tbreak;\n\t\t\tcase TYPE.float32:\n\t\t\t\tdata = new Float32Array(rawData.data.buffer, rawData.bufferByteOffset, this.dataLength * this.bufferLength) as T;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown data block type ${this.type}`);\n\t\t}\n\n\t\tthis.cachedPointer = pointerNumber;\n\t\tthis.cachedFullDataBlock = data;\n\n\t\treturn data;\n\t}\n\tprivate getDataBlock(rawData: T, index: number): T {\n\t\tconst start = index * this.dataLength;\n\t\treturn rawData.subarray(start, start + this.dataLength) as T;\n\t}\n\n\tprivate growBuffer() {\n\t\tlet oldBufferLength = this.bufferLength;\n\t\tlet newBufferLength = oldBufferLength * 2;\n\t\tlet dataLength = this.dataLength;\n\n\t\tlet oldPointer = loadPointer(this.firstBlock.data, VECTOR_INDEX);\n\t\tlet oldDataMemory = new AllocatedMemory(this.memory, oldPointer);\n\t\tlet oldDataBlock = this.getFullDataBlock();\n\t\tlet newDataBlock = this.memory.allocUI32(newBufferLength * dataLength);\n\n\t\tlet newData: T;\n\t\tswitch(this.type) {\n\t\t\tcase TYPE.int32:\n\t\t\t\tnewData = new Int32Array(newDataBlock.data.buffer, newDataBlock.bufferByteOffset, dataLength * newBufferLength) as T;\n\t\t\t\tbreak;\n\t\t\tcase TYPE.uint32:\n\t\t\t\tnewData = new Uint32Array(newDataBlock.data.buffer, newDataBlock.bufferByteOffset, dataLength * newBufferLength) as T;\n\t\t\t\tbreak;\n\t\t\tcase TYPE.float32:\n\t\t\t\tnewData = new Float32Array(newDataBlock.data.buffer, newDataBlock.bufferByteOffset, dataLength * newBufferLength) as T;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown data block type ${this.type}`);\n\t\t}\n\n\t\t// Copy old buffer into new buffer\n\t\tnewData.set(oldDataBlock);\n\n\t\tconst newPointer = newDataBlock.pointer;\n\t\tstoreRawPointer(this.firstBlock.data, VECTOR_INDEX, newPointer);\n\t\tthis.bufferLength = newBufferLength;\n\t\toldDataMemory.free();\n\n\t\tthis.cachedPointer = newPointer;\n\t\tthis.cachedFullDataBlock = newData;\n\t}\n\n\tfree() {\n\t\tlet pointer = loadPointer(this.firstBlock.data, VECTOR_INDEX);\n\t\tlet dataMemory = new AllocatedMemory(this.memory, pointer);\n\n\t\tdataMemory.free();\n\t\tthis.firstBlock.free();\n\t}\n\n\tgetSharedMemory(): SharedVectorMemory {\n\t\treturn {\n\t\t\tfirstBlock: this.firstBlock.getSharedMemory(),\n\t\t};\n\t}\n}\n\ninterface SharedVectorConfig<T extends Uint32Array | Int32Array | Float32Array> {\n\ttype?: TypedArrayConstructor<T>\n\tdataLength?: number\n\n\tbufferLength?: number\n}\ninterface SharedVectorMemory {\n\tfirstBlock: SharedAllocatedMemory\n}\n\nexport type { SharedVectorConfig, SharedVectorMemory };"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shared-vector.js","names":[],"sources":["../src/shared-vector.ts"],"sourcesContent":["import type { SharedAllocatedMemory } from './allocated-memory';\nimport AllocatedMemory from './allocated-memory';\nimport type MemoryHeap from './memory-heap';\nimport { getPointer, loadPointer, storePointer, storeRawPointer } from './utils/pointer';\nimport { getArrayTypeCode, getByteMultipler, makeArrayView, type NumericArray, type NumericArrayIO, type TypedArrayConstructor } from './utils/array-type';\n\nconst VECTOR_INDEX = 0;\nconst LENGTH_INDEX = 1;\nconst BUFFER_LENGTH_INDEX = 2;\nconst TYPE_INDEX = 3;\nconst DEFAULT_SIZE = 4;\nexport default class SharedVector<T extends NumericArray = Uint32Array> implements Iterable<T> {\n\tstatic readonly ALLOCATE_COUNT = 4;\n\tprivate memory: MemoryHeap;\n\n\t// Pointer, List Length, Buffer Length, Type/DataLength\n\tprivate firstBlock: AllocatedMemory;\n\tprivate uint16Array: Uint16Array;\n\t// u32 units per element: 1 for 32-bit types, 2 for 64-bit (float64/int64/uint64). Every data-block allocation scales\n\t// by this; the typed view length stays in elements.\n\tprivate cachedByteMultipler = 1;\n\n\tget length(): number {\n\t\treturn Atomics.load(this.firstBlock.data, LENGTH_INDEX);\n\t}\n\t\n\tget type(): number {\n\t\treturn this.uint16Array[0];\n\t}\n\tprivate set type(value: number) {\n\t\tAtomics.store(this.uint16Array, 0, value);\n\t}\n\tget byteMultipler(): number {\n\t\treturn this.cachedByteMultipler;\n\t}\n\tget dataLength(): number {\n\t\t// Can technically be initialized by passing memory without actually every being called - need to make sure dataLength is always at least one\n\t\treturn this.uint16Array[1] || 1;\n\t}\n\tprivate set dataLength(value: number) {\n\t\tAtomics.store(this.uint16Array, 1, value);\n\t}\n\n\tget bufferLength(): number {\n\t\treturn Atomics.load(this.firstBlock.data, BUFFER_LENGTH_INDEX);\n\t}\n\tprivate set bufferLength(value: number) {\n\t\tAtomics.store(this.firstBlock.data, BUFFER_LENGTH_INDEX, value);\n\t}\n\n\tget pointer() {\n\t\treturn this.firstBlock.pointer;\n\t}\n\n\tget usedMemory(): number {\n\t\tlet dataMemory = new AllocatedMemory(this.memory, loadPointer(this.firstBlock.data, VECTOR_INDEX));\n\t\treturn this.firstBlock.usedMemory + dataMemory.usedMemory;\n\t}\n\n\tprivate cachedFullDataBlock?: T;\n\tprivate cachedPointer: number;\n\n\tconstructor(memory: MemoryHeap, config?: SharedVectorConfig<T> | SharedVectorMemory | SharedVectorMemory & SharedVectorConfig<T>) {\n\t\tthis.memory = memory;\n\n\t\tif(config && 'firstBlock' in config) {\n\t\t\tthis.firstBlock = new AllocatedMemory(memory, config.firstBlock);\n\t\t\tthis.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + TYPE_INDEX * Uint32Array.BYTES_PER_ELEMENT, 2);\n\n\t\t\t// Pre-allocating memory and setting up in specific memory location\n\t\t\tif('type' in config || 'dataLength' in config) {\n\t\t\t\tconst typeCode = getArrayTypeCode(config.type ?? Uint32Array);\n\t\t\t\tconst byteMultipler = getByteMultipler(typeCode);\n\t\t\t\tconst bufferLength = config.bufferLength ?? DEFAULT_SIZE;\n\t\t\t\tlet dataBlock = memory.allocUI32(bufferLength * (config.dataLength ?? 1) * byteMultipler);\n\t\t\t\tstorePointer(this.firstBlock.data, VECTOR_INDEX, dataBlock.bufferPosition, dataBlock.bufferByteOffset);\n\t\t\t\tthis.bufferLength = bufferLength;\n\t\t\t\tthis.dataLength = (config.dataLength ?? 1);\n\t\t\t\tthis.type = typeCode;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.firstBlock = memory.allocUI32(SharedVector.ALLOCATE_COUNT);\n\t\t\tthis.uint16Array = new Uint16Array(this.firstBlock.data.buffer, this.firstBlock.bufferByteOffset + TYPE_INDEX * Uint32Array.BYTES_PER_ELEMENT, 2);\n\n\t\t\tlet dataLength = config?.dataLength ?? 1;\n\t\t\tlet bufferLength = config?.bufferLength ?? DEFAULT_SIZE;\n\t\t\tlet typeCode = getArrayTypeCode(config?.type ?? Uint32Array);\n\t\t\tlet dataBlock = memory.allocUI32(bufferLength * dataLength * getByteMultipler(typeCode));\n\t\t\tstorePointer(this.firstBlock.data, VECTOR_INDEX, dataBlock.bufferPosition, dataBlock.bufferByteOffset);\n\t\t\tthis.bufferLength = bufferLength;\n\t\t\tthis.type = typeCode;\n\t\t\tthis.dataLength = dataLength;\n\t\t}\n\n\t\tthis.cachedByteMultipler = getByteMultipler(this.type);\n\t\tthis.cachedPointer = this.firstBlock.data[0];\n\t\tthis.cachedFullDataBlock = this.getFullDataBlock();\n\t}\n\n\tat(index: number): T {\n\t\tlet length = this.length;\n\t\tif(index >= length || index < 0) {\n\t\t\tthrow new Error(`${index} is out of bounds ${length}`);\n\t\t}\n\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\treturn this.getDataBlock(dataBlock, index);\n\t}\n\tget(index: number, dataIndex = 0): T[number] {\n\t\tif(dataIndex >= this.dataLength) {\n\t\t\tthrow new Error(`${dataIndex} is out of dataLength bounds ${this.dataLength}`);\n\t\t} else if(index >= this.length || index < 0) {\n\t\t\tthrow new Error(`${index} is out of bounds ${this.length}`);\n\t\t}\n\n\t\tlet dataBlock = this.getFullDataBlock() as NumericArrayIO;\n\t\treturn dataBlock[index * this.dataLength + dataIndex];\n\t}\n\n\tpush(values: T[number] | Array<T[number]>): number {\n\t\tlet dataLength = this.dataLength;\n\t\tconst isSingleValue = typeof values !== 'object';\n\t\tif(!isSingleValue && values.length > dataLength) {\n\t\t\tthrow new Error(`Can't insert ${values.length} array into shared list of ${dataLength} dataLength`);\n\t\t}\n\n\t\tlet dataBlock = this.getFullDataBlock() as NumericArrayIO;\n\t\tlet currentLength = this.length;\n\t\tlet startIndex = dataLength * currentLength;\n\t\tif(isSingleValue) {\n\t\t\tdataBlock[startIndex] = values;\n\t\t} else {\n\t\t\tfor(let i = 0; i < values.length; i++) {\n\t\t\t\tdataBlock[startIndex + i] = values[i];\n\t\t\t}\n\t\t}\n\n\t\tlet newLength = Atomics.add(this.firstBlock.data, LENGTH_INDEX, 1) + 1;\n\t\tif(newLength >= this.bufferLength) {\n\t\t\tthis.growBuffer();\n\t\t}\n\n\t\treturn currentLength;\n\t}\n\n\tpop(): T {\n\t\tlet oldLength = Atomics.sub(this.firstBlock.data, LENGTH_INDEX, 1);\n\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\treturn this.getDataBlock(dataBlock, oldLength - 1);\n\t}\n\n\t// Returns the first number irregardless of dataLength - faster way to pop if you don't care about the rest of the data block\n\tpopNumber(): T[number] {\n\t\tconst oldLength = Atomics.sub(this.firstBlock.data, LENGTH_INDEX, 1);\n\t\tconst dataBlock = this.getFullDataBlock() as NumericArrayIO;\n\t\treturn dataBlock[(oldLength - 1) * this.dataLength];\n\t}\n\n\tdeleteIndex(index: number) {\n\t\tlet length = this.length;\n\t\tif(index >= length || index < 0) {\n\t\t\tthrow new Error(`${index} is out of bounds ${length}`);\n\t\t}\n\n\t\tlet dataLength = this.dataLength;\n\t\tlet dataBlock = this.getFullDataBlock() as NumericArrayIO;\n\t\tfor(let i = index; i < length; i++) {\n\t\t\tfor(let j = 0; j < dataLength; j++) {\n\t\t\t\tdataBlock[i * dataLength + j] = dataBlock[(i + 1) * dataLength + j];\n\t\t\t}\n\t\t}\n\n\t\tAtomics.sub(this.firstBlock.data, LENGTH_INDEX, 1);\n\t}\n\n\tclear() {\n\t\tthis.firstBlock.data[LENGTH_INDEX] = 0;\n\t}\n\n\t*[Symbol.iterator]() {\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\tlet dataLength = this.dataLength;\n\t\tlet totalDataEntries = this.length * dataLength;\n\n\t\tfor(let i = 0; i < totalDataEntries; i += dataLength) {\n\t\t\tyield dataBlock.subarray(i, i + dataLength) as T;\n\t\t}\n\t}\n\n\t// Significantly faster but won't be thread safe if anything is removing/adding to it during iteration\n\tgetCurrentArray(): T {\n\t\tlet dataBlock = this.getFullDataBlock();\n\t\treturn dataBlock.subarray(0, this.length * this.dataLength) as T;\n\t}\n\n\tprivate getFullDataBlock(): T {\n\t\tlet pointerNumber = Atomics.load(this.firstBlock.data, VECTOR_INDEX);\n\t\tif(this.cachedPointer === pointerNumber && this.cachedFullDataBlock) {\n\t\t\treturn this.cachedFullDataBlock;\n\t\t}\n\n\t\tlet pointer = getPointer(pointerNumber);\n\t\tlet rawData = new AllocatedMemory(this.memory, pointer);\n\n\t\tlet data = makeArrayView(this.type, rawData.data.buffer, rawData.bufferByteOffset, this.dataLength * this.bufferLength) as T;\n\n\t\tthis.cachedPointer = pointerNumber;\n\t\tthis.cachedFullDataBlock = data;\n\n\t\treturn data;\n\t}\n\tprivate getDataBlock(rawData: T, index: number): T {\n\t\tconst start = index * this.dataLength;\n\t\treturn rawData.subarray(start, start + this.dataLength) as T;\n\t}\n\n\tprivate growBuffer() {\n\t\tlet oldBufferLength = this.bufferLength;\n\t\tlet newBufferLength = oldBufferLength * 2;\n\t\tlet dataLength = this.dataLength;\n\n\t\tlet oldPointer = loadPointer(this.firstBlock.data, VECTOR_INDEX);\n\t\tlet oldDataMemory = new AllocatedMemory(this.memory, oldPointer);\n\t\tlet oldDataBlock = this.getFullDataBlock();\n\t\tlet newDataBlock = this.memory.allocUI32(newBufferLength * dataLength * this.cachedByteMultipler);\n\n\t\tlet newData = makeArrayView(this.type, newDataBlock.data.buffer, newDataBlock.bufferByteOffset, dataLength * newBufferLength) as T;\n\n\t\t// newData and oldDataBlock are the same concrete view type, so a direct copy is valid; the cast only bridges the\n\t\t// union's mutually-incompatible set() overloads (number vs bigint element types)\n\t\t(newData as Float64Array).set(oldDataBlock as unknown as Float64Array);\n\n\t\tconst newPointer = newDataBlock.pointer;\n\t\tstoreRawPointer(this.firstBlock.data, VECTOR_INDEX, newPointer);\n\t\tthis.bufferLength = newBufferLength;\n\t\toldDataMemory.free();\n\n\t\tthis.cachedPointer = newPointer;\n\t\tthis.cachedFullDataBlock = newData;\n\t}\n\n\tfree() {\n\t\tlet pointer = loadPointer(this.firstBlock.data, VECTOR_INDEX);\n\t\tlet dataMemory = new AllocatedMemory(this.memory, pointer);\n\n\t\tdataMemory.free();\n\t\tthis.firstBlock.free();\n\t}\n\n\tgetSharedMemory(): SharedVectorMemory {\n\t\treturn {\n\t\t\tfirstBlock: this.firstBlock.getSharedMemory(),\n\t\t};\n\t}\n}\n\ninterface SharedVectorConfig<T extends NumericArray> {\n\ttype?: TypedArrayConstructor<T>\n\tdataLength?: number\n\n\tbufferLength?: number\n}\ninterface SharedVectorMemory {\n\tfirstBlock: SharedAllocatedMemory\n}\n\nexport type { SharedVectorConfig, SharedVectorMemory };"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TypedArrayConstructor } from '../interfaces/typed-array-constructor';
|
|
2
|
+
type NumericArray = Uint32Array | Int32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
|
|
3
|
+
declare const ARRAY_TYPE: {
|
|
4
|
+
readonly uint32: 0;
|
|
5
|
+
readonly int32: 1;
|
|
6
|
+
readonly float32: 2;
|
|
7
|
+
readonly float64: 3;
|
|
8
|
+
readonly int64: 4;
|
|
9
|
+
readonly uint64: 5;
|
|
10
|
+
};
|
|
11
|
+
type NumericArrayIO = {
|
|
12
|
+
[index: number]: number | bigint;
|
|
13
|
+
};
|
|
14
|
+
declare function getArrayTypeCode(type: unknown): number;
|
|
15
|
+
declare function getByteMultipler(typeCode: number): number;
|
|
16
|
+
declare function isBigIntType(typeCode: number): boolean;
|
|
17
|
+
declare function isFloatType(typeCode: number): boolean;
|
|
18
|
+
declare function makeArrayView(typeCode: number, buffer: ArrayBufferLike, byteOffset: number, length: number): NumericArray;
|
|
19
|
+
export { ARRAY_TYPE, getArrayTypeCode, getByteMultipler, isBigIntType, isFloatType, makeArrayView };
|
|
20
|
+
export type { NumericArray, NumericArrayIO, TypedArrayConstructor };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/utils/array-type.ts
|
|
2
|
+
var e = {
|
|
3
|
+
uint32: 0,
|
|
4
|
+
int32: 1,
|
|
5
|
+
float32: 2,
|
|
6
|
+
float64: 3,
|
|
7
|
+
int64: 4,
|
|
8
|
+
uint64: 5
|
|
9
|
+
};
|
|
10
|
+
function t(t) {
|
|
11
|
+
return t === Int32Array ? e.int32 : t === Float32Array ? e.float32 : t === Float64Array ? e.float64 : t === BigInt64Array ? e.int64 : t === BigUint64Array ? e.uint64 : e.uint32;
|
|
12
|
+
}
|
|
13
|
+
function n(t) {
|
|
14
|
+
return t >= e.float64 ? 2 : 1;
|
|
15
|
+
}
|
|
16
|
+
function r(t) {
|
|
17
|
+
return t === e.int64 || t === e.uint64;
|
|
18
|
+
}
|
|
19
|
+
function i(t) {
|
|
20
|
+
return t === e.float32 || t === e.float64;
|
|
21
|
+
}
|
|
22
|
+
function a(t, n, r, i) {
|
|
23
|
+
switch (t) {
|
|
24
|
+
case e.int32: return new Int32Array(n, r, i);
|
|
25
|
+
case e.float32: return new Float32Array(n, r, i);
|
|
26
|
+
case e.float64: return new Float64Array(n, r, i);
|
|
27
|
+
case e.int64: return new BigInt64Array(n, r, i);
|
|
28
|
+
case e.uint64: return new BigUint64Array(n, r, i);
|
|
29
|
+
case e.uint32: return new Uint32Array(n, r, i);
|
|
30
|
+
default: throw Error(`Unknown data block type ${t}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { e as ARRAY_TYPE, t as getArrayTypeCode, n as getByteMultipler, r as isBigIntType, i as isFloatType, a as makeArrayView };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=array-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array-type.js","names":[],"sources":["../../src/utils/array-type.ts"],"sourcesContent":["import type { TypedArrayConstructor } from '../interfaces/typed-array-constructor';\n\n// Every numeric view a data structure can store values in. The BigInt views (int64/uint64) carry bigint elements;\n// all others carry number. A view's scalar type is T[number], so public signatures derive it straight from T.\ntype NumericArray = Uint32Array | Int32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;\n\n// Persisted in shared memory (the TYPE slot), so the order is append-only - never renumber an existing entry.\nconst ARRAY_TYPE = {\n\tuint32: 0,\n\tint32: 1,\n\tfloat32: 2,\n\tfloat64: 3,\n\tint64: 4,\n\tuint64: 5,\n} as const;\n\n// A numeric view whose element getter/setter accepts number or bigint. TypeScript can't prove `view[i] = value` on a\n// generic (possibly-bigint) view because the union's index signatures collapse to `never`; going through this alias\n// keeps the write type-safe at the boundary. Types are erased, so the emitted store is identical to a direct one.\ntype NumericArrayIO = { [index: number]: number | bigint };\n\nfunction getArrayTypeCode(type: unknown): number {\n\tif(type === Int32Array) {\n\t\treturn ARRAY_TYPE.int32;\n\t} else if(type === Float32Array) {\n\t\treturn ARRAY_TYPE.float32;\n\t} else if(type === Float64Array) {\n\t\treturn ARRAY_TYPE.float64;\n\t} else if(type === BigInt64Array) {\n\t\treturn ARRAY_TYPE.int64;\n\t} else if(type === BigUint64Array) {\n\t\treturn ARRAY_TYPE.uint64;\n\t} else {\n\t\treturn ARRAY_TYPE.uint32;\n\t}\n}\n\n// 64-bit elements occupy two u32 allocation units; everything else occupies one. Callers size blocks as count * this.\nfunction getByteMultipler(typeCode: number): number {\n\treturn typeCode >= ARRAY_TYPE.float64 ? 2 : 1;\n}\n\nfunction isBigIntType(typeCode: number): boolean {\n\treturn typeCode === ARRAY_TYPE.int64 || typeCode === ARRAY_TYPE.uint64;\n}\n\n// Float views don't support Atomics; callers that publish elements atomically must fall back to a plain store for these.\nfunction isFloatType(typeCode: number): boolean {\n\treturn typeCode === ARRAY_TYPE.float32 || typeCode === ARRAY_TYPE.float64;\n}\n\n// Builds the typed view for a resolved type code. `length` is the element count (not u32 units); for 64-bit types the\n// backing block must already reserve length * getByteMultipler(typeCode) u32s.\nfunction makeArrayView(typeCode: number, buffer: ArrayBufferLike, byteOffset: number, length: number): NumericArray {\n\tswitch(typeCode) {\n\t\tcase ARRAY_TYPE.int32:\n\t\t\treturn new Int32Array(buffer, byteOffset, length);\n\t\tcase ARRAY_TYPE.float32:\n\t\t\treturn new Float32Array(buffer, byteOffset, length);\n\t\tcase ARRAY_TYPE.float64:\n\t\t\treturn new Float64Array(buffer, byteOffset, length);\n\t\tcase ARRAY_TYPE.int64:\n\t\t\treturn new BigInt64Array(buffer, byteOffset, length);\n\t\tcase ARRAY_TYPE.uint64:\n\t\t\treturn new BigUint64Array(buffer, byteOffset, length);\n\t\tcase ARRAY_TYPE.uint32:\n\t\t\treturn new Uint32Array(buffer, byteOffset, length);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown data block type ${typeCode}`);\n\t}\n}\n\nexport { ARRAY_TYPE, getArrayTypeCode, getByteMultipler, isBigIntType, isFloatType, makeArrayView };\nexport type { NumericArray, NumericArrayIO, TypedArrayConstructor };\n"],"mappings":";AAOA,IAAM,IAAa;CAClB,QAAQ;CACR,OAAO;CACP,SAAS;CACT,SAAS;CACT,OAAO;CACP,QAAQ;AACT;AAOA,SAAS,EAAiB,GAAuB;CAY/C,OAXE,MAAS,aACJ,EAAW,QACT,MAAS,eACX,EAAW,UACT,MAAS,eACX,EAAW,UACT,MAAS,gBACX,EAAW,QACT,MAAS,iBACX,EAAW,SAEX,EAAW;AAEpB;AAGA,SAAS,EAAiB,GAA0B;CACnD,OAAO,KAAY,EAAW,UAAU,IAAI;AAC7C;AAEA,SAAS,EAAa,GAA2B;CAChD,OAAO,MAAa,EAAW,SAAS,MAAa,EAAW;AACjE;AAGA,SAAS,EAAY,GAA2B;CAC/C,OAAO,MAAa,EAAW,WAAW,MAAa,EAAW;AACnE;AAIA,SAAS,EAAc,GAAkB,GAAyB,GAAoB,GAA8B;CACnH,QAAO,GAAP;EACC,KAAK,EAAW,OACf,OAAO,IAAI,WAAW,GAAQ,GAAY,CAAM;EACjD,KAAK,EAAW,SACf,OAAO,IAAI,aAAa,GAAQ,GAAY,CAAM;EACnD,KAAK,EAAW,SACf,OAAO,IAAI,aAAa,GAAQ,GAAY,CAAM;EACnD,KAAK,EAAW,OACf,OAAO,IAAI,cAAc,GAAQ,GAAY,CAAM;EACpD,KAAK,EAAW,QACf,OAAO,IAAI,eAAe,GAAQ,GAAY,CAAM;EACrD,KAAK,EAAW,QACf,OAAO,IAAI,YAAY,GAAQ,GAAY,CAAM;EAClD,SACC,MAAU,MAAM,2BAA2B,GAAU;CACvD;AACD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/utils/hash.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
return typeof e == "number" ? e : typeof e == "string" ? t(e) : e;
|
|
4
|
+
}
|
|
5
|
+
function t(e) {
|
|
6
|
+
let t = e.length, n = 17 ^ t, r = 0, i;
|
|
7
|
+
for (; t >= 4;) i = e.charCodeAt(r) & 255 | (e.charCodeAt(++r) & 255) << 8 | (e.charCodeAt(++r) & 255) << 16 | (e.charCodeAt(++r) & 255) << 14, i = (i & 65535) * 1540483477 + (((i >>> 16) * 1540483477 & 65535) << 16), i ^= i >>> 14, i = (i & 65535) * 1540483477 + (((i >>> 16) * 1540483477 & 65535) << 16), n = (n & 65535) * 1540483477 + (((n >>> 16) * 1540483477 & 65535) << 16) ^ i, t -= 4, ++r;
|
|
8
|
+
switch (t) {
|
|
9
|
+
case 3: n ^= (e.charCodeAt(r + 2) & 255) << 16;
|
|
10
|
+
case 2: n ^= (e.charCodeAt(r + 1) & 255) << 8;
|
|
11
|
+
case 1: n ^= e.charCodeAt(r) & 255, n = (n & 65535) * 1540483477 + (((n >>> 16) * 1540483477 & 65535) << 16);
|
|
12
|
+
}
|
|
13
|
+
return n ^= n >>> 13, n = (n & 65535) * 1540483477 + (((n >>> 16) * 1540483477 & 65535) << 16), n ^= n >>> 15, n >>>= 0, n;
|
|
14
|
+
}
|
|
15
|
+
function n(e) {
|
|
16
|
+
return e = Math.imul(e ^ e >>> 16, 73244475), e = Math.imul(e ^ e >>> 16, 73244475), e = (e ^ e >>> 16) >>> 0, e;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { e as get32BitHash, t as hashString, n as mix32 };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","names":[],"sources":["../../src/utils/hash.ts"],"sourcesContent":["export function get32BitHash<K extends string | number>(key: K): number {\n\tif(typeof key === 'number') {\n\t\treturn key;\n\t} else if(typeof key === 'string') {\n\t\treturn hashString(key);\n\t} else {\n\t\treturn key;\n\t}\n}\n\n// Copied from https://github.com/mmomtchev/SharedMap/blob/master/index.js - MurmurHash2\nexport function hashString(str: string): number {\n\tlet\n\t\tl = str.length,\n\t\th = 17 ^ l,\n\t\ti = 0,\n\t\tk;\n\twhile(l >= 4) {\n\t\tk =\n\t\t\t((str.charCodeAt(i) & 0xff)) |\n\t\t\t((str.charCodeAt(++i) & 0xff) << 8) |\n\t\t\t((str.charCodeAt(++i) & 0xff) << 16) |\n\t\t\t((str.charCodeAt(++i) & 0xff) << 14);\n\t\tk = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n\t\tk ^= k >>> 14;\n\t\tk = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n\t\th = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;\n\t\tl -= 4;\n\t\t++i;\n\t}\n\t/* eslint-disable no-fallthrough */\n\tswitch(l) {\n\t\tcase 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16;\n\t\tcase 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8;\n\t\tcase 1: h ^= (str.charCodeAt(i) & 0xff);\n\t\t\th = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n\t}\n\t/* eslint-enable no-fallthrough */\n\th ^= h >>> 13;\n\th = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n\th ^= h >>> 15;\n\th = h >>> 0;\n\treturn h;\n}\n\n// Fibonacci/avalanche mix so patterned integer keys (e.g. sequential ids) spread across a power-of-two table instead of\n// clustering. Returns an unsigned 32-bit value; callers mask with (capacity - 1).\nexport function mix32(h: number): number {\n\th = Math.imul(h ^ (h >>> 16), 0x45d9f3b);\n\th = Math.imul(h ^ (h >>> 16), 0x45d9f3b);\n\th = (h ^ (h >>> 16)) >>> 0;\n\treturn h;\n}\n"],"mappings":";AAAA,SAAgB,EAAwC,GAAgB;CAMtE,OALE,OAAO,KAAQ,WACV,IACE,OAAO,KAAQ,WACjB,EAAW,CAAG,IAEd;AAET;AAGA,SAAgB,EAAW,GAAqB;CAC/C,IACC,IAAI,EAAI,QACR,IAAI,KAAK,GACT,IAAI,GACJ;CACD,OAAM,KAAK,IAWV,AAVA,IACG,EAAI,WAAW,CAAC,IAAI,OACpB,EAAI,WAAW,EAAE,CAAC,IAAI,QAAS,KAC/B,EAAI,WAAW,EAAE,CAAC,IAAI,QAAS,MAC/B,EAAI,WAAW,EAAE,CAAC,IAAI,QAAS,IAClC,KAAO,IAAI,SAAU,gBAAkB,MAAM,MAAM,aAAc,UAAW,KAC5E,KAAK,MAAM,IACX,KAAO,IAAI,SAAU,gBAAkB,MAAM,MAAM,aAAc,UAAW,KAC5E,KAAO,IAAI,SAAU,gBAAkB,MAAM,MAAM,aAAc,UAAW,MAAO,GACnF,KAAK,GACL,EAAE;CAGH,QAAO,GAAP;EACC,KAAK,GAAG,MAAM,EAAI,WAAW,IAAI,CAAC,IAAI,QAAS;EAC/C,KAAK,GAAG,MAAM,EAAI,WAAW,IAAI,CAAC,IAAI,QAAS;EAC/C,KAAK,GACJ,AADO,KAAM,EAAI,WAAW,CAAC,IAAI,KACjC,KAAO,IAAI,SAAU,gBAAkB,MAAM,MAAM,aAAc,UAAW;CAC9E;CAMA,OAJA,KAAK,MAAM,IACX,KAAO,IAAI,SAAU,gBAAkB,MAAM,MAAM,aAAc,UAAW,KAC5E,KAAK,MAAM,IACX,OAAU,GACH;AACR;AAIA,SAAgB,EAAM,GAAmB;CAIxC,OAHA,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,QAAS,GACvC,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,QAAS,GACvC,KAAK,IAAK,MAAM,QAAS,GAClB;AACR"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daneren2005/shared-memory-objects",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"author": "daneren2005@gmail.com",
|
|
5
5
|
"description": "Creating objects with a SharedArrayBuffer",
|
|
6
6
|
"homepage": "https://github.com/daneren2005/shared-memory-objects#readme",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"release": "semantic-release",
|
|
39
39
|
"start": "npm run dev",
|
|
40
40
|
"test:bench": "vitest bench --run",
|
|
41
|
-
"test:stress": "npm run build && node scripts/stress-shared-list.mjs",
|
|
41
|
+
"test:stress:list": "npm run build && node scripts/stress-shared-list.mjs",
|
|
42
|
+
"test:stress:map": "npm run build && node scripts/stress-shared-map.mjs",
|
|
42
43
|
"test:bench:watch": "vitest bench",
|
|
43
44
|
"test:ui": "vitest --ui --api 9527",
|
|
44
45
|
"test:unit": "vitest run",
|