@daneren2005/shared-memory-objects 1.1.0 → 1.3.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 +91 -56
- package/dist/{src/allocated-memory.d.ts → allocated-memory.d.ts} +6 -4
- package/dist/allocated-memory.js +47 -37
- package/dist/allocated-memory.js.map +1 -1
- package/dist/{src/cached-item-list.d.ts → cached-item-list.d.ts} +5 -4
- package/dist/cached-item-list.js +75 -75
- package/dist/cached-item-list.js.map +1 -1
- package/dist/constant-string.d.ts +15 -0
- package/dist/constant-string.js +67 -0
- package/dist/constant-string.js.map +1 -0
- package/dist/interfaces/pow2.js +0 -2
- package/dist/interfaces/typed-array-constructor.js +0 -2
- package/dist/interfaces/typed-array.js +0 -2
- package/dist/{src/local-pool.d.ts → local-pool.d.ts} +2 -2
- package/dist/local-pool.js +89 -94
- package/dist/local-pool.js.map +1 -1
- package/dist/lock/read-write-lock.js +15 -21
- package/dist/lock/read-write-lock.js.map +1 -1
- package/dist/lock/simple-lock.js +9 -12
- package/dist/lock/simple-lock.js.map +1 -1
- package/dist/{src/memory-buffer.d.ts → memory-buffer.d.ts} +8 -5
- package/dist/memory-buffer.js +269 -326
- package/dist/memory-buffer.js.map +1 -1
- package/dist/{src/memory-heap.d.ts → memory-heap.d.ts} +4 -2
- package/dist/memory-heap.js +105 -115
- package/dist/memory-heap.js.map +1 -1
- package/dist/{src/serialize-object.d.ts → serialize-object.d.ts} +2 -2
- package/dist/serialize-object.js +43 -55
- package/dist/serialize-object.js.map +1 -1
- package/dist/{src/shared-list.d.ts → shared-list.d.ts} +11 -5
- package/dist/shared-list.js +162 -164
- package/dist/shared-list.js.map +1 -1
- package/dist/{src/shared-map.d.ts → shared-map.d.ts} +2 -2
- package/dist/shared-map.js +105 -138
- package/dist/shared-map.js.map +1 -1
- package/dist/{src/shared-pointer-list.d.ts → shared-pointer-list.d.ts} +4 -3
- package/dist/shared-pointer-list.js +49 -48
- package/dist/shared-pointer-list.js.map +1 -1
- package/dist/{src/shared-pool.d.ts → shared-pool.d.ts} +15 -8
- package/dist/shared-pool.js +151 -164
- package/dist/shared-pool.js.map +1 -1
- package/dist/shared-stack.d.ts +59 -0
- package/dist/shared-stack.js +221 -0
- package/dist/shared-stack.js.map +1 -0
- package/dist/{src/shared-string.d.ts → shared-string.d.ts} +2 -2
- package/dist/shared-string.js +72 -78
- package/dist/shared-string.js.map +1 -1
- package/dist/{src/shared-vector.d.ts → shared-vector.d.ts} +5 -4
- package/dist/shared-vector.js +150 -164
- package/dist/shared-vector.js.map +1 -1
- package/dist/utils/16-from-32-array.js +14 -16
- package/dist/utils/16-from-32-array.js.map +1 -1
- package/dist/utils/16-from-64-array.js +15 -10
- package/dist/utils/16-from-64-array.js.map +1 -1
- package/dist/utils/atomic-math.js +30 -32
- package/dist/utils/atomic-math.js.map +1 -1
- package/dist/utils/float32-atomics.js +18 -22
- package/dist/utils/float32-atomics.js.map +1 -1
- package/dist/utils/float64-atomics.js +18 -22
- package/dist/utils/float64-atomics.js.map +1 -1
- package/dist/utils/pointer.js +34 -44
- package/dist/utils/pointer.js.map +1 -1
- package/dist/{src/utils → utils}/typedarray.d.ts +47 -47
- package/dist/utils/typedarray.js +36 -43
- package/dist/utils/typedarray.js.map +1 -1
- package/package.json +23 -22
- package/dist/interfaces/pow2.js.map +0 -1
- package/dist/interfaces/typed-array-constructor.js.map +0 -1
- package/dist/interfaces/typed-array.js.map +0 -1
- /package/dist/{src/interfaces → interfaces}/pow2.d.ts +0 -0
- /package/dist/{src/interfaces → interfaces}/typed-array-constructor.d.ts +0 -0
- /package/dist/{src/interfaces → interfaces}/typed-array.d.ts +0 -0
- /package/dist/{src/lock → lock}/read-write-lock.d.ts +0 -0
- /package/dist/{src/lock → lock}/simple-lock.d.ts +0 -0
- /package/dist/{src/utils → utils}/16-from-32-array.d.ts +0 -0
- /package/dist/{src/utils → utils}/16-from-64-array.d.ts +0 -0
- /package/dist/{src/utils → utils}/atomic-math.d.ts +0 -0
- /package/dist/{src/utils → utils}/float32-atomics.d.ts +0 -0
- /package/dist/{src/utils → utils}/float64-atomics.d.ts +0 -0
- /package/dist/{src/utils → utils}/pointer.d.ts +0 -0
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constant-string.js","names":[],"sources":["../src/constant-string.ts"],"sourcesContent":["import AllocatedMemory from './allocated-memory';\nimport type { SharedAllocatedMemory } from './allocated-memory';\nimport type MemoryHeap from './memory-heap';\nimport { getPointer, loadRawPointer, storeRawPointer } from './utils/pointer';\n\nenum CHAR_TYPE {\n\tUNDEFINED,\n\tASCII,\n\tUTF16,\n}\nconst TYPED_ARRAY_MAP = {\n\t[CHAR_TYPE.ASCII]: Uint8Array,\n\t[CHAR_TYPE.UTF16]: Uint16Array,\n};\n\nconst POINTER_INDEX = 0;\nconst LENGTH_INDEX = 1;\nconst TYPE_INDEX = 2;\n\n// An immutable SharedString: the value is written once at construction and never changes\nexport default class ConstantString {\n\tstatic readonly ALLOCATE_COUNT = 3;\n\n\tprivate memory: MemoryHeap;\n\tprivate allocatedMemory: AllocatedMemory;\n\n\treadonly value: string;\n\n\tconstructor(memory: MemoryHeap, value: string | SharedAllocatedMemory) {\n\t\tthis.memory = memory;\n\n\t\tif(typeof value === 'string') {\n\t\t\tthis.allocatedMemory = this.memory.allocUI32(ConstantString.ALLOCATE_COUNT);\n\t\t\tthis.writeString(value);\n\t\t\tthis.value = value;\n\t\t} else {\n\t\t\t// A read-only view over a header another thread already wrote.\n\t\t\tthis.allocatedMemory = new AllocatedMemory(memory, value);\n\t\t\tthis.value = this.readString();\n\t\t}\n\t}\n\n\tprivate writeString(value: string) {\n\t\tconst stringMemory = this.createString(value);\n\n\t\tstoreRawPointer(this.allocatedMemory.data, POINTER_INDEX, stringMemory.pointer);\n\t\tAtomics.store(this.allocatedMemory.data, LENGTH_INDEX, value.length);\n\t\tAtomics.store(this.allocatedMemory.data, TYPE_INDEX, stringMemory.charType);\n\t}\n\n\tprivate readString(): string {\n\t\tlet pointer = loadRawPointer(this.allocatedMemory.data, POINTER_INDEX);\n\t\tif(pointer === 0) {\n\t\t\treturn '';\n\t\t}\n\t\tlet { bufferPosition, bufferByteOffset } = getPointer(pointer);\n\n\t\t// No lock: the value never changes after it is written once, so the memory it points at is never freed or\n\t\t// rewritten underneath us.\n\t\tlet charType = Atomics.load(this.allocatedMemory.data, TYPE_INDEX);\n\t\t// @ts-expect-error\n\t\tlet typedArray = TYPED_ARRAY_MAP[charType];\n\t\tlet bufferLength = Atomics.load(this.allocatedMemory.data, LENGTH_INDEX);\n\n\t\tlet data = new typedArray(this.memory.buffers[bufferPosition].buf, bufferByteOffset, bufferLength);\n\t\treturn fromCharCodes(data);\n\t}\n\tprivate createString(value: string) {\n\t\tif(value === '') {\n\t\t\treturn {\n\t\t\t\tpointer: 0,\n\t\t\t\tcharType: CHAR_TYPE.ASCII,\n\t\t\t};\n\t\t}\n\n\t\t// NOTE: Scan with a loop instead of Math.max(...charCodes) which blows the stack for large strings\n\t\tlet maxCharCode = 0;\n\t\tfor(let i = 0; i < value.length; i++) {\n\t\t\tlet charCode = value.charCodeAt(i);\n\t\t\tif(charCode > maxCharCode) {\n\t\t\t\tmaxCharCode = charCode;\n\t\t\t}\n\t\t}\n\t\tlet charType = maxCharCode > 255 ? CHAR_TYPE.UTF16 : CHAR_TYPE.ASCII;\n\n\t\tlet typedArray = TYPED_ARRAY_MAP[charType];\n\t\tlet allocatedMemory = this.memory.allocUI32(Math.ceil(value.length / (4 / typedArray.BYTES_PER_ELEMENT)));\n\t\tlet data = new typedArray(allocatedMemory.data.buffer as ArrayBuffer, allocatedMemory.data.byteOffset, value.length);\n\t\tfor(let i = 0; i < value.length; i++) {\n\t\t\tdata[i] = value.charCodeAt(i);\n\t\t}\n\n\t\treturn {\n\t\t\tpointer: allocatedMemory.pointer,\n\t\t\tcharType,\n\t\t};\n\t}\n\n\tgetSharedMemory(): SharedAllocatedMemory {\n\t\treturn this.allocatedMemory.getSharedMemory();\n\t}\n\n\tget pointer() {\n\t\treturn this.allocatedMemory.pointer;\n\t}\n\n\tfree() {\n\t\tlet pointer = loadRawPointer(this.allocatedMemory.data, POINTER_INDEX);\n\t\tif(pointer) {\n\t\t\tlet { bufferPosition, bufferByteOffset } = getPointer(pointer);\n\t\t\tthis.memory.buffers[bufferPosition].free(bufferByteOffset);\n\t\t}\n\t\tthis.allocatedMemory.free();\n\t}\n}\n\n// String.fromCharCode.apply throws a RangeError (Maximum call stack size exceeded) when handed too many\n// arguments at once, so decode large buffers in chunks to support arbitrarily long strings\nfunction fromCharCodes(data: Uint8Array | Uint16Array): string {\n\tconst CHUNK_SIZE = 8192;\n\tif(data.length <= CHUNK_SIZE) {\n\t\treturn String.fromCharCode.apply(null, data as unknown as Array<number>);\n\t}\n\n\tlet string = '';\n\tfor(let i = 0; i < data.length; i += CHUNK_SIZE) {\n\t\tstring += String.fromCharCode.apply(null, data.subarray(i, i + CHUNK_SIZE) as unknown as Array<number>);\n\t}\n\n\treturn string;\n}\n"],"mappings":";;;AAUA,IAAM,IAAkB;CACJ,GAAA;CACA,GAAA;AACpB,GAEM,IAAgB,GAChB,IAAe,GACf,IAAa,GAGE,IAArB,MAAqB,EAAe;CACnC,OAAgB,iBAAiB;CAEjC;CACA;CAEA;CAEA,YAAY,GAAoB,GAAuC;EAGtE,AAFA,KAAK,SAAS,GAEX,OAAO,KAAU,YACnB,KAAK,kBAAkB,KAAK,OAAO,UAAU,EAAe,cAAc,GAC1E,KAAK,YAAY,CAAK,GACtB,KAAK,QAAQ,MAGb,KAAK,kBAAkB,IAAI,EAAgB,GAAQ,CAAK,GACxD,KAAK,QAAQ,KAAK,WAAW;CAE/B;CAEA,YAAoB,GAAe;EAClC,IAAM,IAAe,KAAK,aAAa,CAAK;EAI5C,AAFA,EAAgB,KAAK,gBAAgB,MAAM,GAAe,EAAa,OAAO,GAC9E,QAAQ,MAAM,KAAK,gBAAgB,MAAM,GAAc,EAAM,MAAM,GACnE,QAAQ,MAAM,KAAK,gBAAgB,MAAM,GAAY,EAAa,QAAQ;CAC3E;CAEA,aAA6B;EAC5B,IAAI,IAAU,EAAe,KAAK,gBAAgB,MAAM,CAAa;EACrE,IAAG,MAAY,GACd,OAAO;EAER,IAAI,EAAE,mBAAgB,wBAAqB,EAAW,CAAO,GAMzD,IAAa,EAFF,QAAQ,KAAK,KAAK,gBAAgB,MAAM,CAEtB,IAC7B,IAAe,QAAQ,KAAK,KAAK,gBAAgB,MAAM,CAAY;EAGvE,OAAO,EAAc,IADN,EAAW,KAAK,OAAO,QAAQ,EAAe,CAAC,KAAK,GAAkB,CAChE,CAAI;CAC1B;CACA,aAAqB,GAAe;EACnC,IAAG,MAAU,IACZ,OAAO;GACN,SAAS;GACT,UAAA;EACD;EAID,IAAI,IAAc;EAClB,KAAI,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAAK;GACrC,IAAI,IAAW,EAAM,WAAW,CAAC;GACjC,AAAG,IAAW,MACb,IAAc;EAEhB;EACA,IAAI,IAAW,IAAc,MAAA,IAAA,GAEzB,IAAa,EAAgB,IAC7B,IAAkB,KAAK,OAAO,UAAU,KAAK,KAAK,EAAM,UAAU,IAAI,EAAW,kBAAkB,CAAC,GACpG,IAAO,IAAI,EAAW,EAAgB,KAAK,QAAuB,EAAgB,KAAK,YAAY,EAAM,MAAM;EACnH,KAAI,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAChC,EAAK,KAAK,EAAM,WAAW,CAAC;EAG7B,OAAO;GACN,SAAS,EAAgB;GACzB;EACD;CACD;CAEA,kBAAyC;EACxC,OAAO,KAAK,gBAAgB,gBAAgB;CAC7C;CAEA,IAAI,UAAU;EACb,OAAO,KAAK,gBAAgB;CAC7B;CAEA,OAAO;EACN,IAAI,IAAU,EAAe,KAAK,gBAAgB,MAAM,CAAa;EACrE,IAAG,GAAS;GACX,IAAI,EAAE,mBAAgB,wBAAqB,EAAW,CAAO;GAC7D,KAAK,OAAO,QAAQ,EAAe,CAAC,KAAK,CAAgB;EAC1D;EACA,KAAK,gBAAgB,KAAK;CAC3B;AACD;AAIA,SAAS,EAAc,GAAwC;CAC9D,IAAM,IAAa;CACnB,IAAG,EAAK,UAAU,GACjB,OAAO,OAAO,aAAa,MAAM,MAAM,CAAgC;CAGxE,IAAI,IAAS;CACb,KAAI,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,GACpC,KAAU,OAAO,aAAa,MAAM,MAAM,EAAK,SAAS,GAAG,IAAI,CAAU,CAA6B;CAGvG,OAAO;AACR"}
|
package/dist/interfaces/pow2.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TypedArrayConstructor } from './interfaces/typed-array-constructor';
|
|
2
|
-
import
|
|
1
|
+
import type { TypedArrayConstructor } from './interfaces/typed-array-constructor';
|
|
2
|
+
import type MemoryHeap from './memory-heap';
|
|
3
3
|
export default class LocalPool<T extends Uint32Array | Int32Array | Float32Array | Float64Array = Uint32Array> implements Iterable<T> {
|
|
4
4
|
private memory;
|
|
5
5
|
private pointers;
|
package/dist/local-pool.js
CHANGED
|
@@ -1,95 +1,90 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
free() {
|
|
87
|
-
for (let t of this.pointers)
|
|
88
|
-
new n(this.memory, o(t)).free();
|
|
89
|
-
this.pointers = [], this.recycledIndexes = [], this.totalLength = 0, this.fullDataBlocks = {};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
export {
|
|
93
|
-
g as default
|
|
1
|
+
import { getPointer as e } from "./utils/pointer.js";
|
|
2
|
+
import t from "./allocated-memory.js";
|
|
3
|
+
//#region src/local-pool.ts
|
|
4
|
+
var n = class {
|
|
5
|
+
memory;
|
|
6
|
+
pointers = [];
|
|
7
|
+
recycledIndexes = [];
|
|
8
|
+
totalLength = 0;
|
|
9
|
+
maxChunkSize = 100;
|
|
10
|
+
dataLength = 1;
|
|
11
|
+
byteMultipler = 1;
|
|
12
|
+
typeConstructor;
|
|
13
|
+
fullDataBlocks = {};
|
|
14
|
+
get length() {
|
|
15
|
+
return this.totalLength - this.recycledIndexes.length;
|
|
16
|
+
}
|
|
17
|
+
get bufferLength() {
|
|
18
|
+
return this.maxChunkSize * this.pointers.length;
|
|
19
|
+
}
|
|
20
|
+
constructor(e, t) {
|
|
21
|
+
this.memory = e;
|
|
22
|
+
let n = t?.dataLength ?? 1, r = t?.maxChunkSize ?? 100;
|
|
23
|
+
this.dataLength = n, this.maxChunkSize = r, this.typeConstructor = t.type, this.typeConstructor === Float64Array && (this.byteMultipler = 2);
|
|
24
|
+
let i = e.allocUI32(r * n * this.byteMultipler);
|
|
25
|
+
this.pointers.push(i.pointer);
|
|
26
|
+
let a = new this.typeConstructor(i.data.buffer, i.bufferByteOffset, this.dataLength * this.maxChunkSize);
|
|
27
|
+
this.fullDataBlocks[0] = a;
|
|
28
|
+
}
|
|
29
|
+
at(e) {
|
|
30
|
+
let t = this.fullDataBlocks[Math.floor(e / this.maxChunkSize)];
|
|
31
|
+
return this.getDataBlock(t, e % this.maxChunkSize);
|
|
32
|
+
}
|
|
33
|
+
get(e, t = 0) {
|
|
34
|
+
let n = this.dataLength;
|
|
35
|
+
if (t >= n) throw Error(`${t} is out of dataLength bounds ${n}`);
|
|
36
|
+
return this.fullDataBlocks[Math.floor(e / this.maxChunkSize)][e % this.maxChunkSize * n + t];
|
|
37
|
+
}
|
|
38
|
+
push(e) {
|
|
39
|
+
let t = typeof e == "number";
|
|
40
|
+
if (!t && e.length > this.dataLength) throw Error(`Can't insert ${e.length} array into shared list of ${this.dataLength} dataLength`);
|
|
41
|
+
let n = this.recycledIndexes.pop();
|
|
42
|
+
n === void 0 && (n = this.totalLength++);
|
|
43
|
+
let r = Math.floor(n / this.maxChunkSize);
|
|
44
|
+
if (r >= this.pointers.length) {
|
|
45
|
+
let e = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);
|
|
46
|
+
this.pointers.push(e.pointer);
|
|
47
|
+
let t = new this.typeConstructor(e.data.buffer, e.bufferByteOffset, this.dataLength * this.maxChunkSize);
|
|
48
|
+
this.fullDataBlocks[r] = t;
|
|
49
|
+
}
|
|
50
|
+
let i = this.fullDataBlocks[r], a = n % this.maxChunkSize, o = this.dataLength * a;
|
|
51
|
+
return t ? i[o] = e : i.set(e, o), n;
|
|
52
|
+
}
|
|
53
|
+
deleteIndex(e) {
|
|
54
|
+
this.recycledIndexes.push(e);
|
|
55
|
+
}
|
|
56
|
+
clear() {
|
|
57
|
+
this.totalLength = 0, this.recycledIndexes = [];
|
|
58
|
+
}
|
|
59
|
+
*[Symbol.iterator]() {
|
|
60
|
+
let e = {};
|
|
61
|
+
for (let t of this.recycledIndexes) e[t] = !0;
|
|
62
|
+
let t = this.getFullDataBlock(0), n = 0;
|
|
63
|
+
for (let r = 0; r < this.totalLength; r++) if (!e[r]) {
|
|
64
|
+
let e = Math.floor(r / this.maxChunkSize);
|
|
65
|
+
e !== n && (t = this.getFullDataBlock(r), n = e), yield this.getDataBlock(t, r % this.maxChunkSize);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
getFullDataBlock(n) {
|
|
69
|
+
let r = Math.floor(n / this.maxChunkSize), i = this.fullDataBlocks[r];
|
|
70
|
+
if (i) return i;
|
|
71
|
+
if (r >= this.pointers.length) {
|
|
72
|
+
let e = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);
|
|
73
|
+
this.pointers.push(e.pointer);
|
|
74
|
+
}
|
|
75
|
+
let a = new t(this.memory, e(this.pointers[r])), o = new this.typeConstructor(a.data.buffer, a.bufferByteOffset, this.dataLength * this.maxChunkSize);
|
|
76
|
+
return this.fullDataBlocks[r] = o, o;
|
|
77
|
+
}
|
|
78
|
+
getDataBlock(e, t) {
|
|
79
|
+
let n = t * this.dataLength;
|
|
80
|
+
return e.subarray(n, n + this.dataLength);
|
|
81
|
+
}
|
|
82
|
+
free() {
|
|
83
|
+
for (let n of this.pointers) new t(this.memory, e(n)).free();
|
|
84
|
+
this.pointers = [], this.recycledIndexes = [], this.totalLength = 0, this.fullDataBlocks = {};
|
|
85
|
+
}
|
|
94
86
|
};
|
|
95
|
-
//#
|
|
87
|
+
//#endregion
|
|
88
|
+
export { n as default };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=local-pool.js.map
|
package/dist/local-pool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-pool.js","sources":["../src/local-pool.ts"],"sourcesContent":["import AllocatedMemory from './allocated-memory';\nimport type { TypedArrayConstructor } from './interfaces/typed-array-constructor';\nimport type MemoryHeap from './memory-heap';\nimport { getPointer } from './utils/pointer';\n\n// Array with stable indexes and maximum contiguous memory sizes (necessary to fit large data sets into max 1MB buffers)\n// Can only do insert/deletions from a single thread - useful if other threads are known to be read-only\nexport default class LocalPool<T extends Uint32Array | Int32Array | Float32Array | Float64Array = Uint32Array> implements Iterable<T> {\n\tprivate memory: MemoryHeap;\n\tprivate pointers: Array<number> = [];\n\tprivate recycledIndexes: Array<number> = [];\n\tprivate totalLength = 0;\n\treadonly maxChunkSize: number = 100;\n\treadonly dataLength: number = 1;\n\treadonly byteMultipler: number = 1;\n\tprivate typeConstructor: TypedArrayConstructor<T>;\n\tprivate fullDataBlocks: { [key: number]: T } = {};\n\n\tget length(): number {\n\t\treturn this.totalLength - this.recycledIndexes.length;\n\t}\n\tget bufferLength(): number {\n\t\treturn this.maxChunkSize * this.pointers.length;\n\t}\n\n\tconstructor(memory: MemoryHeap, config: LocalPoolConfig<T>) {\n\t\tthis.memory = memory;\n\n\t\tconst dataLength = config?.dataLength ?? 1;\n\t\tconst maxLength = config?.maxChunkSize ?? 100;\n\t\tthis.dataLength = dataLength;\n\t\tthis.maxChunkSize = maxLength;\n\n\t\tthis.typeConstructor = config.type;\n\t\t// @ts-expect-error\n\t\tif(this.typeConstructor === Float64Array) {\n\t\t\tthis.byteMultipler = 2;\n\t\t}\n\n\t\tlet firstArray = memory.allocUI32(maxLength * dataLength * this.byteMultipler);\n\t\tthis.pointers.push(firstArray.pointer);\n\t\tlet data: T = new this.typeConstructor(firstArray.data.buffer, firstArray.bufferByteOffset, this.dataLength * this.maxChunkSize)
|
|
1
|
+
{"version":3,"file":"local-pool.js","names":[],"sources":["../src/local-pool.ts"],"sourcesContent":["import AllocatedMemory from './allocated-memory';\nimport type { TypedArrayConstructor } from './interfaces/typed-array-constructor';\nimport type MemoryHeap from './memory-heap';\nimport { getPointer } from './utils/pointer';\n\n// Array with stable indexes and maximum contiguous memory sizes (necessary to fit large data sets into max 1MB buffers)\n// Can only do insert/deletions from a single thread - useful if other threads are known to be read-only\nexport default class LocalPool<T extends Uint32Array | Int32Array | Float32Array | Float64Array = Uint32Array> implements Iterable<T> {\n\tprivate memory: MemoryHeap;\n\tprivate pointers: Array<number> = [];\n\tprivate recycledIndexes: Array<number> = [];\n\tprivate totalLength = 0;\n\treadonly maxChunkSize: number = 100;\n\treadonly dataLength: number = 1;\n\treadonly byteMultipler: number = 1;\n\tprivate typeConstructor: TypedArrayConstructor<T>;\n\tprivate fullDataBlocks: { [key: number]: T } = {};\n\n\tget length(): number {\n\t\treturn this.totalLength - this.recycledIndexes.length;\n\t}\n\tget bufferLength(): number {\n\t\treturn this.maxChunkSize * this.pointers.length;\n\t}\n\n\tconstructor(memory: MemoryHeap, config: LocalPoolConfig<T>) {\n\t\tthis.memory = memory;\n\n\t\tconst dataLength = config?.dataLength ?? 1;\n\t\tconst maxLength = config?.maxChunkSize ?? 100;\n\t\tthis.dataLength = dataLength;\n\t\tthis.maxChunkSize = maxLength;\n\n\t\tthis.typeConstructor = config.type;\n\t\t// @ts-expect-error\n\t\tif(this.typeConstructor === Float64Array) {\n\t\t\tthis.byteMultipler = 2;\n\t\t}\n\n\t\tlet firstArray = memory.allocUI32(maxLength * dataLength * this.byteMultipler);\n\t\tthis.pointers.push(firstArray.pointer);\n\t\tlet data: T = new this.typeConstructor(firstArray.data.buffer, firstArray.bufferByteOffset, this.dataLength * this.maxChunkSize);\n\t\tthis.fullDataBlocks[0] = data;\n\t}\n\n\tat(index: number): T {\n\t\tlet dataBlock = this.fullDataBlocks[Math.floor(index / this.maxChunkSize)];\n\t\treturn this.getDataBlock(dataBlock, index % this.maxChunkSize);\n\t}\n\tget(index: number, dataIndex = 0): number {\n\t\tconst dataLength = this.dataLength;\n\t\tif(dataIndex >= dataLength) {\n\t\t\tthrow new Error(`${dataIndex} is out of dataLength bounds ${dataLength}`);\n\t\t}\n\n\t\tlet dataBlock = this.fullDataBlocks[Math.floor(index / this.maxChunkSize)];\n\t\treturn dataBlock[(index % this.maxChunkSize) * dataLength + dataIndex];\n\t}\n\n\tpush(values: number | Array<number>): number {\n\t\tconst isSingleNumber = typeof values === 'number';\n\t\tif(!isSingleNumber && values.length > this.dataLength) {\n\t\t\tthrow new Error(`Can't insert ${values.length} array into shared list of ${this.dataLength} dataLength`);\n\t\t}\n\n\t\tlet newIndex = this.recycledIndexes.pop();\n\t\tif(newIndex === undefined) {\n\t\t\tnewIndex = this.totalLength++;\n\t\t}\n\t\t\n\t\t\n\t\tlet pointerIndex = Math.floor(newIndex / this.maxChunkSize);\n\t\tif(pointerIndex >= this.pointers.length) {\n\t\t\tlet newArray = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);\n\t\t\tthis.pointers.push(newArray.pointer);\n\t\t\tlet data: T = new this.typeConstructor(newArray.data.buffer, newArray.bufferByteOffset, this.dataLength * this.maxChunkSize);\n\t\t\tthis.fullDataBlocks[pointerIndex] = data;\n\t\t}\n\n\t\tlet dataBlock = this.fullDataBlocks[pointerIndex];\n\t\tlet blockIndex = newIndex % this.maxChunkSize;\n\t\tlet startIndex = this.dataLength * blockIndex;\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\treturn newIndex;\n\t}\n\n\tdeleteIndex(index: number) {\n\t\tthis.recycledIndexes.push(index);\n\t}\n\n\tclear() {\n\t\tthis.totalLength = 0;\n\t\tthis.recycledIndexes = [];\n\t}\n\n\t*[Symbol.iterator]() {\n\t\tconst recycledValues: { [key: number]: true } = {};\n\t\tfor(let value of this.recycledIndexes) {\n\t\t\trecycledValues[value] = true;\n\t\t}\n\n\t\tlet dataBlock = this.getFullDataBlock(0);\n\t\tlet dataBlockIndex = 0;\n\t\tfor(let i = 0; i < this.totalLength; i++) {\n\t\t\tif(!recycledValues[i]) {\n\t\t\t\tlet newDataBlockIndex = Math.floor(i / this.maxChunkSize);\n\t\t\t\tif(newDataBlockIndex !== dataBlockIndex) {\n\t\t\t\t\tdataBlock = this.getFullDataBlock(i);\n\t\t\t\t\tdataBlockIndex = newDataBlockIndex;\n\t\t\t\t}\n\t\t\t\tyield this.getDataBlock(dataBlock, i % this.maxChunkSize);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getFullDataBlock(index: number) {\n\t\tlet pointerIndex = Math.floor(index / this.maxChunkSize);\n\t\tlet cachedDataBlock = this.fullDataBlocks[pointerIndex];\n\t\tif(cachedDataBlock) {\n\t\t\treturn cachedDataBlock;\n\t\t}\n\t\tif(pointerIndex >= this.pointers.length) {\n\t\t\tlet newArray = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);\n\t\t\tthis.pointers.push(newArray.pointer);\n\t\t}\n\n\t\tlet array = new AllocatedMemory(this.memory, getPointer(this.pointers[pointerIndex]));\n\t\tlet data: T = new this.typeConstructor(array.data.buffer, array.bufferByteOffset, this.dataLength * this.maxChunkSize);\n\t\tthis.fullDataBlocks[pointerIndex] = data;\n\t\treturn data;\n\t}\n\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\tfree() {\n\t\tfor(let pointer of this.pointers) {\n\t\t\tlet memory = new AllocatedMemory(this.memory, getPointer(pointer));\n\t\t\tmemory.free();\n\t\t}\n\t\tthis.pointers = [];\n\t\tthis.recycledIndexes = [];\n\t\tthis.totalLength = 0;\n\t\tthis.fullDataBlocks = {};\n\t}\n}\n\ninterface LocalPoolConfig<T extends Uint32Array | Int32Array | Float32Array | Float64Array> {\n\tmaxChunkSize?: number\n\ttype: TypedArrayConstructor<T>\n\tdataLength?: number\n}\nexport type { LocalPoolConfig };"],"mappings":"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"}
|
|
@@ -1,25 +1,19 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Atomics.add(o, c + 1, 1);
|
|
1
|
+
function e(e, t = 0) {
|
|
2
|
+
for (; Atomics.compareExchange(e, t, 0, 1) === 2;) Atomics.wait(e, t, 2);
|
|
3
|
+
Atomics.add(e, t + 1, 1);
|
|
5
4
|
}
|
|
6
|
-
function t(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Atomics.wait(o, c, E), E = Atomics.compareExchange(o, c, 0, 2);
|
|
5
|
+
function t(e, t = 0) {
|
|
6
|
+
let n = Atomics.compareExchange(e, t, 0, 2);
|
|
7
|
+
for (; n !== 0;) Atomics.wait(e, t, n), n = Atomics.compareExchange(e, t, 0, 2);
|
|
10
8
|
}
|
|
11
|
-
function e
|
|
12
|
-
|
|
9
|
+
function n(e, t = 0) {
|
|
10
|
+
Atomics.sub(e, t + 1, 1) - 1 <= 0 && (Atomics.compareExchange(e, t, 1, 0) !== 1 && console.warn("We are unlocking when it was not read locked!"), Atomics.notify(e, t));
|
|
13
11
|
}
|
|
14
|
-
function
|
|
15
|
-
|
|
12
|
+
function r(e, t = 0) {
|
|
13
|
+
Atomics.compareExchange(e, t, 2, 0) !== 2 && console.warn("We are unlocking when it was not write locked!"), Atomics.notify(e, t);
|
|
16
14
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
t as writeLock,
|
|
23
|
-
i as writeUnlock
|
|
24
|
-
};
|
|
25
|
-
//# sourceMappingURL=read-write-lock.js.map
|
|
15
|
+
var i = 2;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { i as READ_WRITE_LOCK_ALLOCATE_COUNT, e as readLock, n as readUnlock, t as writeLock, r as writeUnlock };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=read-write-lock.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-write-lock.js","sources":["../../src/lock/read-write-lock.ts"],"sourcesContent":["const UNLOCKED = 0;\nconst READ_LOCKED = 1;\nconst WRITE_LOCKED = 2;\n\nexport function readLock(data: Int32Array, index: number = 0) {\n\t// Wait over and over again until we get that it was unlocked or read locked\n\twhile(Atomics.compareExchange(data, index, UNLOCKED, READ_LOCKED) === WRITE_LOCKED) {\n\t\tAtomics.wait(data, index, WRITE_LOCKED);\n\t}\n\n\tAtomics.add(data, index + 1, 1);\n}\nexport function writeLock(data: Int32Array, index: number = 0) {\n\t// Write lock needs to be exclusive - wait until we were in UNLOCKED to proceed\n\tlet oldValue = Atomics.compareExchange(data, index, UNLOCKED, WRITE_LOCKED);\n\twhile(oldValue !== UNLOCKED) {\n\t\tAtomics.wait(data, index, oldValue);\n\t\toldValue = Atomics.compareExchange(data, index, UNLOCKED, WRITE_LOCKED);\n\t}\n}\n\nexport function readUnlock(data: Int32Array, index: number = 0) {\n\tlet readCount = Atomics.sub(data, index + 1, 1) - 1;\n\n\tif(readCount <= 0) {\n\t\tif(Atomics.compareExchange(data, index, READ_LOCKED, UNLOCKED) !== READ_LOCKED) {\n\t\t\tconsole.warn('We are unlocking when it was not read locked!');\n\t\t}\n\n\t\tAtomics.notify(data, index);\n\t}\n}\nexport function writeUnlock(data: Int32Array, index: number = 0) {\n\tif(Atomics.compareExchange(data, index, WRITE_LOCKED, UNLOCKED) !== WRITE_LOCKED) {\n\t\tconsole.warn('We are unlocking when it was not write locked!');\n\t}\n\n\tAtomics.notify(data, index);\n}\n\nexport const READ_WRITE_LOCK_ALLOCATE_COUNT = 2;"],"
|
|
1
|
+
{"version":3,"file":"read-write-lock.js","names":[],"sources":["../../src/lock/read-write-lock.ts"],"sourcesContent":["const UNLOCKED = 0;\nconst READ_LOCKED = 1;\nconst WRITE_LOCKED = 2;\n\nexport function readLock(data: Int32Array, index: number = 0) {\n\t// Wait over and over again until we get that it was unlocked or read locked\n\twhile(Atomics.compareExchange(data, index, UNLOCKED, READ_LOCKED) === WRITE_LOCKED) {\n\t\tAtomics.wait(data, index, WRITE_LOCKED);\n\t}\n\n\tAtomics.add(data, index + 1, 1);\n}\nexport function writeLock(data: Int32Array, index: number = 0) {\n\t// Write lock needs to be exclusive - wait until we were in UNLOCKED to proceed\n\tlet oldValue = Atomics.compareExchange(data, index, UNLOCKED, WRITE_LOCKED);\n\twhile(oldValue !== UNLOCKED) {\n\t\tAtomics.wait(data, index, oldValue);\n\t\toldValue = Atomics.compareExchange(data, index, UNLOCKED, WRITE_LOCKED);\n\t}\n}\n\nexport function readUnlock(data: Int32Array, index: number = 0) {\n\tlet readCount = Atomics.sub(data, index + 1, 1) - 1;\n\n\tif(readCount <= 0) {\n\t\tif(Atomics.compareExchange(data, index, READ_LOCKED, UNLOCKED) !== READ_LOCKED) {\n\t\t\tconsole.warn('We are unlocking when it was not read locked!');\n\t\t}\n\n\t\tAtomics.notify(data, index);\n\t}\n}\nexport function writeUnlock(data: Int32Array, index: number = 0) {\n\tif(Atomics.compareExchange(data, index, WRITE_LOCKED, UNLOCKED) !== WRITE_LOCKED) {\n\t\tconsole.warn('We are unlocking when it was not write locked!');\n\t}\n\n\tAtomics.notify(data, index);\n}\n\nexport const READ_WRITE_LOCK_ALLOCATE_COUNT = 2;"],"mappings":"AAIA,SAAgB,EAAS,GAAkB,IAAgB,GAAG;CAE7D,OAAM,QAAQ,gBAAgB,GAAM,GAAO,GAAU,CAAW,MAAM,IACrE,QAAQ,KAAK,GAAM,GAAO,CAAY;CAGvC,QAAQ,IAAI,GAAM,IAAQ,GAAG,CAAC;AAC/B;AACA,SAAgB,EAAU,GAAkB,IAAgB,GAAG;CAE9D,IAAI,IAAW,QAAQ,gBAAgB,GAAM,GAAO,GAAU,CAAY;CAC1E,OAAM,MAAa,IAElB,AADA,QAAQ,KAAK,GAAM,GAAO,CAAQ,GAClC,IAAW,QAAQ,gBAAgB,GAAM,GAAO,GAAU,CAAY;AAExE;AAEA,SAAgB,EAAW,GAAkB,IAAgB,GAAG;CAG/D,AAFgB,QAAQ,IAAI,GAAM,IAAQ,GAAG,CAAC,IAAI,KAElC,MACZ,QAAQ,gBAAgB,GAAM,GAAO,GAAa,CAAQ,MAAM,KAClE,QAAQ,KAAK,+CAA+C,GAG7D,QAAQ,OAAO,GAAM,CAAK;AAE5B;AACA,SAAgB,EAAY,GAAkB,IAAgB,GAAG;CAKhE,AAJG,QAAQ,gBAAgB,GAAM,GAAO,GAAc,CAAQ,MAAM,KACnE,QAAQ,KAAK,gDAAgD,GAG9D,QAAQ,OAAO,GAAM,CAAK;AAC3B;AAEA,IAAa,IAAiC"}
|
package/dist/lock/simple-lock.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
"WorkerGlobalScope" in self && Atomics.wait(o, c, 1);
|
|
1
|
+
function e(e, t = 0) {
|
|
2
|
+
for (; Atomics.compareExchange(e, t, 0, 1) !== 0;) "WorkerGlobalScope" in self && Atomics.wait(e, t, 1);
|
|
4
3
|
}
|
|
5
|
-
function
|
|
6
|
-
|
|
4
|
+
function t(e, t = 0) {
|
|
5
|
+
Atomics.compareExchange(e, t, 1, 0) !== 1 && console.warn("We are unlocking when it was not locked!"), Atomics.notify(e, t);
|
|
7
6
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=simple-lock.js.map
|
|
7
|
+
var n = 1;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { n as SIMPLE_LOCK_ALLOCATE_COUNT, e as lock, t as unlock };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=simple-lock.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-lock.js","sources":["../../src/lock/simple-lock.ts"],"sourcesContent":["const UNLOCKED = 0;\nconst LOCKED = 1;\nexport function lock(data: Int32Array, index: number = 0) {\n\t// Wait over and over again until we are one who set this from UNLOCKED to LOCKED\n\twhile(Atomics.compareExchange(data, index, UNLOCKED, LOCKED) !== UNLOCKED) {\n\t\tif('WorkerGlobalScope' in self) {\n\t\t\tAtomics.wait(data, index, LOCKED);\n\t\t} else {\n\t\t\t// TODO: Spin-locks suck....\n\t\t}\n\t}\n}\nexport function unlock(data: Int32Array, index: number = 0) {\n\tif(Atomics.compareExchange(data, index, LOCKED, UNLOCKED) !== LOCKED) {\n\t\tconsole.warn('We are unlocking when it was not locked!');\n\t}\n\n\tAtomics.notify(data, index);\n}\n\nexport const SIMPLE_LOCK_ALLOCATE_COUNT = 1;"],"
|
|
1
|
+
{"version":3,"file":"simple-lock.js","names":[],"sources":["../../src/lock/simple-lock.ts"],"sourcesContent":["const UNLOCKED = 0;\nconst LOCKED = 1;\nexport function lock(data: Int32Array, index: number = 0) {\n\t// Wait over and over again until we are one who set this from UNLOCKED to LOCKED\n\twhile(Atomics.compareExchange(data, index, UNLOCKED, LOCKED) !== UNLOCKED) {\n\t\tif('WorkerGlobalScope' in self) {\n\t\t\tAtomics.wait(data, index, LOCKED);\n\t\t} else {\n\t\t\t// TODO: Spin-locks suck....\n\t\t}\n\t}\n}\nexport function unlock(data: Int32Array, index: number = 0) {\n\tif(Atomics.compareExchange(data, index, LOCKED, UNLOCKED) !== LOCKED) {\n\t\tconsole.warn('We are unlocking when it was not locked!');\n\t}\n\n\tAtomics.notify(data, index);\n}\n\nexport const SIMPLE_LOCK_ALLOCATE_COUNT = 1;"],"mappings":"AAEA,SAAgB,EAAK,GAAkB,IAAgB,GAAG;CAEzD,OAAM,QAAQ,gBAAgB,GAAM,GAAO,GAAU,CAAM,MAAM,IAChE,AAAG,uBAAuB,QACzB,QAAQ,KAAK,GAAM,GAAO,CAAM;AAKnC;AACA,SAAgB,EAAO,GAAkB,IAAgB,GAAG;CAK3D,AAJG,QAAQ,gBAAgB,GAAM,GAAO,GAAQ,CAAQ,MAAM,KAC7D,QAAQ,KAAK,0CAA0C,GAGxD,QAAQ,OAAO,GAAM,CAAK;AAC3B;AAEA,IAAa,IAA6B"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { Pow2 } from './interfaces/pow2';
|
|
2
|
-
import { TypedArray } from './interfaces/typed-array';
|
|
1
|
+
import type { Pow2 } from './interfaces/pow2';
|
|
2
|
+
import type { TypedArray } from './interfaces/typed-array';
|
|
3
|
+
declare const SIZEOF_STATE: number;
|
|
4
|
+
declare const SIZEOF_MEM_BLOCK: number;
|
|
3
5
|
export default class MemoryBuffer {
|
|
4
6
|
buf: ArrayBufferLike;
|
|
5
7
|
protected readonly start: number;
|
|
@@ -9,8 +11,8 @@ export default class MemoryBuffer {
|
|
|
9
11
|
protected lock: Int32Array;
|
|
10
12
|
constructor(opts?: Partial<MemoryBufferConfig>);
|
|
11
13
|
stats(): Readonly<MemoryBufferStats>;
|
|
12
|
-
callocAs<T extends Type>(type: T, num: number, fill?: number): import(
|
|
13
|
-
mallocAs<T extends Type>(type: T, num: number): import(
|
|
14
|
+
callocAs<T extends Type>(type: T, num: number, fill?: number): import("./utils/typedarray").TypedArrayTypeMap[T] | undefined;
|
|
15
|
+
mallocAs<T extends Type>(type: T, num: number): import("./utils/typedarray").TypedArrayTypeMap[T] | undefined;
|
|
14
16
|
calloc(bytes: number, fill?: number): number;
|
|
15
17
|
malloc(bytes: number): number;
|
|
16
18
|
private mallocTop;
|
|
@@ -28,6 +30,7 @@ export default class MemoryBuffer {
|
|
|
28
30
|
protected set end(x: number);
|
|
29
31
|
get top(): number;
|
|
30
32
|
protected set top(x: number);
|
|
33
|
+
get isEmpty(): boolean;
|
|
31
34
|
protected get _free(): number;
|
|
32
35
|
protected set _free(block: number);
|
|
33
36
|
protected get _used(): number;
|
|
@@ -77,6 +80,7 @@ export default class MemoryBuffer {
|
|
|
77
80
|
*/
|
|
78
81
|
protected insert(block: number): void;
|
|
79
82
|
}
|
|
83
|
+
export { SIZEOF_STATE, SIZEOF_MEM_BLOCK };
|
|
80
84
|
type Type = 'u8' | 'u8c' | 'i8' | 'u16' | 'i16' | 'u32' | 'i32' | 'f32' | 'f64';
|
|
81
85
|
interface MemoryBufferConfig {
|
|
82
86
|
/**
|
|
@@ -182,4 +186,3 @@ interface MemoryBufferStats {
|
|
|
182
186
|
*/
|
|
183
187
|
total: number;
|
|
184
188
|
}
|
|
185
|
-
export {};
|