xitdb 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +129 -15
  2. package/dist/core-buffered-file.d.ts +2 -2
  3. package/dist/core-buffered-file.js +182 -0
  4. package/dist/core-file.d.ts +1 -1
  5. package/dist/core-file.js +105 -0
  6. package/dist/core-memory.d.ts +1 -1
  7. package/dist/core-memory.js +152 -0
  8. package/dist/core.js +1 -0
  9. package/dist/database.d.ts +174 -49
  10. package/dist/database.js +3047 -0
  11. package/dist/exceptions.d.ts +4 -0
  12. package/dist/exceptions.js +62 -0
  13. package/dist/hasher.js +49 -0
  14. package/dist/index.d.ts +30 -26
  15. package/dist/index.js +35 -3923
  16. package/dist/read-array-list.d.ts +4 -3
  17. package/dist/read-array-list.js +41 -0
  18. package/dist/read-counted-hash-map.d.ts +2 -2
  19. package/dist/read-counted-hash-map.js +19 -0
  20. package/dist/read-counted-hash-set.d.ts +2 -2
  21. package/dist/read-counted-hash-set.js +19 -0
  22. package/dist/read-cursor.d.ts +16 -5
  23. package/dist/read-cursor.js +678 -0
  24. package/dist/read-hash-map.d.ts +4 -4
  25. package/dist/read-hash-map.js +65 -0
  26. package/dist/read-hash-set.d.ts +4 -4
  27. package/dist/read-hash-set.js +47 -0
  28. package/dist/read-linked-array-list.d.ts +4 -3
  29. package/dist/read-linked-array-list.js +41 -0
  30. package/dist/read-sorted-map.d.ts +21 -0
  31. package/dist/read-sorted-map.js +73 -0
  32. package/dist/read-sorted-set.d.ts +19 -0
  33. package/dist/read-sorted-set.js +65 -0
  34. package/dist/slot-pointer.d.ts +1 -1
  35. package/dist/slot-pointer.js +11 -0
  36. package/dist/slot.d.ts +2 -2
  37. package/dist/slot.js +41 -0
  38. package/dist/slotted.d.ts +1 -1
  39. package/dist/slotted.js +1 -0
  40. package/dist/tag.d.ts +3 -1
  41. package/dist/tag.js +25 -0
  42. package/dist/write-array-list.d.ts +4 -4
  43. package/dist/write-array-list.js +42 -0
  44. package/dist/write-counted-hash-map.d.ts +2 -2
  45. package/dist/write-counted-hash-map.js +18 -0
  46. package/dist/write-counted-hash-set.d.ts +2 -2
  47. package/dist/write-counted-hash-set.js +18 -0
  48. package/dist/write-cursor.d.ts +5 -5
  49. package/dist/write-cursor.js +124 -0
  50. package/dist/write-hash-map.d.ts +4 -4
  51. package/dist/write-hash-map.js +90 -0
  52. package/dist/write-hash-set.d.ts +4 -4
  53. package/dist/write-hash-set.js +59 -0
  54. package/dist/write-linked-array-list.d.ts +4 -4
  55. package/dist/write-linked-array-list.js +52 -0
  56. package/dist/write-sorted-map.d.ts +12 -0
  57. package/dist/write-sorted-map.js +37 -0
  58. package/dist/write-sorted-set.d.ts +10 -0
  59. package/dist/write-sorted-set.js +29 -0
  60. package/dist/writeable-data.js +68 -0
  61. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -1,3923 +1,35 @@
1
- // @bun
2
- // src/tag.ts
3
- var Tag;
4
- ((Tag2) => {
5
- Tag2[Tag2["NONE"] = 0] = "NONE";
6
- Tag2[Tag2["INDEX"] = 1] = "INDEX";
7
- Tag2[Tag2["ARRAY_LIST"] = 2] = "ARRAY_LIST";
8
- Tag2[Tag2["LINKED_ARRAY_LIST"] = 3] = "LINKED_ARRAY_LIST";
9
- Tag2[Tag2["HASH_MAP"] = 4] = "HASH_MAP";
10
- Tag2[Tag2["KV_PAIR"] = 5] = "KV_PAIR";
11
- Tag2[Tag2["BYTES"] = 6] = "BYTES";
12
- Tag2[Tag2["SHORT_BYTES"] = 7] = "SHORT_BYTES";
13
- Tag2[Tag2["UINT"] = 8] = "UINT";
14
- Tag2[Tag2["INT"] = 9] = "INT";
15
- Tag2[Tag2["FLOAT"] = 10] = "FLOAT";
16
- Tag2[Tag2["HASH_SET"] = 11] = "HASH_SET";
17
- Tag2[Tag2["COUNTED_HASH_MAP"] = 12] = "COUNTED_HASH_MAP";
18
- Tag2[Tag2["COUNTED_HASH_SET"] = 13] = "COUNTED_HASH_SET";
19
- })(Tag ||= {});
20
- function tagValueOf(n) {
21
- if (n < 0 || n > 13) {
22
- throw new Error(`Invalid tag value: ${n}`);
23
- }
24
- return n;
25
- }
26
- // src/slot.ts
27
- class Slot {
28
- static LENGTH = 9;
29
- value;
30
- tag;
31
- full;
32
- constructor(value = 0n, tag = 0 /* NONE */, full = false) {
33
- this.value = typeof value === "bigint" ? value : BigInt(value);
34
- this.tag = tag;
35
- this.full = full;
36
- }
37
- withTag(tag) {
38
- return new Slot(this.value, tag, this.full);
39
- }
40
- withFull(full) {
41
- return new Slot(this.value, this.tag, full);
42
- }
43
- empty() {
44
- return this.tag === 0 /* NONE */ && !this.full;
45
- }
46
- toBytes() {
47
- const buffer = new ArrayBuffer(Slot.LENGTH);
48
- const view = new DataView(buffer);
49
- let tagInt = this.full ? 128 : 0;
50
- tagInt = tagInt | this.tag;
51
- view.setUint8(0, tagInt);
52
- view.setBigInt64(1, this.value, false);
53
- return new Uint8Array(buffer);
54
- }
55
- static fromBytes(bytes) {
56
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
57
- const tagByte = view.getUint8(0);
58
- const full = (tagByte & 128) !== 0;
59
- const tag = tagValueOf(tagByte & 127);
60
- const value = view.getBigInt64(1, false);
61
- return new Slot(value, tag, full);
62
- }
63
- equals(other) {
64
- return this.value === other.value && this.tag === other.tag && this.full === other.full;
65
- }
66
- }
67
- // src/slot-pointer.ts
68
- class SlotPointer {
69
- position;
70
- slot;
71
- constructor(position, slot) {
72
- this.position = position;
73
- this.slot = slot;
74
- }
75
- withSlot(slot) {
76
- return new SlotPointer(this.position, slot);
77
- }
78
- }
79
- // src/exceptions.ts
80
- class DatabaseException extends Error {
81
- constructor(message) {
82
- super(message);
83
- this.name = this.constructor.name;
84
- }
85
- }
86
-
87
- class NotImplementedException extends DatabaseException {
88
- }
89
-
90
- class UnreachableException extends DatabaseException {
91
- }
92
-
93
- class InvalidDatabaseException extends DatabaseException {
94
- }
95
-
96
- class InvalidVersionException extends DatabaseException {
97
- }
98
-
99
- class InvalidHashSizeException extends DatabaseException {
100
- }
101
-
102
- class KeyNotFoundException extends DatabaseException {
103
- }
104
-
105
- class WriteNotAllowedException extends DatabaseException {
106
- }
107
-
108
- class UnexpectedTagException extends DatabaseException {
109
- }
110
-
111
- class CursorNotWriteableException extends DatabaseException {
112
- }
113
-
114
- class ExpectedTxStartException extends DatabaseException {
115
- }
116
-
117
- class KeyOffsetExceededException extends DatabaseException {
118
- }
119
-
120
- class PathPartMustBeAtEndException extends DatabaseException {
121
- }
122
-
123
- class StreamTooLongException extends DatabaseException {
124
- }
125
-
126
- class EndOfStreamException extends DatabaseException {
127
- }
128
-
129
- class InvalidOffsetException extends DatabaseException {
130
- }
131
-
132
- class InvalidTopLevelTypeException extends DatabaseException {
133
- }
134
-
135
- class ExpectedUnsignedLongException extends DatabaseException {
136
- }
137
-
138
- class NoAvailableSlotsException extends DatabaseException {
139
- }
140
-
141
- class MustSetNewSlotsToFullException extends DatabaseException {
142
- }
143
-
144
- class EmptySlotException extends DatabaseException {
145
- }
146
-
147
- class ExpectedRootNodeException extends DatabaseException {
148
- }
149
-
150
- class InvalidFormatTagSizeException extends DatabaseException {
151
- }
152
-
153
- class UnexpectedWriterPositionException extends DatabaseException {
154
- }
155
-
156
- class MaxShiftExceededException extends DatabaseException {
157
- }
158
-
159
- class Uint64OverflowException extends DatabaseException {
160
- }
161
-
162
- class Int64OverflowException extends DatabaseException {
163
- }
164
-
165
- // src/writeable-data.ts
166
- var UINT64_MAX = 2n ** 64n - 1n;
167
- var INT64_MIN = -(2n ** 63n);
168
- var INT64_MAX = 2n ** 63n - 1n;
169
-
170
- class Uint {
171
- value;
172
- constructor(value) {
173
- const bigintValue = BigInt(value);
174
- if (bigintValue < 0n || bigintValue > UINT64_MAX) {
175
- throw new Uint64OverflowException;
176
- }
177
- this.value = bigintValue;
178
- }
179
- }
180
-
181
- class Int {
182
- value;
183
- constructor(value) {
184
- const bigintValue = BigInt(value);
185
- if (bigintValue < INT64_MIN || bigintValue > INT64_MAX) {
186
- throw new Int64OverflowException;
187
- }
188
- this.value = bigintValue;
189
- }
190
- }
191
-
192
- class Float {
193
- value;
194
- constructor(value) {
195
- this.value = value;
196
- }
197
- }
198
-
199
- class Bytes {
200
- value;
201
- formatTag;
202
- constructor(value, formatTag) {
203
- if (typeof value === "string") {
204
- this.value = new TextEncoder().encode(value);
205
- } else {
206
- this.value = value;
207
- }
208
- if (formatTag === undefined || formatTag === null) {
209
- this.formatTag = null;
210
- } else if (typeof formatTag === "string") {
211
- const encoded = new TextEncoder().encode(formatTag);
212
- if (encoded.length !== 2) {
213
- throw new InvalidFormatTagSizeException;
214
- }
215
- this.formatTag = encoded;
216
- } else {
217
- if (formatTag.length !== 2) {
218
- throw new InvalidFormatTagSizeException;
219
- }
220
- this.formatTag = formatTag;
221
- }
222
- }
223
- isShort() {
224
- const totalSize = this.formatTag !== null ? 6 : 8;
225
- if (this.value.length > totalSize)
226
- return false;
227
- for (const b of this.value) {
228
- if (b === 0)
229
- return false;
230
- }
231
- return true;
232
- }
233
- }
234
- // src/core-memory.ts
235
- class CoreMemory {
236
- memory;
237
- constructor() {
238
- this.memory = new RandomAccessMemory;
239
- }
240
- reader() {
241
- return this.memory;
242
- }
243
- writer() {
244
- return this.memory;
245
- }
246
- length() {
247
- return this.memory.size();
248
- }
249
- seek(pos) {
250
- this.memory.seek(pos);
251
- }
252
- position() {
253
- return this.memory.getPosition();
254
- }
255
- setLength(len) {
256
- this.memory.setLength(len);
257
- }
258
- flush() {}
259
- sync() {}
260
- }
261
-
262
- class RandomAccessMemory {
263
- buffer;
264
- _position = 0;
265
- _count = 0;
266
- constructor(initialSize = 1024) {
267
- this.buffer = new Uint8Array(initialSize);
268
- }
269
- ensureCapacity(minCapacity) {
270
- if (minCapacity > this.buffer.length) {
271
- let newCapacity = this.buffer.length * 2;
272
- if (newCapacity < minCapacity) {
273
- newCapacity = minCapacity;
274
- }
275
- const newBuffer = new Uint8Array(newCapacity);
276
- newBuffer.set(this.buffer.subarray(0, this._count));
277
- this.buffer = newBuffer;
278
- }
279
- }
280
- size() {
281
- return this._count;
282
- }
283
- seek(pos) {
284
- if (pos > this._count) {
285
- this._position = this._count;
286
- } else {
287
- this._position = pos;
288
- }
289
- }
290
- getPosition() {
291
- return this._position;
292
- }
293
- setLength(len) {
294
- if (len === 0) {
295
- this.reset();
296
- } else {
297
- if (len > this._count)
298
- throw new Error("Cannot extend length");
299
- this._count = len;
300
- if (this._position > len) {
301
- this._position = len;
302
- }
303
- }
304
- }
305
- reset() {
306
- this._count = 0;
307
- this._position = 0;
308
- }
309
- toByteArray() {
310
- return this.buffer.slice(0, this._count);
311
- }
312
- write(data) {
313
- const pos = this._position;
314
- if (pos < this._count) {
315
- const bytesBeforeEnd = Math.min(data.length, this._count - pos);
316
- for (let i = 0;i < bytesBeforeEnd; i++) {
317
- this.buffer[pos + i] = data[i];
318
- }
319
- if (bytesBeforeEnd < data.length) {
320
- const bytesAfterEnd = data.length - bytesBeforeEnd;
321
- this.ensureCapacity(this._count + bytesAfterEnd);
322
- this.buffer.set(data.subarray(bytesBeforeEnd), this._count);
323
- this._count += bytesAfterEnd;
324
- }
325
- } else {
326
- this.ensureCapacity(this._count + data.length);
327
- this.buffer.set(data, this._count);
328
- this._count += data.length;
329
- }
330
- this._position = pos + data.length;
331
- }
332
- writeByte(v) {
333
- this.write(new Uint8Array([v & 255]));
334
- }
335
- writeShort(v) {
336
- const buffer = new ArrayBuffer(2);
337
- const view = new DataView(buffer);
338
- view.setInt16(0, v, false);
339
- this.write(new Uint8Array(buffer));
340
- }
341
- writeLong(v) {
342
- const buffer = new ArrayBuffer(8);
343
- const view = new DataView(buffer);
344
- view.setBigInt64(0, BigInt(v), false);
345
- this.write(new Uint8Array(buffer));
346
- }
347
- readFully(b) {
348
- const pos = this._position;
349
- if (pos + b.length > this._count) {
350
- throw new Error("End of stream");
351
- }
352
- b.set(this.buffer.subarray(pos, pos + b.length));
353
- this._position = pos + b.length;
354
- }
355
- readByte() {
356
- const bytes = new Uint8Array(1);
357
- this.readFully(bytes);
358
- return bytes[0];
359
- }
360
- readShort() {
361
- const bytes = new Uint8Array(2);
362
- this.readFully(bytes);
363
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
364
- return view.getInt16(0, false);
365
- }
366
- readInt() {
367
- const bytes = new Uint8Array(4);
368
- this.readFully(bytes);
369
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
370
- return view.getInt32(0, false);
371
- }
372
- readLong() {
373
- const bytes = new Uint8Array(8);
374
- this.readFully(bytes);
375
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
376
- return Number(view.getBigInt64(0, false));
377
- }
378
- }
379
- // src/core-file.ts
380
- import * as fs from "fs";
381
-
382
- class CoreFile {
383
- filePath;
384
- _position = 0;
385
- fd;
386
- constructor(filePath) {
387
- this.filePath = filePath;
388
- try {
389
- fs.accessSync(filePath);
390
- } catch {
391
- fs.writeFileSync(filePath, new Uint8Array(0));
392
- }
393
- this.fd = fs.openSync(filePath, "r+");
394
- }
395
- reader() {
396
- return new FileDataReader(this);
397
- }
398
- writer() {
399
- return new FileDataWriter(this);
400
- }
401
- length() {
402
- const stats = fs.fstatSync(this.fd);
403
- return stats.size;
404
- }
405
- seek(pos) {
406
- this._position = pos;
407
- }
408
- position() {
409
- return this._position;
410
- }
411
- setLength(len) {
412
- fs.ftruncateSync(this.fd, len);
413
- }
414
- flush() {}
415
- sync() {
416
- fs.fsyncSync(this.fd);
417
- }
418
- [Symbol.dispose]() {
419
- fs.closeSync(this.fd);
420
- }
421
- }
422
-
423
- class FileDataReader {
424
- core;
425
- constructor(core) {
426
- this.core = core;
427
- }
428
- readFully(b) {
429
- const position = this.core.position();
430
- fs.readSync(this.core.fd, b, 0, b.length, position);
431
- this.core.seek(position + b.length);
432
- }
433
- readByte() {
434
- const bytes = new Uint8Array(1);
435
- this.readFully(bytes);
436
- return bytes[0];
437
- }
438
- readShort() {
439
- const bytes = new Uint8Array(2);
440
- this.readFully(bytes);
441
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
442
- return view.getInt16(0, false);
443
- }
444
- readInt() {
445
- const bytes = new Uint8Array(4);
446
- this.readFully(bytes);
447
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
448
- return view.getInt32(0, false);
449
- }
450
- readLong() {
451
- const bytes = new Uint8Array(8);
452
- this.readFully(bytes);
453
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
454
- return Number(view.getBigInt64(0, false));
455
- }
456
- }
457
-
458
- class FileDataWriter {
459
- core;
460
- constructor(core) {
461
- this.core = core;
462
- }
463
- write(buffer) {
464
- const position = this.core.position();
465
- fs.writeSync(this.core.fd, buffer, 0, buffer.length, position);
466
- this.core.seek(position + buffer.length);
467
- }
468
- writeByte(v) {
469
- this.write(new Uint8Array([v & 255]));
470
- }
471
- writeShort(v) {
472
- const buffer = new ArrayBuffer(2);
473
- const view = new DataView(buffer);
474
- view.setInt16(0, v, false);
475
- this.write(new Uint8Array(buffer));
476
- }
477
- writeLong(v) {
478
- const buffer = new ArrayBuffer(8);
479
- const view = new DataView(buffer);
480
- view.setBigInt64(0, BigInt(v), false);
481
- this.write(new Uint8Array(buffer));
482
- }
483
- }
484
- // src/core-buffered-file.ts
485
- class CoreBufferedFile {
486
- file;
487
- constructor(filePath, bufferSize) {
488
- this.file = new RandomAccessBufferedFile(filePath, bufferSize);
489
- }
490
- reader() {
491
- return this.file;
492
- }
493
- writer() {
494
- return this.file;
495
- }
496
- length() {
497
- return this.file.length();
498
- }
499
- seek(pos) {
500
- this.file.seek(pos);
501
- }
502
- position() {
503
- return this.file.position();
504
- }
505
- setLength(len) {
506
- this.file.setLength(len);
507
- }
508
- flush() {
509
- this.file.flush();
510
- }
511
- sync() {
512
- this.file.sync();
513
- }
514
- [Symbol.dispose]() {
515
- this.file.file[Symbol.dispose]();
516
- }
517
- }
518
- var DEFAULT_BUFFER_SIZE = 8 * 1024 * 1024;
519
-
520
- class RandomAccessBufferedFile {
521
- file;
522
- memory;
523
- bufferSize;
524
- filePos;
525
- memoryPos;
526
- constructor(filePath, bufferSize = DEFAULT_BUFFER_SIZE) {
527
- this.file = new CoreFile(filePath);
528
- this.memory = new CoreMemory;
529
- this.bufferSize = bufferSize;
530
- this.filePos = 0;
531
- this.memoryPos = 0;
532
- }
533
- seek(pos) {
534
- if (pos > this.memoryPos + this.memory.length()) {
535
- this.flush();
536
- }
537
- this.filePos = pos;
538
- if (this.memory.length() === 0) {
539
- this.memoryPos = pos;
540
- }
541
- }
542
- length() {
543
- return Math.max(this.memoryPos + this.memory.length(), this.file.length());
544
- }
545
- position() {
546
- return this.filePos;
547
- }
548
- setLength(len) {
549
- this.flush();
550
- this.file.setLength(len);
551
- this.filePos = Math.min(len, this.filePos);
552
- }
553
- flush() {
554
- if (this.memory.length() > 0) {
555
- this.file.seek(this.memoryPos);
556
- this.file.writer().write(this.memory.memory.toByteArray());
557
- this.memoryPos = 0;
558
- this.memory.memory.reset();
559
- }
560
- }
561
- sync() {
562
- this.flush();
563
- this.file.sync();
564
- }
565
- write(buffer) {
566
- if (this.memory.length() + buffer.length > this.bufferSize) {
567
- this.flush();
568
- }
569
- if (this.filePos >= this.memoryPos && this.filePos <= this.memoryPos + this.memory.length()) {
570
- this.memory.seek(this.filePos - this.memoryPos);
571
- this.memory.memory.write(buffer);
572
- } else {
573
- this.file.seek(this.filePos);
574
- this.file.writer().write(buffer);
575
- }
576
- this.filePos += buffer.length;
577
- }
578
- writeByte(v) {
579
- this.write(new Uint8Array([v & 255]));
580
- }
581
- writeShort(v) {
582
- const buffer = new ArrayBuffer(2);
583
- const view = new DataView(buffer);
584
- view.setInt16(0, v & 65535, false);
585
- this.write(new Uint8Array(buffer));
586
- }
587
- writeLong(v) {
588
- const buffer = new ArrayBuffer(8);
589
- const view = new DataView(buffer);
590
- view.setBigInt64(0, BigInt(v), false);
591
- this.write(new Uint8Array(buffer));
592
- }
593
- readFully(buffer) {
594
- let pos = 0;
595
- if (this.filePos < this.memoryPos) {
596
- const sizeBeforeMem = Math.min(this.memoryPos - this.filePos, buffer.length);
597
- const tempBuffer = new Uint8Array(sizeBeforeMem);
598
- this.file.seek(this.filePos);
599
- this.file.reader().readFully(tempBuffer);
600
- buffer.set(tempBuffer, pos);
601
- pos += sizeBeforeMem;
602
- this.filePos += sizeBeforeMem;
603
- }
604
- if (pos === buffer.length)
605
- return;
606
- if (this.filePos >= this.memoryPos && this.filePos < this.memoryPos + this.memory.length()) {
607
- const memPos = this.filePos - this.memoryPos;
608
- const sizeInMem = Math.min(this.memory.length() - memPos, buffer.length - pos);
609
- this.memory.seek(memPos);
610
- const memBuffer = new Uint8Array(sizeInMem);
611
- this.memory.memory.readFully(memBuffer);
612
- buffer.set(memBuffer, pos);
613
- pos += sizeInMem;
614
- this.filePos += sizeInMem;
615
- }
616
- if (pos === buffer.length)
617
- return;
618
- if (this.filePos >= this.memoryPos + this.memory.length()) {
619
- const sizeAfterMem = buffer.length - pos;
620
- const tempBuffer = new Uint8Array(sizeAfterMem);
621
- this.file.seek(this.filePos);
622
- this.file.reader().readFully(tempBuffer);
623
- buffer.set(tempBuffer, pos);
624
- pos += sizeAfterMem;
625
- this.filePos += sizeAfterMem;
626
- }
627
- }
628
- readByte() {
629
- const bytes = new Uint8Array(1);
630
- this.readFully(bytes);
631
- return bytes[0];
632
- }
633
- readShort() {
634
- const bytes = new Uint8Array(2);
635
- this.readFully(bytes);
636
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
637
- return view.getInt16(0, false);
638
- }
639
- readInt() {
640
- const bytes = new Uint8Array(4);
641
- this.readFully(bytes);
642
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
643
- return view.getInt32(0, false);
644
- }
645
- readLong() {
646
- const bytes = new Uint8Array(8);
647
- this.readFully(bytes);
648
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
649
- return Number(view.getBigInt64(0, false));
650
- }
651
- }
652
- // src/hasher.ts
653
- import { createHash } from "crypto";
654
-
655
- class Hasher {
656
- algorithm;
657
- nodeAlgorithm;
658
- id;
659
- digestLength;
660
- constructor(algorithm, id = 0) {
661
- this.algorithm = algorithm;
662
- this.id = id;
663
- switch (algorithm) {
664
- case "SHA-1":
665
- this.digestLength = 20;
666
- this.nodeAlgorithm = "sha1";
667
- break;
668
- case "SHA-256":
669
- this.digestLength = 32;
670
- this.nodeAlgorithm = "sha256";
671
- break;
672
- case "SHA-384":
673
- this.digestLength = 48;
674
- this.nodeAlgorithm = "sha384";
675
- break;
676
- case "SHA-512":
677
- this.digestLength = 64;
678
- this.nodeAlgorithm = "sha512";
679
- break;
680
- default:
681
- throw new Error(`Unsupported hash algorithm: ${algorithm}`);
682
- }
683
- }
684
- digest(data) {
685
- return new Uint8Array(createHash(this.nodeAlgorithm).update(data).digest());
686
- }
687
- static stringToId(hashIdName) {
688
- const bytes = new TextEncoder().encode(hashIdName);
689
- if (bytes.length !== 4) {
690
- throw new Error("Name must be exactly four bytes long");
691
- }
692
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
693
- return view.getInt32(0, false);
694
- }
695
- static idToString(id) {
696
- const buffer = new ArrayBuffer(4);
697
- const view = new DataView(buffer);
698
- view.setInt32(0, id, false);
699
- return new TextDecoder().decode(new Uint8Array(buffer));
700
- }
701
- }
702
- // src/read-cursor.ts
703
- class KeyValuePairCursor {
704
- valueCursor;
705
- keyCursor;
706
- hash;
707
- constructor(valueCursor, keyCursor, hash) {
708
- this.valueCursor = valueCursor;
709
- this.keyCursor = keyCursor;
710
- this.hash = hash;
711
- }
712
- }
713
-
714
- class ReadCursor {
715
- slotPtr;
716
- db;
717
- constructor(slotPtr, db) {
718
- this.slotPtr = slotPtr;
719
- this.db = db;
720
- }
721
- slot() {
722
- return this.slotPtr.slot;
723
- }
724
- readPath(path) {
725
- try {
726
- const slotPtr = this.db.readSlotPointer(0 /* READ_ONLY */, path, 0, this.slotPtr);
727
- return new ReadCursor(slotPtr, this.db);
728
- } catch (e) {
729
- if (e instanceof KeyNotFoundException) {
730
- return null;
731
- }
732
- throw e;
733
- }
734
- }
735
- readPathSlot(path) {
736
- try {
737
- const slotPtr = this.db.readSlotPointer(0 /* READ_ONLY */, path, 0, this.slotPtr);
738
- if (!slotPtr.slot.empty()) {
739
- return slotPtr.slot;
740
- } else {
741
- return null;
742
- }
743
- } catch (e) {
744
- if (e instanceof KeyNotFoundException) {
745
- return null;
746
- }
747
- throw e;
748
- }
749
- }
750
- readUint() {
751
- if (this.slotPtr.slot.tag !== 8 /* UINT */) {
752
- throw new UnexpectedTagException;
753
- }
754
- if (this.slotPtr.slot.value < 0n)
755
- throw new ExpectedUnsignedLongException;
756
- return Number(this.slotPtr.slot.value);
757
- }
758
- readInt() {
759
- if (this.slotPtr.slot.tag !== 9 /* INT */) {
760
- throw new UnexpectedTagException;
761
- }
762
- return Number(this.slotPtr.slot.value);
763
- }
764
- readFloat() {
765
- if (this.slotPtr.slot.tag !== 10 /* FLOAT */) {
766
- throw new UnexpectedTagException;
767
- }
768
- const buffer = new ArrayBuffer(8);
769
- const view = new DataView(buffer);
770
- view.setBigInt64(0, this.slotPtr.slot.value, false);
771
- return view.getFloat64(0, false);
772
- }
773
- readBytes(maxSizeMaybe = null) {
774
- const bytesObj = this.readBytesObject(maxSizeMaybe);
775
- return bytesObj.value;
776
- }
777
- readBytesObject(maxSizeMaybe = null) {
778
- const reader = this.db.core.reader();
779
- switch (this.slotPtr.slot.tag) {
780
- case 0 /* NONE */:
781
- return new Bytes(new Uint8Array(0));
782
- case 6 /* BYTES */: {
783
- this.db.core.seek(Number(this.slotPtr.slot.value));
784
- const valueSize = reader.readLong();
785
- if (maxSizeMaybe !== null && valueSize > maxSizeMaybe) {
786
- throw new StreamTooLongException;
787
- }
788
- const startPosition = this.db.core.position();
789
- const value = new Uint8Array(valueSize);
790
- reader.readFully(value);
791
- let formatTag = null;
792
- if (this.slotPtr.slot.full) {
793
- this.db.core.seek(startPosition + valueSize);
794
- formatTag = new Uint8Array(2);
795
- reader.readFully(formatTag);
796
- }
797
- return new Bytes(value, formatTag);
798
- }
799
- case 7 /* SHORT_BYTES */: {
800
- const buffer = new ArrayBuffer(8);
801
- const view = new DataView(buffer);
802
- view.setBigInt64(0, this.slotPtr.slot.value, false);
803
- const bytes = new Uint8Array(buffer);
804
- const totalSize = this.slotPtr.slot.full ? bytes.length - 2 : bytes.length;
805
- let valueSize = 0;
806
- for (const b of bytes) {
807
- if (b === 0 || valueSize === totalSize)
808
- break;
809
- valueSize += 1;
810
- }
811
- if (maxSizeMaybe !== null && valueSize > maxSizeMaybe) {
812
- throw new StreamTooLongException;
813
- }
814
- let formatTag = null;
815
- if (this.slotPtr.slot.full) {
816
- formatTag = bytes.slice(totalSize, bytes.length);
817
- }
818
- return new Bytes(bytes.slice(0, valueSize), formatTag);
819
- }
820
- default:
821
- throw new UnexpectedTagException;
822
- }
823
- }
824
- readKeyValuePair() {
825
- const reader = this.db.core.reader();
826
- if (this.slotPtr.slot.tag !== 5 /* KV_PAIR */) {
827
- throw new UnexpectedTagException;
828
- }
829
- this.db.core.seek(Number(this.slotPtr.slot.value));
830
- const kvPairBytes = new Uint8Array(KeyValuePair.length(this.db.header.hashSize));
831
- reader.readFully(kvPairBytes);
832
- const kvPair = KeyValuePair.fromBytes(kvPairBytes, this.db.header.hashSize);
833
- const hashPos = Number(this.slotPtr.slot.value);
834
- const keySlotPos = hashPos + this.db.header.hashSize;
835
- const valueSlotPos = keySlotPos + Slot.LENGTH;
836
- return new KeyValuePairCursor(new ReadCursor(new SlotPointer(valueSlotPos, kvPair.valueSlot), this.db), new ReadCursor(new SlotPointer(keySlotPos, kvPair.keySlot), this.db), kvPair.hash);
837
- }
838
- reader() {
839
- const reader = this.db.core.reader();
840
- switch (this.slotPtr.slot.tag) {
841
- case 6 /* BYTES */: {
842
- this.db.core.seek(Number(this.slotPtr.slot.value));
843
- const size = reader.readLong();
844
- const startPosition = this.db.core.position();
845
- return new Reader(this, size, startPosition, 0);
846
- }
847
- case 7 /* SHORT_BYTES */: {
848
- const buffer = new ArrayBuffer(8);
849
- const view = new DataView(buffer);
850
- view.setBigInt64(0, this.slotPtr.slot.value, false);
851
- const bytes = new Uint8Array(buffer);
852
- const totalSize = this.slotPtr.slot.full ? bytes.length - 2 : bytes.length;
853
- let valueSize = 0;
854
- for (const b of bytes) {
855
- if (b === 0 || valueSize === totalSize)
856
- break;
857
- valueSize += 1;
858
- }
859
- const startPosition = this.slotPtr.position + 1;
860
- return new Reader(this, valueSize, startPosition, 0);
861
- }
862
- default:
863
- throw new UnexpectedTagException;
864
- }
865
- }
866
- count() {
867
- const reader = this.db.core.reader();
868
- switch (this.slotPtr.slot.tag) {
869
- case 0 /* NONE */:
870
- return 0;
871
- case 2 /* ARRAY_LIST */: {
872
- this.db.core.seek(Number(this.slotPtr.slot.value));
873
- const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
874
- reader.readFully(headerBytes);
875
- const header = ArrayListHeader.fromBytes(headerBytes);
876
- return header.size;
877
- }
878
- case 3 /* LINKED_ARRAY_LIST */: {
879
- this.db.core.seek(Number(this.slotPtr.slot.value));
880
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
881
- reader.readFully(headerBytes);
882
- const header = LinkedArrayListHeader.fromBytes(headerBytes);
883
- return header.size;
884
- }
885
- case 6 /* BYTES */: {
886
- this.db.core.seek(Number(this.slotPtr.slot.value));
887
- return reader.readLong();
888
- }
889
- case 7 /* SHORT_BYTES */: {
890
- const buffer = new ArrayBuffer(8);
891
- const view = new DataView(buffer);
892
- view.setBigInt64(0, this.slotPtr.slot.value, false);
893
- const bytes = new Uint8Array(buffer);
894
- const totalSize = this.slotPtr.slot.full ? bytes.length - 2 : bytes.length;
895
- let size = 0;
896
- for (const b of bytes) {
897
- if (b === 0 || size === totalSize)
898
- break;
899
- size += 1;
900
- }
901
- return size;
902
- }
903
- case 12 /* COUNTED_HASH_MAP */:
904
- case 13 /* COUNTED_HASH_SET */: {
905
- this.db.core.seek(Number(this.slotPtr.slot.value));
906
- return reader.readLong();
907
- }
908
- default:
909
- throw new UnexpectedTagException;
910
- }
911
- }
912
- *[Symbol.iterator]() {
913
- const iterator = this.iterator();
914
- while (iterator.hasNext()) {
915
- const next = iterator.next();
916
- if (next !== null) {
917
- yield next;
918
- }
919
- }
920
- }
921
- iterator() {
922
- const iterator = new CursorIterator(this);
923
- iterator.init();
924
- return iterator;
925
- }
926
- }
927
-
928
- class Reader {
929
- parent;
930
- size;
931
- startPosition;
932
- relativePosition;
933
- constructor(parent, size, startPosition, relativePosition) {
934
- this.parent = parent;
935
- this.size = size;
936
- this.startPosition = startPosition;
937
- this.relativePosition = relativePosition;
938
- }
939
- read(buffer) {
940
- if (this.size < this.relativePosition)
941
- throw new EndOfStreamException;
942
- this.parent.db.core.seek(this.startPosition + this.relativePosition);
943
- const readSize = Math.min(buffer.length, this.size - this.relativePosition);
944
- if (readSize === 0)
945
- return -1;
946
- const reader = this.parent.db.core.reader();
947
- const tempBuffer = new Uint8Array(readSize);
948
- reader.readFully(tempBuffer);
949
- buffer.set(tempBuffer);
950
- this.relativePosition += readSize;
951
- return readSize;
952
- }
953
- readFully(buffer) {
954
- if (this.size < this.relativePosition || this.size - this.relativePosition < buffer.length) {
955
- throw new EndOfStreamException;
956
- }
957
- this.parent.db.core.seek(this.startPosition + this.relativePosition);
958
- const reader = this.parent.db.core.reader();
959
- reader.readFully(buffer);
960
- this.relativePosition += buffer.length;
961
- }
962
- readByte() {
963
- const bytes = new Uint8Array(1);
964
- this.readFully(bytes);
965
- return bytes[0];
966
- }
967
- readShort() {
968
- const readSize = 2;
969
- const bytes = new Uint8Array(readSize);
970
- this.readFully(bytes);
971
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
972
- return view.getInt16(0, false);
973
- }
974
- readInt() {
975
- const readSize = 4;
976
- const bytes = new Uint8Array(readSize);
977
- this.readFully(bytes);
978
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
979
- return view.getInt32(0, false);
980
- }
981
- readLong() {
982
- const readSize = 8;
983
- const bytes = new Uint8Array(readSize);
984
- this.readFully(bytes);
985
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
986
- return Number(view.getBigInt64(0, false));
987
- }
988
- seek(position) {
989
- if (position > this.size) {
990
- throw new InvalidOffsetException;
991
- }
992
- this.relativePosition = position;
993
- }
994
- }
995
-
996
- class IteratorLevel {
997
- position;
998
- block;
999
- index;
1000
- constructor(position, block, index) {
1001
- this.position = position;
1002
- this.block = block;
1003
- this.index = index;
1004
- }
1005
- }
1006
-
1007
- class CursorIterator {
1008
- cursor;
1009
- size = 0;
1010
- index = 0;
1011
- stack = [];
1012
- nextCursorMaybe = null;
1013
- constructor(cursor) {
1014
- this.cursor = cursor;
1015
- }
1016
- init() {
1017
- switch (this.cursor.slotPtr.slot.tag) {
1018
- case 0 /* NONE */:
1019
- this.size = 0;
1020
- this.index = 0;
1021
- this.stack = [];
1022
- break;
1023
- case 2 /* ARRAY_LIST */: {
1024
- const position = Number(this.cursor.slotPtr.slot.value);
1025
- this.cursor.db.core.seek(position);
1026
- const reader = this.cursor.db.core.reader();
1027
- const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
1028
- reader.readFully(headerBytes);
1029
- const header = ArrayListHeader.fromBytes(headerBytes);
1030
- this.size = this.cursor.count();
1031
- this.index = 0;
1032
- this.stack = this.initStack(this.cursor, header.ptr, INDEX_BLOCK_SIZE);
1033
- break;
1034
- }
1035
- case 3 /* LINKED_ARRAY_LIST */: {
1036
- const position = Number(this.cursor.slotPtr.slot.value);
1037
- this.cursor.db.core.seek(position);
1038
- const reader = this.cursor.db.core.reader();
1039
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
1040
- reader.readFully(headerBytes);
1041
- const header = LinkedArrayListHeader.fromBytes(headerBytes);
1042
- this.size = this.cursor.count();
1043
- this.index = 0;
1044
- this.stack = this.initStack(this.cursor, header.ptr, LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
1045
- break;
1046
- }
1047
- case 4 /* HASH_MAP */:
1048
- case 11 /* HASH_SET */:
1049
- this.size = 0;
1050
- this.index = 0;
1051
- this.stack = this.initStack(this.cursor, Number(this.cursor.slotPtr.slot.value), INDEX_BLOCK_SIZE);
1052
- break;
1053
- case 12 /* COUNTED_HASH_MAP */:
1054
- case 13 /* COUNTED_HASH_SET */:
1055
- this.size = 0;
1056
- this.index = 0;
1057
- this.stack = this.initStack(this.cursor, Number(this.cursor.slotPtr.slot.value) + 8, INDEX_BLOCK_SIZE);
1058
- break;
1059
- default:
1060
- throw new UnexpectedTagException;
1061
- }
1062
- }
1063
- initStack(cursor, position, blockSize) {
1064
- cursor.db.core.seek(position);
1065
- const reader = cursor.db.core.reader();
1066
- const indexBlockBytes = new Uint8Array(blockSize);
1067
- reader.readFully(indexBlockBytes);
1068
- const indexBlock = new Array(SLOT_COUNT);
1069
- const slotSize = blockSize / SLOT_COUNT;
1070
- for (let i = 0;i < SLOT_COUNT; i++) {
1071
- const slotBytes = indexBlockBytes.slice(i * slotSize, i * slotSize + Slot.LENGTH);
1072
- indexBlock[i] = Slot.fromBytes(slotBytes);
1073
- }
1074
- return [new IteratorLevel(position, indexBlock, 0)];
1075
- }
1076
- hasNext() {
1077
- switch (this.cursor.slotPtr.slot.tag) {
1078
- case 0 /* NONE */:
1079
- return false;
1080
- case 2 /* ARRAY_LIST */:
1081
- return this.index < this.size;
1082
- case 3 /* LINKED_ARRAY_LIST */:
1083
- return this.index < this.size;
1084
- case 4 /* HASH_MAP */:
1085
- case 11 /* HASH_SET */:
1086
- case 12 /* COUNTED_HASH_MAP */:
1087
- case 13 /* COUNTED_HASH_SET */:
1088
- if (this.nextCursorMaybe === null) {
1089
- this.nextCursorMaybe = this.nextInternal(INDEX_BLOCK_SIZE);
1090
- }
1091
- return this.nextCursorMaybe !== null;
1092
- default:
1093
- return false;
1094
- }
1095
- }
1096
- next() {
1097
- switch (this.cursor.slotPtr.slot.tag) {
1098
- case 0 /* NONE */:
1099
- return null;
1100
- case 2 /* ARRAY_LIST */:
1101
- if (!this.hasNext())
1102
- return null;
1103
- this.index += 1;
1104
- return this.nextInternal(INDEX_BLOCK_SIZE);
1105
- case 3 /* LINKED_ARRAY_LIST */:
1106
- if (!this.hasNext())
1107
- return null;
1108
- this.index += 1;
1109
- return this.nextInternal(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
1110
- case 4 /* HASH_MAP */:
1111
- case 11 /* HASH_SET */:
1112
- case 12 /* COUNTED_HASH_MAP */:
1113
- case 13 /* COUNTED_HASH_SET */:
1114
- if (this.nextCursorMaybe !== null) {
1115
- const nextCursor = this.nextCursorMaybe;
1116
- this.nextCursorMaybe = null;
1117
- return nextCursor;
1118
- } else {
1119
- return this.nextInternal(INDEX_BLOCK_SIZE);
1120
- }
1121
- default:
1122
- throw new UnexpectedTagException;
1123
- }
1124
- }
1125
- nextInternal(blockSize) {
1126
- while (this.stack.length > 0) {
1127
- const level = this.stack[this.stack.length - 1];
1128
- if (level.index === level.block.length) {
1129
- this.stack.pop();
1130
- if (this.stack.length > 0) {
1131
- this.stack[this.stack.length - 1].index += 1;
1132
- }
1133
- continue;
1134
- } else {
1135
- const nextSlot = level.block[level.index];
1136
- if (nextSlot.tag === 1 /* INDEX */) {
1137
- const nextPos = Number(nextSlot.value);
1138
- this.cursor.db.core.seek(nextPos);
1139
- const reader = this.cursor.db.core.reader();
1140
- const indexBlockBytes = new Uint8Array(blockSize);
1141
- reader.readFully(indexBlockBytes);
1142
- const indexBlock = new Array(SLOT_COUNT);
1143
- const slotSize = blockSize / SLOT_COUNT;
1144
- for (let i = 0;i < SLOT_COUNT; i++) {
1145
- const slotBytes = indexBlockBytes.slice(i * slotSize, i * slotSize + Slot.LENGTH);
1146
- indexBlock[i] = Slot.fromBytes(slotBytes);
1147
- }
1148
- this.stack.push(new IteratorLevel(nextPos, indexBlock, 0));
1149
- continue;
1150
- } else {
1151
- this.stack[this.stack.length - 1].index += 1;
1152
- if (!nextSlot.empty()) {
1153
- const position = level.position + level.index * Slot.LENGTH;
1154
- return new ReadCursor(new SlotPointer(position, nextSlot), this.cursor.db);
1155
- } else {
1156
- continue;
1157
- }
1158
- }
1159
- }
1160
- }
1161
- return null;
1162
- }
1163
- }
1164
-
1165
- // src/write-cursor.ts
1166
- class WriteKeyValuePairCursor extends KeyValuePairCursor {
1167
- valueCursor;
1168
- keyCursor;
1169
- constructor(valueCursor, keyCursor, hash) {
1170
- super(valueCursor, keyCursor, hash);
1171
- this.valueCursor = valueCursor;
1172
- this.keyCursor = keyCursor;
1173
- }
1174
- }
1175
-
1176
- class WriteCursor extends ReadCursor {
1177
- constructor(slotPtr, db) {
1178
- super(slotPtr, db);
1179
- }
1180
- writePath(path) {
1181
- const slotPtr = this.db.readSlotPointer(1 /* READ_WRITE */, path, 0, this.slotPtr);
1182
- if (this.db.txStart === null) {
1183
- this.db.core.sync();
1184
- }
1185
- return new WriteCursor(slotPtr, this.db);
1186
- }
1187
- write(data) {
1188
- const cursor = this.writePath([new WriteData(data)]);
1189
- this.slotPtr = cursor.slotPtr;
1190
- }
1191
- writeIfEmpty(data) {
1192
- if (this.slotPtr.slot.empty()) {
1193
- this.write(data);
1194
- }
1195
- }
1196
- readKeyValuePair() {
1197
- const kvPairCursor = super.readKeyValuePair();
1198
- return new WriteKeyValuePairCursor(new WriteCursor(kvPairCursor.valueCursor.slotPtr, this.db), new WriteCursor(kvPairCursor.keyCursor.slotPtr, this.db), kvPairCursor.hash);
1199
- }
1200
- writer() {
1201
- const writer = this.db.core.writer();
1202
- const ptrPos = this.db.core.length();
1203
- this.db.core.seek(ptrPos);
1204
- writer.writeLong(0);
1205
- const startPosition = this.db.core.length();
1206
- return new Writer(this, 0, new Slot(ptrPos, 6 /* BYTES */), startPosition, 0);
1207
- }
1208
- *[Symbol.iterator]() {
1209
- const iterator = this.iterator();
1210
- while (iterator.hasNext()) {
1211
- const next = iterator.next();
1212
- if (next !== null) {
1213
- yield next;
1214
- }
1215
- }
1216
- }
1217
- iterator() {
1218
- const iterator = new WriteCursorIterator(this);
1219
- iterator.init();
1220
- return iterator;
1221
- }
1222
- }
1223
-
1224
- class Writer {
1225
- parent;
1226
- size;
1227
- slot;
1228
- startPosition;
1229
- relativePosition;
1230
- formatTag = null;
1231
- constructor(parent, size, slot, startPosition, relativePosition) {
1232
- this.parent = parent;
1233
- this.size = size;
1234
- this.slot = slot;
1235
- this.startPosition = startPosition;
1236
- this.relativePosition = relativePosition;
1237
- }
1238
- write(buffer) {
1239
- if (this.size < this.relativePosition)
1240
- throw new EndOfStreamException;
1241
- this.parent.db.core.seek(this.startPosition + this.relativePosition);
1242
- const writer = this.parent.db.core.writer();
1243
- writer.write(buffer);
1244
- this.relativePosition += buffer.length;
1245
- if (this.relativePosition > this.size) {
1246
- this.size = this.relativePosition;
1247
- }
1248
- }
1249
- finish() {
1250
- const writer = this.parent.db.core.writer();
1251
- if (this.formatTag !== null) {
1252
- this.slot = this.slot.withFull(true);
1253
- const formatTagPos = this.parent.db.core.length();
1254
- this.parent.db.core.seek(formatTagPos);
1255
- if (this.startPosition + this.size !== formatTagPos)
1256
- throw new UnexpectedWriterPositionException;
1257
- writer.write(this.formatTag);
1258
- }
1259
- this.parent.db.core.seek(Number(this.slot.value));
1260
- writer.writeLong(this.size);
1261
- if (this.parent.slotPtr.position === null)
1262
- throw new CursorNotWriteableException;
1263
- const position = this.parent.slotPtr.position;
1264
- this.parent.db.core.seek(position);
1265
- writer.write(this.slot.toBytes());
1266
- this.parent.slotPtr = this.parent.slotPtr.withSlot(this.slot);
1267
- }
1268
- seek(position) {
1269
- if (position <= this.size) {
1270
- this.relativePosition = position;
1271
- }
1272
- }
1273
- }
1274
-
1275
- class WriteCursorIterator extends CursorIterator {
1276
- constructor(cursor) {
1277
- super(cursor);
1278
- }
1279
- next() {
1280
- const readCursor = super.next();
1281
- if (readCursor !== null) {
1282
- return new WriteCursor(readCursor.slotPtr, readCursor.db);
1283
- } else {
1284
- return null;
1285
- }
1286
- }
1287
- }
1288
-
1289
- // src/database.ts
1290
- var VERSION = 0;
1291
- var MAGIC_NUMBER = new Uint8Array([120, 105, 116]);
1292
- var BIT_COUNT = 4;
1293
- var SLOT_COUNT = 1 << BIT_COUNT;
1294
- var MASK = BigInt(SLOT_COUNT - 1);
1295
- var INDEX_BLOCK_SIZE = Slot.LENGTH * SLOT_COUNT;
1296
- var LINKED_ARRAY_LIST_SLOT_LENGTH = 8 + Slot.LENGTH;
1297
- var LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE = LINKED_ARRAY_LIST_SLOT_LENGTH * SLOT_COUNT;
1298
- var MAX_BRANCH_LENGTH = 16;
1299
- var WriteMode;
1300
- ((WriteMode2) => {
1301
- WriteMode2[WriteMode2["READ_ONLY"] = 0] = "READ_ONLY";
1302
- WriteMode2[WriteMode2["READ_WRITE"] = 1] = "READ_WRITE";
1303
- })(WriteMode ||= {});
1304
-
1305
- class Header {
1306
- hashId;
1307
- hashSize;
1308
- version;
1309
- tag;
1310
- magicNumber;
1311
- static LENGTH = 12;
1312
- constructor(hashId, hashSize, version, tag, magicNumber) {
1313
- this.hashId = hashId;
1314
- this.hashSize = hashSize;
1315
- this.version = version;
1316
- this.tag = tag;
1317
- this.magicNumber = magicNumber;
1318
- }
1319
- toBytes() {
1320
- const buffer = new ArrayBuffer(Header.LENGTH);
1321
- const view = new DataView(buffer);
1322
- const arr = new Uint8Array(buffer);
1323
- arr.set(this.magicNumber, 0);
1324
- view.setUint8(3, this.tag);
1325
- view.setInt16(4, this.version, false);
1326
- view.setInt16(6, this.hashSize, false);
1327
- view.setInt32(8, this.hashId, false);
1328
- return arr;
1329
- }
1330
- static read(core) {
1331
- const reader = core.reader();
1332
- const magicNumber = new Uint8Array(3);
1333
- reader.readFully(magicNumber);
1334
- const tagByte = reader.readByte();
1335
- const tag = tagValueOf(tagByte & 127);
1336
- const version = reader.readShort();
1337
- const hashSize = reader.readShort();
1338
- const hashId = reader.readInt();
1339
- return new Header(hashId, hashSize, version, tag, magicNumber);
1340
- }
1341
- write(core) {
1342
- const writer = core.writer();
1343
- writer.write(this.toBytes());
1344
- }
1345
- validate() {
1346
- if (!arraysEqual(this.magicNumber, MAGIC_NUMBER)) {
1347
- throw new InvalidDatabaseException;
1348
- }
1349
- if (this.version > VERSION) {
1350
- throw new InvalidVersionException;
1351
- }
1352
- }
1353
- withTag(tag) {
1354
- return new Header(this.hashId, this.hashSize, this.version, tag, this.magicNumber);
1355
- }
1356
- }
1357
-
1358
- class ArrayListHeader {
1359
- ptr;
1360
- size;
1361
- static LENGTH = 16;
1362
- constructor(ptr, size) {
1363
- this.ptr = ptr;
1364
- this.size = size;
1365
- }
1366
- toBytes() {
1367
- const buffer = new ArrayBuffer(ArrayListHeader.LENGTH);
1368
- const view = new DataView(buffer);
1369
- view.setBigInt64(0, BigInt(this.size), false);
1370
- view.setBigInt64(8, BigInt(this.ptr), false);
1371
- return new Uint8Array(buffer);
1372
- }
1373
- static fromBytes(bytes) {
1374
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1375
- const size = Number(view.getBigInt64(0, false));
1376
- checkLong(size);
1377
- const ptr = Number(view.getBigInt64(8, false));
1378
- checkLong(ptr);
1379
- return new ArrayListHeader(ptr, size);
1380
- }
1381
- withPtr(ptr) {
1382
- return new ArrayListHeader(ptr, this.size);
1383
- }
1384
- }
1385
-
1386
- class TopLevelArrayListHeader {
1387
- fileSize;
1388
- parent;
1389
- static LENGTH = 8 + ArrayListHeader.LENGTH;
1390
- constructor(fileSize, parent) {
1391
- this.fileSize = fileSize;
1392
- this.parent = parent;
1393
- }
1394
- toBytes() {
1395
- const buffer = new ArrayBuffer(TopLevelArrayListHeader.LENGTH);
1396
- const view = new DataView(buffer);
1397
- const arr = new Uint8Array(buffer);
1398
- arr.set(this.parent.toBytes(), 0);
1399
- view.setBigInt64(ArrayListHeader.LENGTH, BigInt(this.fileSize), false);
1400
- return arr;
1401
- }
1402
- }
1403
-
1404
- class LinkedArrayListHeader {
1405
- shift;
1406
- ptr;
1407
- size;
1408
- static LENGTH = 17;
1409
- constructor(shift, ptr, size) {
1410
- this.shift = shift;
1411
- this.ptr = ptr;
1412
- this.size = size;
1413
- }
1414
- toBytes() {
1415
- const buffer = new ArrayBuffer(LinkedArrayListHeader.LENGTH);
1416
- const view = new DataView(buffer);
1417
- view.setBigInt64(0, BigInt(this.size), false);
1418
- view.setBigInt64(8, BigInt(this.ptr), false);
1419
- view.setUint8(16, this.shift & 63);
1420
- return new Uint8Array(buffer);
1421
- }
1422
- static fromBytes(bytes) {
1423
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1424
- const size = Number(view.getBigInt64(0, false));
1425
- checkLong(size);
1426
- const ptr = Number(view.getBigInt64(8, false));
1427
- checkLong(ptr);
1428
- const shift = view.getUint8(16) & 63;
1429
- return new LinkedArrayListHeader(shift, ptr, size);
1430
- }
1431
- withPtr(ptr) {
1432
- return new LinkedArrayListHeader(this.shift, ptr, this.size);
1433
- }
1434
- }
1435
-
1436
- class KeyValuePair {
1437
- valueSlot;
1438
- keySlot;
1439
- hash;
1440
- constructor(valueSlot, keySlot, hash) {
1441
- this.valueSlot = valueSlot;
1442
- this.keySlot = keySlot;
1443
- this.hash = hash;
1444
- }
1445
- static length(hashSize) {
1446
- return hashSize + Slot.LENGTH * 2;
1447
- }
1448
- toBytes() {
1449
- const buffer = new Uint8Array(KeyValuePair.length(this.hash.length));
1450
- buffer.set(this.hash, 0);
1451
- buffer.set(this.keySlot.toBytes(), this.hash.length);
1452
- buffer.set(this.valueSlot.toBytes(), this.hash.length + Slot.LENGTH);
1453
- return buffer;
1454
- }
1455
- static fromBytes(bytes, hashSize) {
1456
- const hash = bytes.slice(0, hashSize);
1457
- const keySlotBytes = bytes.slice(hashSize, hashSize + Slot.LENGTH);
1458
- const keySlot = Slot.fromBytes(keySlotBytes);
1459
- const valueSlotBytes = bytes.slice(hashSize + Slot.LENGTH, hashSize + Slot.LENGTH * 2);
1460
- const valueSlot = Slot.fromBytes(valueSlotBytes);
1461
- return new KeyValuePair(valueSlot, keySlot, hash);
1462
- }
1463
- }
1464
-
1465
- class LinkedArrayListSlot2 {
1466
- size;
1467
- slot;
1468
- static LENGTH = 8 + Slot.LENGTH;
1469
- constructor(size, slot) {
1470
- this.size = size;
1471
- this.slot = slot;
1472
- }
1473
- withSize(size) {
1474
- return new LinkedArrayListSlot2(size, this.slot);
1475
- }
1476
- toBytes() {
1477
- const buffer = new ArrayBuffer(LinkedArrayListSlot2.LENGTH);
1478
- const view = new DataView(buffer);
1479
- const arr = new Uint8Array(buffer);
1480
- arr.set(this.slot.toBytes(), 0);
1481
- view.setBigInt64(Slot.LENGTH, BigInt(this.size), false);
1482
- return arr;
1483
- }
1484
- static fromBytes(bytes) {
1485
- const slotBytes = bytes.slice(0, Slot.LENGTH);
1486
- const slot = Slot.fromBytes(slotBytes);
1487
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1488
- const size = Number(view.getBigInt64(Slot.LENGTH, false));
1489
- checkLong(size);
1490
- return new LinkedArrayListSlot2(size, slot);
1491
- }
1492
- }
1493
-
1494
- class LinkedArrayListSlotPointer {
1495
- slotPtr;
1496
- leafCount;
1497
- constructor(slotPtr, leafCount) {
1498
- this.slotPtr = slotPtr;
1499
- this.leafCount = leafCount;
1500
- }
1501
- withSlotPointer(slotPtr) {
1502
- return new LinkedArrayListSlotPointer(slotPtr, this.leafCount);
1503
- }
1504
- }
1505
-
1506
- class LinkedArrayListBlockInfo {
1507
- block;
1508
- i;
1509
- parentSlot;
1510
- constructor(block, i, parentSlot) {
1511
- this.block = block;
1512
- this.i = i;
1513
- this.parentSlot = parentSlot;
1514
- }
1515
- }
1516
-
1517
- class HashMapGetKVPair {
1518
- hash;
1519
- kind = "kv_pair";
1520
- constructor(hash) {
1521
- this.hash = hash;
1522
- }
1523
- }
1524
-
1525
- class HashMapGetKey {
1526
- hash;
1527
- kind = "key";
1528
- constructor(hash) {
1529
- this.hash = hash;
1530
- }
1531
- }
1532
-
1533
- class HashMapGetValue {
1534
- hash;
1535
- kind = "value";
1536
- constructor(hash) {
1537
- this.hash = hash;
1538
- }
1539
- }
1540
-
1541
- class ArrayListInit {
1542
- kind = "ArrayListInit";
1543
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1544
- if (writeMode === 0 /* READ_ONLY */)
1545
- throw new WriteNotAllowedException;
1546
- if (isTopLevel) {
1547
- const writer = db.core.writer();
1548
- if (db.header.tag === 0 /* NONE */) {
1549
- db.core.seek(Header.LENGTH);
1550
- const arrayListPtr = Header.LENGTH + TopLevelArrayListHeader.LENGTH;
1551
- writer.write(new TopLevelArrayListHeader(0, new ArrayListHeader(arrayListPtr, 0)).toBytes());
1552
- writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
1553
- db.core.seek(0);
1554
- db.header = db.header.withTag(2 /* ARRAY_LIST */);
1555
- writer.write(db.header.toBytes());
1556
- }
1557
- const nextSlotPtr = slotPtr.withSlot(slotPtr.slot.withTag(2 /* ARRAY_LIST */));
1558
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
1559
- }
1560
- if (slotPtr.position === null)
1561
- throw new CursorNotWriteableException;
1562
- const position = slotPtr.position;
1563
- switch (slotPtr.slot.tag) {
1564
- case 0 /* NONE */: {
1565
- const writer = db.core.writer();
1566
- let arrayListStart = db.core.length();
1567
- db.core.seek(arrayListStart);
1568
- const arrayListPtr = arrayListStart + ArrayListHeader.LENGTH;
1569
- writer.write(new ArrayListHeader(arrayListPtr, 0).toBytes());
1570
- writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
1571
- const nextSlotPtr = new SlotPointer(position, new Slot(arrayListStart, 2 /* ARRAY_LIST */));
1572
- db.core.seek(position);
1573
- writer.write(nextSlotPtr.slot.toBytes());
1574
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
1575
- }
1576
- case 2 /* ARRAY_LIST */: {
1577
- const reader = db.core.reader();
1578
- const writer = db.core.writer();
1579
- let arrayListStart = Number(slotPtr.slot.value);
1580
- if (db.txStart !== null) {
1581
- if (arrayListStart < db.txStart) {
1582
- db.core.seek(arrayListStart);
1583
- const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
1584
- reader.readFully(headerBytes);
1585
- const header = ArrayListHeader.fromBytes(headerBytes);
1586
- db.core.seek(header.ptr);
1587
- const arrayListIndexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
1588
- reader.readFully(arrayListIndexBlock);
1589
- arrayListStart = db.core.length();
1590
- db.core.seek(arrayListStart);
1591
- const nextArrayListPtr = arrayListStart + ArrayListHeader.LENGTH;
1592
- const newHeader = header.withPtr(nextArrayListPtr);
1593
- writer.write(newHeader.toBytes());
1594
- writer.write(arrayListIndexBlock);
1595
- }
1596
- } else if (db.header.tag === 2 /* ARRAY_LIST */) {
1597
- throw new ExpectedTxStartException;
1598
- }
1599
- const nextSlotPtr = new SlotPointer(position, new Slot(arrayListStart, 2 /* ARRAY_LIST */));
1600
- db.core.seek(position);
1601
- writer.write(nextSlotPtr.slot.toBytes());
1602
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
1603
- }
1604
- default:
1605
- throw new UnexpectedTagException;
1606
- }
1607
- }
1608
- }
1609
-
1610
- class ArrayListGet2 {
1611
- index;
1612
- kind = "ArrayListGet";
1613
- constructor(index) {
1614
- this.index = index;
1615
- }
1616
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1617
- const tag = isTopLevel ? db.header.tag : slotPtr.slot.tag;
1618
- switch (tag) {
1619
- case 0 /* NONE */:
1620
- throw new KeyNotFoundException;
1621
- case 2 /* ARRAY_LIST */:
1622
- break;
1623
- default:
1624
- throw new UnexpectedTagException;
1625
- }
1626
- const nextArrayListStart = Number(slotPtr.slot.value);
1627
- let index = this.index;
1628
- db.core.seek(nextArrayListStart);
1629
- const reader = db.core.reader();
1630
- const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
1631
- reader.readFully(headerBytes);
1632
- const header = ArrayListHeader.fromBytes(headerBytes);
1633
- if (index >= header.size || index < -header.size) {
1634
- throw new KeyNotFoundException;
1635
- }
1636
- const key = index < 0 ? header.size - Math.abs(index) : index;
1637
- const lastKey = header.size - 1;
1638
- const shift = lastKey < SLOT_COUNT ? 0 : Math.floor(Math.log(lastKey) / Math.log(SLOT_COUNT));
1639
- const finalSlotPtr = db.readArrayListSlot(header.ptr, key, shift, writeMode, isTopLevel);
1640
- return db.readSlotPointer(writeMode, path, pathI + 1, finalSlotPtr);
1641
- }
1642
- }
1643
-
1644
- class ArrayListAppend {
1645
- kind = "ArrayListAppend";
1646
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1647
- if (writeMode === 0 /* READ_ONLY */)
1648
- throw new WriteNotAllowedException;
1649
- const tag = isTopLevel ? db.header.tag : slotPtr.slot.tag;
1650
- if (tag !== 2 /* ARRAY_LIST */)
1651
- throw new UnexpectedTagException;
1652
- const reader = db.core.reader();
1653
- const nextArrayListStart = Number(slotPtr.slot.value);
1654
- db.core.seek(nextArrayListStart);
1655
- const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
1656
- reader.readFully(headerBytes);
1657
- const origHeader = ArrayListHeader.fromBytes(headerBytes);
1658
- const appendResult = db.readArrayListSlotAppend(origHeader, writeMode, isTopLevel);
1659
- const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, appendResult.slotPtr);
1660
- const writer = db.core.writer();
1661
- if (isTopLevel) {
1662
- db.core.flush();
1663
- const fileSize = db.core.length();
1664
- const header = new TopLevelArrayListHeader(fileSize, appendResult.header);
1665
- db.core.seek(nextArrayListStart);
1666
- writer.write(header.toBytes());
1667
- } else {
1668
- db.core.seek(nextArrayListStart);
1669
- writer.write(appendResult.header.toBytes());
1670
- }
1671
- return finalSlotPtr;
1672
- }
1673
- }
1674
-
1675
- class ArrayListSlice {
1676
- size;
1677
- kind = "ArrayListSlice";
1678
- constructor(size) {
1679
- this.size = size;
1680
- }
1681
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1682
- if (writeMode === 0 /* READ_ONLY */)
1683
- throw new WriteNotAllowedException;
1684
- if (slotPtr.slot.tag !== 2 /* ARRAY_LIST */)
1685
- throw new UnexpectedTagException;
1686
- const reader = db.core.reader();
1687
- const nextArrayListStart = Number(slotPtr.slot.value);
1688
- db.core.seek(nextArrayListStart);
1689
- const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
1690
- reader.readFully(headerBytes);
1691
- const origHeader = ArrayListHeader.fromBytes(headerBytes);
1692
- const sliceHeader = db.readArrayListSlice(origHeader, this.size);
1693
- const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, slotPtr);
1694
- const writer = db.core.writer();
1695
- db.core.seek(nextArrayListStart);
1696
- writer.write(sliceHeader.toBytes());
1697
- return finalSlotPtr;
1698
- }
1699
- }
1700
-
1701
- class LinkedArrayListInit {
1702
- kind = "LinkedArrayListInit";
1703
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1704
- if (writeMode === 0 /* READ_ONLY */)
1705
- throw new WriteNotAllowedException;
1706
- if (isTopLevel)
1707
- throw new InvalidTopLevelTypeException;
1708
- if (slotPtr.position === null)
1709
- throw new CursorNotWriteableException;
1710
- const position = slotPtr.position;
1711
- switch (slotPtr.slot.tag) {
1712
- case 0 /* NONE */: {
1713
- const writer = db.core.writer();
1714
- const arrayListStart = db.core.length();
1715
- db.core.seek(arrayListStart);
1716
- const arrayListPtr = arrayListStart + LinkedArrayListHeader.LENGTH;
1717
- writer.write(new LinkedArrayListHeader(0, arrayListPtr, 0).toBytes());
1718
- writer.write(new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE));
1719
- const nextSlotPtr = new SlotPointer(position, new Slot(arrayListStart, 3 /* LINKED_ARRAY_LIST */));
1720
- db.core.seek(position);
1721
- writer.write(nextSlotPtr.slot.toBytes());
1722
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
1723
- }
1724
- case 3 /* LINKED_ARRAY_LIST */: {
1725
- const reader = db.core.reader();
1726
- const writer = db.core.writer();
1727
- let arrayListStart = Number(slotPtr.slot.value);
1728
- if (db.txStart !== null) {
1729
- if (arrayListStart < db.txStart) {
1730
- db.core.seek(arrayListStart);
1731
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
1732
- reader.readFully(headerBytes);
1733
- const header = LinkedArrayListHeader.fromBytes(headerBytes);
1734
- db.core.seek(header.ptr);
1735
- const arrayListIndexBlock = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
1736
- reader.readFully(arrayListIndexBlock);
1737
- arrayListStart = db.core.length();
1738
- db.core.seek(arrayListStart);
1739
- const nextArrayListPtr = arrayListStart + LinkedArrayListHeader.LENGTH;
1740
- const newHeader = header.withPtr(nextArrayListPtr);
1741
- writer.write(newHeader.toBytes());
1742
- writer.write(arrayListIndexBlock);
1743
- }
1744
- } else if (db.header.tag === 2 /* ARRAY_LIST */) {
1745
- throw new ExpectedTxStartException;
1746
- }
1747
- const nextSlotPtr = new SlotPointer(position, new Slot(arrayListStart, 3 /* LINKED_ARRAY_LIST */));
1748
- db.core.seek(position);
1749
- writer.write(nextSlotPtr.slot.toBytes());
1750
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
1751
- }
1752
- default:
1753
- throw new UnexpectedTagException;
1754
- }
1755
- }
1756
- }
1757
-
1758
- class LinkedArrayListGet {
1759
- index;
1760
- kind = "LinkedArrayListGet";
1761
- constructor(index) {
1762
- this.index = index;
1763
- }
1764
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1765
- switch (slotPtr.slot.tag) {
1766
- case 0 /* NONE */:
1767
- throw new KeyNotFoundException;
1768
- case 3 /* LINKED_ARRAY_LIST */:
1769
- break;
1770
- default:
1771
- throw new UnexpectedTagException;
1772
- }
1773
- let index = this.index;
1774
- db.core.seek(Number(slotPtr.slot.value));
1775
- const reader = db.core.reader();
1776
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
1777
- reader.readFully(headerBytes);
1778
- const header = LinkedArrayListHeader.fromBytes(headerBytes);
1779
- if (index >= header.size || index < -header.size) {
1780
- throw new KeyNotFoundException;
1781
- }
1782
- const key = index < 0 ? header.size - Math.abs(index) : index;
1783
- const finalSlotPtr = db.readLinkedArrayListSlot(header.ptr, key, header.shift, writeMode, isTopLevel);
1784
- return db.readSlotPointer(writeMode, path, pathI + 1, finalSlotPtr.slotPtr);
1785
- }
1786
- }
1787
-
1788
- class LinkedArrayListAppend {
1789
- kind = "LinkedArrayListAppend";
1790
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1791
- if (writeMode === 0 /* READ_ONLY */)
1792
- throw new WriteNotAllowedException;
1793
- if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
1794
- throw new UnexpectedTagException;
1795
- const reader = db.core.reader();
1796
- const nextArrayListStart = Number(slotPtr.slot.value);
1797
- db.core.seek(nextArrayListStart);
1798
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
1799
- reader.readFully(headerBytes);
1800
- const origHeader = LinkedArrayListHeader.fromBytes(headerBytes);
1801
- const appendResult = db.readLinkedArrayListSlotAppend(origHeader, writeMode, isTopLevel);
1802
- const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, appendResult.slotPtr.slotPtr);
1803
- const writer = db.core.writer();
1804
- db.core.seek(nextArrayListStart);
1805
- writer.write(appendResult.header.toBytes());
1806
- return finalSlotPtr;
1807
- }
1808
- }
1809
-
1810
- class LinkedArrayListSlice {
1811
- offset;
1812
- size;
1813
- kind = "LinkedArrayListSlice";
1814
- constructor(offset, size) {
1815
- this.offset = offset;
1816
- this.size = size;
1817
- }
1818
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1819
- if (writeMode === 0 /* READ_ONLY */)
1820
- throw new WriteNotAllowedException;
1821
- if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
1822
- throw new UnexpectedTagException;
1823
- const reader = db.core.reader();
1824
- const nextArrayListStart = Number(slotPtr.slot.value);
1825
- db.core.seek(nextArrayListStart);
1826
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
1827
- reader.readFully(headerBytes);
1828
- const origHeader = LinkedArrayListHeader.fromBytes(headerBytes);
1829
- const sliceHeader = db.readLinkedArrayListSlice(origHeader, this.offset, this.size);
1830
- const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, slotPtr);
1831
- const writer = db.core.writer();
1832
- db.core.seek(nextArrayListStart);
1833
- writer.write(sliceHeader.toBytes());
1834
- return finalSlotPtr;
1835
- }
1836
- }
1837
-
1838
- class LinkedArrayListConcat {
1839
- list;
1840
- kind = "LinkedArrayListConcat";
1841
- constructor(list) {
1842
- this.list = list;
1843
- }
1844
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1845
- if (writeMode === 0 /* READ_ONLY */)
1846
- throw new WriteNotAllowedException;
1847
- if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
1848
- throw new UnexpectedTagException;
1849
- if (this.list.tag !== 3 /* LINKED_ARRAY_LIST */)
1850
- throw new UnexpectedTagException;
1851
- const reader = db.core.reader();
1852
- const nextArrayListStart = Number(slotPtr.slot.value);
1853
- db.core.seek(nextArrayListStart);
1854
- const headerBytesA = new Uint8Array(LinkedArrayListHeader.LENGTH);
1855
- reader.readFully(headerBytesA);
1856
- const headerA = LinkedArrayListHeader.fromBytes(headerBytesA);
1857
- db.core.seek(Number(this.list.value));
1858
- const headerBytesB = new Uint8Array(LinkedArrayListHeader.LENGTH);
1859
- reader.readFully(headerBytesB);
1860
- const headerB = LinkedArrayListHeader.fromBytes(headerBytesB);
1861
- const concatHeader = db.readLinkedArrayListConcat(headerA, headerB);
1862
- const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, slotPtr);
1863
- const writer = db.core.writer();
1864
- db.core.seek(nextArrayListStart);
1865
- writer.write(concatHeader.toBytes());
1866
- return finalSlotPtr;
1867
- }
1868
- }
1869
-
1870
- class LinkedArrayListInsert {
1871
- index;
1872
- kind = "LinkedArrayListInsert";
1873
- constructor(index) {
1874
- this.index = index;
1875
- }
1876
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1877
- if (writeMode === 0 /* READ_ONLY */)
1878
- throw new WriteNotAllowedException;
1879
- if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
1880
- throw new UnexpectedTagException;
1881
- const reader = db.core.reader();
1882
- const nextArrayListStart = Number(slotPtr.slot.value);
1883
- db.core.seek(nextArrayListStart);
1884
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
1885
- reader.readFully(headerBytes);
1886
- const origHeader = LinkedArrayListHeader.fromBytes(headerBytes);
1887
- let index = this.index;
1888
- if (index >= origHeader.size || index < -origHeader.size) {
1889
- throw new KeyNotFoundException;
1890
- }
1891
- const key = index < 0 ? origHeader.size - Math.abs(index) : index;
1892
- const headerA = db.readLinkedArrayListSlice(origHeader, 0, key);
1893
- const headerB = db.readLinkedArrayListSlice(origHeader, key, origHeader.size - key);
1894
- const appendResult = db.readLinkedArrayListSlotAppend(headerA, writeMode, isTopLevel);
1895
- const concatHeader = db.readLinkedArrayListConcat(appendResult.header, headerB);
1896
- const nextSlotPtr = db.readLinkedArrayListSlot(concatHeader.ptr, key, concatHeader.shift, 0 /* READ_ONLY */, isTopLevel);
1897
- const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr.slotPtr);
1898
- const writer = db.core.writer();
1899
- db.core.seek(nextArrayListStart);
1900
- writer.write(concatHeader.toBytes());
1901
- return finalSlotPtr;
1902
- }
1903
- }
1904
-
1905
- class LinkedArrayListRemove {
1906
- index;
1907
- kind = "LinkedArrayListRemove";
1908
- constructor(index) {
1909
- this.index = index;
1910
- }
1911
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1912
- if (writeMode === 0 /* READ_ONLY */)
1913
- throw new WriteNotAllowedException;
1914
- if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
1915
- throw new UnexpectedTagException;
1916
- const reader = db.core.reader();
1917
- const nextArrayListStart = Number(slotPtr.slot.value);
1918
- db.core.seek(nextArrayListStart);
1919
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
1920
- reader.readFully(headerBytes);
1921
- const origHeader = LinkedArrayListHeader.fromBytes(headerBytes);
1922
- let index = this.index;
1923
- if (index >= origHeader.size || index < -origHeader.size) {
1924
- throw new KeyNotFoundException;
1925
- }
1926
- const key = index < 0 ? origHeader.size - Math.abs(index) : index;
1927
- const headerA = db.readLinkedArrayListSlice(origHeader, 0, key);
1928
- const headerB = db.readLinkedArrayListSlice(origHeader, key + 1, origHeader.size - (key + 1));
1929
- const concatHeader = db.readLinkedArrayListConcat(headerA, headerB);
1930
- const nextSlotPtr = new SlotPointer(concatHeader.ptr, new Slot(nextArrayListStart, 3 /* LINKED_ARRAY_LIST */));
1931
- const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
1932
- const writer = db.core.writer();
1933
- db.core.seek(nextArrayListStart);
1934
- writer.write(concatHeader.toBytes());
1935
- return finalSlotPtr;
1936
- }
1937
- }
1938
-
1939
- class HashMapInit {
1940
- counted;
1941
- set;
1942
- kind = "HashMapInit";
1943
- constructor(counted = false, set = false) {
1944
- this.counted = counted;
1945
- this.set = set;
1946
- }
1947
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
1948
- if (writeMode === 0 /* READ_ONLY */)
1949
- throw new WriteNotAllowedException;
1950
- const tag = this.counted ? this.set ? 13 /* COUNTED_HASH_SET */ : 12 /* COUNTED_HASH_MAP */ : this.set ? 11 /* HASH_SET */ : 4 /* HASH_MAP */;
1951
- if (isTopLevel) {
1952
- const writer = db.core.writer();
1953
- if (db.header.tag === 0 /* NONE */) {
1954
- db.core.seek(Header.LENGTH);
1955
- if (this.counted) {
1956
- writer.writeLong(0);
1957
- }
1958
- writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
1959
- db.core.seek(0);
1960
- db.header = db.header.withTag(tag);
1961
- writer.write(db.header.toBytes());
1962
- }
1963
- const nextSlotPtr = slotPtr.withSlot(slotPtr.slot.withTag(tag));
1964
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
1965
- }
1966
- if (slotPtr.position === null)
1967
- throw new CursorNotWriteableException;
1968
- const position = slotPtr.position;
1969
- switch (slotPtr.slot.tag) {
1970
- case 0 /* NONE */: {
1971
- const writer = db.core.writer();
1972
- const mapStart = db.core.length();
1973
- db.core.seek(mapStart);
1974
- if (this.counted) {
1975
- writer.writeLong(0);
1976
- }
1977
- writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
1978
- const nextSlotPtr = new SlotPointer(position, new Slot(mapStart, tag));
1979
- db.core.seek(position);
1980
- writer.write(nextSlotPtr.slot.toBytes());
1981
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
1982
- }
1983
- case 4 /* HASH_MAP */:
1984
- case 11 /* HASH_SET */:
1985
- case 12 /* COUNTED_HASH_MAP */:
1986
- case 13 /* COUNTED_HASH_SET */: {
1987
- if (this.counted) {
1988
- switch (slotPtr.slot.tag) {
1989
- case 12 /* COUNTED_HASH_MAP */:
1990
- case 13 /* COUNTED_HASH_SET */:
1991
- break;
1992
- default:
1993
- throw new UnexpectedTagException;
1994
- }
1995
- } else {
1996
- switch (slotPtr.slot.tag) {
1997
- case 4 /* HASH_MAP */:
1998
- case 11 /* HASH_SET */:
1999
- break;
2000
- default:
2001
- throw new UnexpectedTagException;
2002
- }
2003
- }
2004
- const reader = db.core.reader();
2005
- const writer = db.core.writer();
2006
- let mapStart = Number(slotPtr.slot.value);
2007
- if (db.txStart !== null) {
2008
- if (mapStart < db.txStart) {
2009
- db.core.seek(mapStart);
2010
- let mapCountMaybe = null;
2011
- if (this.counted) {
2012
- mapCountMaybe = reader.readLong();
2013
- }
2014
- const mapIndexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
2015
- reader.readFully(mapIndexBlock);
2016
- mapStart = db.core.length();
2017
- db.core.seek(mapStart);
2018
- if (mapCountMaybe !== null) {
2019
- writer.writeLong(mapCountMaybe);
2020
- }
2021
- writer.write(mapIndexBlock);
2022
- }
2023
- } else if (db.header.tag === 2 /* ARRAY_LIST */) {
2024
- throw new ExpectedTxStartException;
2025
- }
2026
- const nextSlotPtr = new SlotPointer(position, new Slot(mapStart, tag));
2027
- db.core.seek(position);
2028
- writer.write(nextSlotPtr.slot.toBytes());
2029
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
2030
- }
2031
- default:
2032
- throw new UnexpectedTagException;
2033
- }
2034
- }
2035
- }
2036
-
2037
- class HashMapGet {
2038
- target;
2039
- kind = "HashMapGet";
2040
- constructor(target) {
2041
- this.target = target;
2042
- }
2043
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
2044
- let counted = false;
2045
- switch (slotPtr.slot.tag) {
2046
- case 0 /* NONE */:
2047
- throw new KeyNotFoundException;
2048
- case 4 /* HASH_MAP */:
2049
- case 11 /* HASH_SET */:
2050
- break;
2051
- case 12 /* COUNTED_HASH_MAP */:
2052
- case 13 /* COUNTED_HASH_SET */:
2053
- counted = true;
2054
- break;
2055
- default:
2056
- throw new UnexpectedTagException;
2057
- }
2058
- const indexPos = counted ? Number(slotPtr.slot.value) + 8 : Number(slotPtr.slot.value);
2059
- const hash = db.checkHash(this.target);
2060
- const res = db.readMapSlot(indexPos, hash, 0, writeMode, isTopLevel, this.target);
2061
- if (writeMode === 1 /* READ_WRITE */ && counted && res.isEmpty) {
2062
- const reader = db.core.reader();
2063
- const writer = db.core.writer();
2064
- db.core.seek(Number(slotPtr.slot.value));
2065
- const mapCount = reader.readLong();
2066
- db.core.seek(Number(slotPtr.slot.value));
2067
- writer.writeLong(mapCount + 1);
2068
- }
2069
- return db.readSlotPointer(writeMode, path, pathI + 1, res.slotPtr);
2070
- }
2071
- }
2072
-
2073
- class HashMapRemove {
2074
- hash;
2075
- kind = "HashMapRemove";
2076
- constructor(hash) {
2077
- this.hash = hash;
2078
- }
2079
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
2080
- if (writeMode === 0 /* READ_ONLY */)
2081
- throw new WriteNotAllowedException;
2082
- let counted = false;
2083
- switch (slotPtr.slot.tag) {
2084
- case 0 /* NONE */:
2085
- throw new KeyNotFoundException;
2086
- case 4 /* HASH_MAP */:
2087
- case 11 /* HASH_SET */:
2088
- break;
2089
- case 12 /* COUNTED_HASH_MAP */:
2090
- case 13 /* COUNTED_HASH_SET */:
2091
- counted = true;
2092
- break;
2093
- default:
2094
- throw new UnexpectedTagException;
2095
- }
2096
- const indexPos = counted ? Number(slotPtr.slot.value) + 8 : Number(slotPtr.slot.value);
2097
- const hash = db.checkHashBytes(this.hash);
2098
- let keyFound = true;
2099
- try {
2100
- db.removeMapSlot(indexPos, hash, 0, isTopLevel);
2101
- } catch (e) {
2102
- if (e instanceof KeyNotFoundException) {
2103
- keyFound = false;
2104
- } else {
2105
- throw e;
2106
- }
2107
- }
2108
- if (writeMode === 1 /* READ_WRITE */ && counted && keyFound) {
2109
- const reader = db.core.reader();
2110
- const writer = db.core.writer();
2111
- db.core.seek(Number(slotPtr.slot.value));
2112
- const mapCount = reader.readLong();
2113
- db.core.seek(Number(slotPtr.slot.value));
2114
- writer.writeLong(mapCount - 1);
2115
- }
2116
- if (!keyFound)
2117
- throw new KeyNotFoundException;
2118
- return slotPtr;
2119
- }
2120
- }
2121
-
2122
- class WriteData {
2123
- data;
2124
- kind = "WriteData";
2125
- constructor(data) {
2126
- this.data = data;
2127
- }
2128
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
2129
- if (writeMode === 0 /* READ_ONLY */)
2130
- throw new WriteNotAllowedException;
2131
- if (slotPtr.position === null)
2132
- throw new CursorNotWriteableException;
2133
- const position = slotPtr.position;
2134
- const writer = db.core.writer();
2135
- const data = this.data;
2136
- let slot;
2137
- if (data === null) {
2138
- slot = new Slot;
2139
- } else if (data instanceof Slot) {
2140
- slot = data;
2141
- } else if (data instanceof Uint) {
2142
- slot = new Slot(data.value, 8 /* UINT */);
2143
- } else if (data instanceof Int) {
2144
- slot = new Slot(data.value, 9 /* INT */);
2145
- } else if (data instanceof Float) {
2146
- const buffer = new ArrayBuffer(8);
2147
- const view = new DataView(buffer);
2148
- view.setFloat64(0, data.value, false);
2149
- const longValue = view.getBigInt64(0, false);
2150
- slot = new Slot(longValue, 10 /* FLOAT */);
2151
- } else if (data instanceof Bytes) {
2152
- if (data.isShort()) {
2153
- const buffer = new Uint8Array(8);
2154
- buffer.set(data.value, 0);
2155
- if (data.formatTag !== null) {
2156
- buffer.set(data.formatTag, 6);
2157
- }
2158
- const view = new DataView(buffer.buffer);
2159
- const longValue = view.getBigInt64(0, false);
2160
- slot = new Slot(longValue, 7 /* SHORT_BYTES */, data.formatTag !== null);
2161
- } else {
2162
- const nextCursor = new WriteCursor(slotPtr, db);
2163
- const cursorWriter = nextCursor.writer();
2164
- cursorWriter.formatTag = data.formatTag;
2165
- cursorWriter.write(data.value);
2166
- cursorWriter.finish();
2167
- slot = cursorWriter.slot;
2168
- }
2169
- } else {
2170
- throw new Error("Unknown data type");
2171
- }
2172
- if (slot.tag === 0 /* NONE */) {
2173
- slot = slot.withFull(true);
2174
- }
2175
- db.core.seek(position);
2176
- writer.write(slot.toBytes());
2177
- const nextSlotPtr = new SlotPointer(slotPtr.position, slot);
2178
- return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
2179
- }
2180
- }
2181
-
2182
- class Context {
2183
- fn;
2184
- kind = "Context";
2185
- constructor(fn) {
2186
- this.fn = fn;
2187
- }
2188
- readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
2189
- if (writeMode === 0 /* READ_ONLY */)
2190
- throw new WriteNotAllowedException;
2191
- if (pathI !== path.length - 1)
2192
- throw new PathPartMustBeAtEndException;
2193
- const nextCursor = new WriteCursor(slotPtr, db);
2194
- try {
2195
- this.fn(nextCursor);
2196
- } catch (e) {
2197
- try {
2198
- db.truncate();
2199
- } catch (_) {}
2200
- throw e;
2201
- }
2202
- return nextCursor.slotPtr;
2203
- }
2204
- }
2205
-
2206
- class HashMapGetResult {
2207
- slotPtr;
2208
- isEmpty;
2209
- constructor(slotPtr, isEmpty) {
2210
- this.slotPtr = slotPtr;
2211
- this.isEmpty = isEmpty;
2212
- }
2213
- }
2214
-
2215
- class ArrayListAppendResult {
2216
- header;
2217
- slotPtr;
2218
- constructor(header, slotPtr) {
2219
- this.header = header;
2220
- this.slotPtr = slotPtr;
2221
- }
2222
- }
2223
-
2224
- class LinkedArrayListAppendResult {
2225
- header;
2226
- slotPtr;
2227
- constructor(header, slotPtr) {
2228
- this.header = header;
2229
- this.slotPtr = slotPtr;
2230
- }
2231
- }
2232
- function arraysEqual(a, b) {
2233
- if (a.length !== b.length)
2234
- return false;
2235
- for (let i = 0;i < a.length; i++) {
2236
- if (a[i] !== b[i])
2237
- return false;
2238
- }
2239
- return true;
2240
- }
2241
- function checkLong(n) {
2242
- if (n < 0) {
2243
- throw new ExpectedUnsignedLongException;
2244
- }
2245
- return n;
2246
- }
2247
- function bigIntShiftRight(value, bits) {
2248
- let result = 0n;
2249
- for (let i = 0;i < value.length; i++) {
2250
- result = result << 8n | BigInt(value[i]);
2251
- }
2252
- return result >> BigInt(bits);
2253
- }
2254
-
2255
- class Database3 {
2256
- core;
2257
- hasher;
2258
- header;
2259
- txStart = null;
2260
- constructor(core, hasher) {
2261
- this.core = core;
2262
- this.hasher = hasher;
2263
- core.seek(0);
2264
- if (core.length() === 0) {
2265
- this.header = new Header(hasher.id, hasher.digestLength, VERSION, 0 /* NONE */, MAGIC_NUMBER);
2266
- this.header.write(core);
2267
- core.flush();
2268
- } else {
2269
- this.header = Header.read(core);
2270
- this.header.validate();
2271
- if (this.header.hashSize !== hasher.digestLength) {
2272
- throw new InvalidHashSizeException;
2273
- }
2274
- this.truncate();
2275
- }
2276
- }
2277
- rootCursor() {
2278
- if (this.header.tag === 0 /* NONE */) {
2279
- this.core.seek(0);
2280
- this.header = Header.read(this.core);
2281
- }
2282
- return new WriteCursor(new SlotPointer(null, new Slot(Header.LENGTH, this.header.tag)), this);
2283
- }
2284
- freeze() {
2285
- if (this.txStart !== null) {
2286
- this.txStart = this.core.length();
2287
- } else {
2288
- throw new ExpectedTxStartException;
2289
- }
2290
- }
2291
- compact(targetCore) {
2292
- const offsetMap = new Map;
2293
- const hasher = new Hasher(this.hasher.algorithm, this.header.hashId);
2294
- const target = new Database3(targetCore, hasher);
2295
- if (this.header.tag === 0 /* NONE */)
2296
- return target;
2297
- if (this.header.tag !== 2 /* ARRAY_LIST */)
2298
- throw new UnexpectedTagException;
2299
- this.core.seek(Header.LENGTH);
2300
- const sourceReader = this.core.reader();
2301
- const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
2302
- sourceReader.readFully(headerBytes);
2303
- const sourceHeader = ArrayListHeader.fromBytes(headerBytes);
2304
- if (sourceHeader.size === 0)
2305
- return target;
2306
- const lastKey = sourceHeader.size - 1;
2307
- const shift = lastKey < SLOT_COUNT ? 0 : Math.floor(Math.log(lastKey) / Math.log(SLOT_COUNT));
2308
- const lastSlotPtr = this.readArrayListSlot(sourceHeader.ptr, lastKey, shift, 0 /* READ_ONLY */, true);
2309
- const momentSlot = lastSlotPtr.slot;
2310
- const targetWriter = targetCore.writer();
2311
- targetCore.seek(Header.LENGTH);
2312
- const targetArrayListPtr = Header.LENGTH + TopLevelArrayListHeader.LENGTH;
2313
- targetWriter.write(new TopLevelArrayListHeader(0, new ArrayListHeader(targetArrayListPtr, 1)).toBytes());
2314
- targetWriter.write(new Uint8Array(INDEX_BLOCK_SIZE));
2315
- const remappedMoment = remapSlot(this.core, targetCore, this.header.hashSize, offsetMap, momentSlot);
2316
- targetCore.seek(targetArrayListPtr);
2317
- targetWriter.write(remappedMoment.toBytes());
2318
- target.header = target.header.withTag(2 /* ARRAY_LIST */);
2319
- targetCore.seek(0);
2320
- target.header.write(targetCore);
2321
- targetCore.flush();
2322
- const fileSize = targetCore.length();
2323
- targetCore.seek(Header.LENGTH + ArrayListHeader.LENGTH);
2324
- targetWriter.writeLong(fileSize);
2325
- targetCore.flush();
2326
- return target;
2327
- }
2328
- truncate() {
2329
- if (this.header.tag !== 2 /* ARRAY_LIST */)
2330
- return;
2331
- const rootCursor = this.rootCursor();
2332
- const listSize = rootCursor.count();
2333
- if (listSize === 0)
2334
- return;
2335
- this.core.seek(Header.LENGTH + ArrayListHeader.LENGTH);
2336
- const reader = this.core.reader();
2337
- const headerFileSize = reader.readLong();
2338
- if (headerFileSize === 0)
2339
- return;
2340
- const fileSize = this.core.length();
2341
- if (fileSize === headerFileSize)
2342
- return;
2343
- try {
2344
- this.core.setLength(headerFileSize);
2345
- } catch (_) {}
2346
- }
2347
- checkHashBytes(hash) {
2348
- if (hash.length !== this.header.hashSize) {
2349
- throw new InvalidHashSizeException;
2350
- }
2351
- return hash;
2352
- }
2353
- checkHash(target) {
2354
- return this.checkHashBytes(target.hash);
2355
- }
2356
- readSlotPointer(writeMode, path, pathI, slotPtr) {
2357
- if (pathI === path.length) {
2358
- if (writeMode === 0 /* READ_ONLY */ && slotPtr.slot.tag === 0 /* NONE */) {
2359
- throw new KeyNotFoundException;
2360
- }
2361
- return slotPtr;
2362
- }
2363
- const part = path[pathI];
2364
- const isTopLevel = slotPtr.slot.value === BigInt(Header.LENGTH);
2365
- const isTxStart = isTopLevel && this.header.tag === 2 /* ARRAY_LIST */ && this.txStart === null;
2366
- if (isTxStart) {
2367
- this.txStart = this.core.length();
2368
- }
2369
- try {
2370
- return part.readSlotPointer(this, isTopLevel, writeMode, path, pathI, slotPtr);
2371
- } finally {
2372
- if (isTxStart) {
2373
- this.txStart = null;
2374
- }
2375
- }
2376
- }
2377
- readMapSlot(indexPos, keyHash, keyOffset, writeMode, isTopLevel, target) {
2378
- if (keyOffset > this.header.hashSize * 8 / BIT_COUNT) {
2379
- throw new KeyOffsetExceededException;
2380
- }
2381
- const reader = this.core.reader();
2382
- const writer = this.core.writer();
2383
- const i = Number(bigIntShiftRight(keyHash, keyOffset * BIT_COUNT) & MASK);
2384
- const slotPos = indexPos + Slot.LENGTH * i;
2385
- this.core.seek(slotPos);
2386
- const slotBytes = new Uint8Array(Slot.LENGTH);
2387
- reader.readFully(slotBytes);
2388
- const slot = Slot.fromBytes(slotBytes);
2389
- const ptr = Number(slot.value);
2390
- switch (slot.tag) {
2391
- case 0 /* NONE */: {
2392
- switch (writeMode) {
2393
- case 0 /* READ_ONLY */:
2394
- throw new KeyNotFoundException;
2395
- case 1 /* READ_WRITE */: {
2396
- const hashPos = this.core.length();
2397
- this.core.seek(hashPos);
2398
- const keySlotPos = hashPos + this.header.hashSize;
2399
- const valueSlotPos = keySlotPos + Slot.LENGTH;
2400
- const kvPair = new KeyValuePair(new Slot, new Slot, keyHash);
2401
- writer.write(kvPair.toBytes());
2402
- const nextSlot = new Slot(hashPos, 5 /* KV_PAIR */);
2403
- this.core.seek(slotPos);
2404
- writer.write(nextSlot.toBytes());
2405
- let nextSlotPtr;
2406
- if (target.kind === "kv_pair") {
2407
- nextSlotPtr = new SlotPointer(slotPos, nextSlot);
2408
- } else if (target.kind === "key") {
2409
- nextSlotPtr = new SlotPointer(keySlotPos, kvPair.keySlot);
2410
- } else {
2411
- nextSlotPtr = new SlotPointer(valueSlotPos, kvPair.valueSlot);
2412
- }
2413
- return new HashMapGetResult(nextSlotPtr, true);
2414
- }
2415
- default:
2416
- throw new UnreachableException;
2417
- }
2418
- }
2419
- case 1 /* INDEX */: {
2420
- let nextPtr = ptr;
2421
- if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
2422
- if (this.txStart !== null) {
2423
- if (nextPtr < this.txStart) {
2424
- this.core.seek(ptr);
2425
- const indexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
2426
- reader.readFully(indexBlock);
2427
- nextPtr = this.core.length();
2428
- this.core.seek(nextPtr);
2429
- writer.write(indexBlock);
2430
- this.core.seek(slotPos);
2431
- writer.write(new Slot(nextPtr, 1 /* INDEX */).toBytes());
2432
- }
2433
- } else if (this.header.tag === 2 /* ARRAY_LIST */) {
2434
- throw new ExpectedTxStartException;
2435
- }
2436
- }
2437
- return this.readMapSlot(nextPtr, keyHash, keyOffset + 1, writeMode, isTopLevel, target);
2438
- }
2439
- case 5 /* KV_PAIR */: {
2440
- this.core.seek(ptr);
2441
- const kvPairBytes = new Uint8Array(KeyValuePair.length(this.header.hashSize));
2442
- reader.readFully(kvPairBytes);
2443
- const kvPair = KeyValuePair.fromBytes(kvPairBytes, this.header.hashSize);
2444
- if (arraysEqual(kvPair.hash, keyHash)) {
2445
- if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
2446
- if (this.txStart !== null) {
2447
- if (ptr < this.txStart) {
2448
- const hashPos = this.core.length();
2449
- this.core.seek(hashPos);
2450
- const keySlotPos2 = hashPos + this.header.hashSize;
2451
- const valueSlotPos2 = keySlotPos2 + Slot.LENGTH;
2452
- writer.write(kvPair.toBytes());
2453
- const nextSlot = new Slot(hashPos, 5 /* KV_PAIR */);
2454
- this.core.seek(slotPos);
2455
- writer.write(nextSlot.toBytes());
2456
- let nextSlotPtr2;
2457
- if (target.kind === "kv_pair") {
2458
- nextSlotPtr2 = new SlotPointer(slotPos, nextSlot);
2459
- } else if (target.kind === "key") {
2460
- nextSlotPtr2 = new SlotPointer(keySlotPos2, kvPair.keySlot);
2461
- } else {
2462
- nextSlotPtr2 = new SlotPointer(valueSlotPos2, kvPair.valueSlot);
2463
- }
2464
- return new HashMapGetResult(nextSlotPtr2, false);
2465
- }
2466
- } else if (this.header.tag === 2 /* ARRAY_LIST */) {
2467
- throw new ExpectedTxStartException;
2468
- }
2469
- }
2470
- const keySlotPos = ptr + this.header.hashSize;
2471
- const valueSlotPos = keySlotPos + Slot.LENGTH;
2472
- let nextSlotPtr;
2473
- if (target.kind === "kv_pair") {
2474
- nextSlotPtr = new SlotPointer(slotPos, slot);
2475
- } else if (target.kind === "key") {
2476
- nextSlotPtr = new SlotPointer(keySlotPos, kvPair.keySlot);
2477
- } else {
2478
- nextSlotPtr = new SlotPointer(valueSlotPos, kvPair.valueSlot);
2479
- }
2480
- return new HashMapGetResult(nextSlotPtr, false);
2481
- } else {
2482
- switch (writeMode) {
2483
- case 0 /* READ_ONLY */:
2484
- throw new KeyNotFoundException;
2485
- case 1 /* READ_WRITE */: {
2486
- if (keyOffset + 1 >= this.header.hashSize * 8 / BIT_COUNT) {
2487
- throw new KeyOffsetExceededException;
2488
- }
2489
- const nextI = Number(bigIntShiftRight(kvPair.hash, (keyOffset + 1) * BIT_COUNT) & MASK);
2490
- const nextIndexPos = this.core.length();
2491
- this.core.seek(nextIndexPos);
2492
- writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
2493
- this.core.seek(nextIndexPos + Slot.LENGTH * nextI);
2494
- writer.write(slot.toBytes());
2495
- const res = this.readMapSlot(nextIndexPos, keyHash, keyOffset + 1, writeMode, isTopLevel, target);
2496
- this.core.seek(slotPos);
2497
- writer.write(new Slot(nextIndexPos, 1 /* INDEX */).toBytes());
2498
- return res;
2499
- }
2500
- default:
2501
- throw new UnreachableException;
2502
- }
2503
- }
2504
- }
2505
- default:
2506
- throw new UnexpectedTagException;
2507
- }
2508
- }
2509
- removeMapSlot(indexPos, keyHash, keyOffset, isTopLevel) {
2510
- if (keyOffset > this.header.hashSize * 8 / BIT_COUNT) {
2511
- throw new KeyOffsetExceededException;
2512
- }
2513
- const reader = this.core.reader();
2514
- const writer = this.core.writer();
2515
- const slotBlock = new Array(SLOT_COUNT);
2516
- this.core.seek(indexPos);
2517
- const indexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
2518
- reader.readFully(indexBlock);
2519
- for (let i2 = 0;i2 < SLOT_COUNT; i2++) {
2520
- const slotBytes = indexBlock.slice(i2 * Slot.LENGTH, (i2 + 1) * Slot.LENGTH);
2521
- slotBlock[i2] = Slot.fromBytes(slotBytes);
2522
- }
2523
- const i = Number(bigIntShiftRight(keyHash, keyOffset * BIT_COUNT) & MASK);
2524
- const slotPos = indexPos + Slot.LENGTH * i;
2525
- const slot = slotBlock[i];
2526
- let nextSlot;
2527
- switch (slot.tag) {
2528
- case 0 /* NONE */:
2529
- throw new KeyNotFoundException;
2530
- case 1 /* INDEX */:
2531
- nextSlot = this.removeMapSlot(Number(slot.value), keyHash, keyOffset + 1, isTopLevel);
2532
- break;
2533
- case 5 /* KV_PAIR */: {
2534
- this.core.seek(Number(slot.value));
2535
- const kvPairBytes = new Uint8Array(KeyValuePair.length(this.header.hashSize));
2536
- reader.readFully(kvPairBytes);
2537
- const kvPair = KeyValuePair.fromBytes(kvPairBytes, this.header.hashSize);
2538
- if (arraysEqual(kvPair.hash, keyHash)) {
2539
- nextSlot = new Slot;
2540
- } else {
2541
- throw new KeyNotFoundException;
2542
- }
2543
- break;
2544
- }
2545
- default:
2546
- throw new UnexpectedTagException;
2547
- }
2548
- if (keyOffset === 0) {
2549
- this.core.seek(slotPos);
2550
- writer.write(nextSlot.toBytes());
2551
- return new Slot(indexPos, 1 /* INDEX */);
2552
- }
2553
- let slotToReturnMaybe = new Slot;
2554
- slotBlock[i] = nextSlot;
2555
- for (const blockSlot of slotBlock) {
2556
- if (blockSlot.tag === 0 /* NONE */)
2557
- continue;
2558
- if (slotToReturnMaybe !== null) {
2559
- if (slotToReturnMaybe.tag !== 0 /* NONE */) {
2560
- slotToReturnMaybe = null;
2561
- break;
2562
- }
2563
- }
2564
- slotToReturnMaybe = blockSlot;
2565
- }
2566
- if (slotToReturnMaybe !== null) {
2567
- switch (slotToReturnMaybe.tag) {
2568
- case 0 /* NONE */:
2569
- case 5 /* KV_PAIR */:
2570
- return slotToReturnMaybe;
2571
- default:
2572
- break;
2573
- }
2574
- }
2575
- if (!isTopLevel) {
2576
- if (this.txStart !== null) {
2577
- if (indexPos < this.txStart) {
2578
- const nextIndexPos = this.core.length();
2579
- this.core.seek(nextIndexPos);
2580
- writer.write(indexBlock);
2581
- const nextSlotPos = nextIndexPos + Slot.LENGTH * i;
2582
- this.core.seek(nextSlotPos);
2583
- writer.write(nextSlot.toBytes());
2584
- return new Slot(nextIndexPos, 1 /* INDEX */);
2585
- }
2586
- } else if (this.header.tag === 2 /* ARRAY_LIST */) {
2587
- throw new ExpectedTxStartException;
2588
- }
2589
- }
2590
- this.core.seek(slotPos);
2591
- writer.write(nextSlot.toBytes());
2592
- return new Slot(indexPos, 1 /* INDEX */);
2593
- }
2594
- readArrayListSlotAppend(header, writeMode, isTopLevel) {
2595
- const writer = this.core.writer();
2596
- let indexPos = header.ptr;
2597
- const key = header.size;
2598
- const prevShift = key < SLOT_COUNT ? 0 : Math.floor(Math.log(key - 1) / Math.log(SLOT_COUNT));
2599
- const nextShift = key < SLOT_COUNT ? 0 : Math.floor(Math.log(key) / Math.log(SLOT_COUNT));
2600
- if (prevShift !== nextShift) {
2601
- const nextIndexPos = this.core.length();
2602
- this.core.seek(nextIndexPos);
2603
- writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
2604
- this.core.seek(nextIndexPos);
2605
- writer.write(new Slot(indexPos, 1 /* INDEX */).toBytes());
2606
- indexPos = nextIndexPos;
2607
- }
2608
- const slotPtr = this.readArrayListSlot(indexPos, key, nextShift, writeMode, isTopLevel);
2609
- return new ArrayListAppendResult(new ArrayListHeader(indexPos, header.size + 1), slotPtr);
2610
- }
2611
- readArrayListSlot(indexPos, key, shift, writeMode, isTopLevel) {
2612
- if (shift >= MAX_BRANCH_LENGTH)
2613
- throw new MaxShiftExceededException;
2614
- const reader = this.core.reader();
2615
- const i = key >>> shift * BIT_COUNT & SLOT_COUNT - 1;
2616
- const slotPos = indexPos + Slot.LENGTH * i;
2617
- this.core.seek(slotPos);
2618
- const slotBytes = new Uint8Array(Slot.LENGTH);
2619
- reader.readFully(slotBytes);
2620
- const slot = Slot.fromBytes(slotBytes);
2621
- if (shift === 0) {
2622
- return new SlotPointer(slotPos, slot);
2623
- }
2624
- const ptr = Number(slot.value);
2625
- switch (slot.tag) {
2626
- case 0 /* NONE */: {
2627
- switch (writeMode) {
2628
- case 0 /* READ_ONLY */:
2629
- throw new KeyNotFoundException;
2630
- case 1 /* READ_WRITE */: {
2631
- const writer = this.core.writer();
2632
- const nextIndexPos = this.core.length();
2633
- this.core.seek(nextIndexPos);
2634
- writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
2635
- if (isTopLevel) {
2636
- const fileSize = this.core.length();
2637
- this.core.seek(Header.LENGTH + ArrayListHeader.LENGTH);
2638
- writer.writeLong(fileSize);
2639
- }
2640
- this.core.seek(slotPos);
2641
- writer.write(new Slot(nextIndexPos, 1 /* INDEX */).toBytes());
2642
- return this.readArrayListSlot(nextIndexPos, key, shift - 1, writeMode, isTopLevel);
2643
- }
2644
- default:
2645
- throw new UnreachableException;
2646
- }
2647
- }
2648
- case 1 /* INDEX */: {
2649
- let nextPtr = ptr;
2650
- if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
2651
- if (this.txStart !== null) {
2652
- if (nextPtr < this.txStart) {
2653
- this.core.seek(ptr);
2654
- const indexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
2655
- reader.readFully(indexBlock);
2656
- const writer = this.core.writer();
2657
- nextPtr = this.core.length();
2658
- this.core.seek(nextPtr);
2659
- writer.write(indexBlock);
2660
- this.core.seek(slotPos);
2661
- writer.write(new Slot(nextPtr, 1 /* INDEX */).toBytes());
2662
- }
2663
- } else if (this.header.tag === 2 /* ARRAY_LIST */) {
2664
- throw new ExpectedTxStartException;
2665
- }
2666
- }
2667
- return this.readArrayListSlot(nextPtr, key, shift - 1, writeMode, isTopLevel);
2668
- }
2669
- default:
2670
- throw new UnexpectedTagException;
2671
- }
2672
- }
2673
- readArrayListSlice(header, size) {
2674
- const reader = this.core.reader();
2675
- if (size > header.size || size < 0) {
2676
- throw new KeyNotFoundException;
2677
- }
2678
- const prevShift = header.size < SLOT_COUNT + 1 ? 0 : Math.floor(Math.log(header.size - 1) / Math.log(SLOT_COUNT));
2679
- const nextShift = size < SLOT_COUNT + 1 ? 0 : Math.floor(Math.log(size - 1) / Math.log(SLOT_COUNT));
2680
- if (prevShift === nextShift) {
2681
- return new ArrayListHeader(header.ptr, size);
2682
- } else {
2683
- let shift = prevShift;
2684
- let indexPos = header.ptr;
2685
- while (shift > nextShift) {
2686
- this.core.seek(indexPos);
2687
- const slotBytes = new Uint8Array(Slot.LENGTH);
2688
- reader.readFully(slotBytes);
2689
- const slot = Slot.fromBytes(slotBytes);
2690
- shift -= 1;
2691
- indexPos = Number(slot.value);
2692
- }
2693
- return new ArrayListHeader(indexPos, size);
2694
- }
2695
- }
2696
- readLinkedArrayListSlotAppend(header, writeMode, isTopLevel) {
2697
- const writer = this.core.writer();
2698
- let ptr = header.ptr;
2699
- const key = header.size;
2700
- let shift = header.shift;
2701
- let slotPtr;
2702
- try {
2703
- slotPtr = this.readLinkedArrayListSlot(ptr, key, shift, writeMode, isTopLevel);
2704
- } catch (e) {
2705
- if (e instanceof NoAvailableSlotsException) {
2706
- const nextPtr = this.core.length();
2707
- this.core.seek(nextPtr);
2708
- writer.write(new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE));
2709
- this.core.seek(nextPtr);
2710
- writer.write(new LinkedArrayListSlot2(header.size, new Slot(ptr, 1 /* INDEX */, true)).toBytes());
2711
- ptr = nextPtr;
2712
- shift += 1;
2713
- slotPtr = this.readLinkedArrayListSlot(ptr, key, shift, writeMode, isTopLevel);
2714
- } else {
2715
- throw e;
2716
- }
2717
- }
2718
- const newSlot = new Slot(0, 0 /* NONE */, true);
2719
- slotPtr = slotPtr.withSlotPointer(slotPtr.slotPtr.withSlot(newSlot));
2720
- if (slotPtr.slotPtr.position === null)
2721
- throw new CursorNotWriteableException;
2722
- const position = slotPtr.slotPtr.position;
2723
- this.core.seek(position);
2724
- writer.write(new LinkedArrayListSlot2(0, newSlot).toBytes());
2725
- if (header.size < SLOT_COUNT && shift > 0) {
2726
- throw new MustSetNewSlotsToFullException;
2727
- }
2728
- return new LinkedArrayListAppendResult(new LinkedArrayListHeader(shift, ptr, header.size + 1), slotPtr);
2729
- }
2730
- static blockLeafCount(block, shift, i) {
2731
- let n = 0;
2732
- if (shift === 0) {
2733
- for (let blockI = 0;blockI < block.length; blockI++) {
2734
- const blockSlot = block[blockI];
2735
- if (!blockSlot.slot.empty() || blockI === i) {
2736
- n += 1;
2737
- }
2738
- }
2739
- } else {
2740
- for (const blockSlot of block) {
2741
- n += blockSlot.size;
2742
- }
2743
- }
2744
- return n;
2745
- }
2746
- static slotLeafCount(slot, shift) {
2747
- if (shift === 0) {
2748
- if (slot.slot.empty()) {
2749
- return 0;
2750
- } else {
2751
- return 1;
2752
- }
2753
- } else {
2754
- return slot.size;
2755
- }
2756
- }
2757
- static keyAndIndexForLinkedArrayList(slotBlock, key, shift) {
2758
- let nextKey = key;
2759
- let i = 0;
2760
- const maxLeafCount = shift === 0 ? 1 : Math.pow(SLOT_COUNT, shift);
2761
- while (true) {
2762
- const slotLeafCount = Database3.slotLeafCount(slotBlock[i], shift);
2763
- if (nextKey === slotLeafCount) {
2764
- if (slotLeafCount === maxLeafCount || slotBlock[i].slot.full) {
2765
- if (i < SLOT_COUNT - 1) {
2766
- nextKey -= slotLeafCount;
2767
- i += 1;
2768
- } else {
2769
- return null;
2770
- }
2771
- }
2772
- break;
2773
- } else if (nextKey < slotLeafCount) {
2774
- break;
2775
- } else if (i < SLOT_COUNT - 1) {
2776
- nextKey -= slotLeafCount;
2777
- i += 1;
2778
- } else {
2779
- return null;
2780
- }
2781
- }
2782
- return { key: nextKey, index: i };
2783
- }
2784
- readLinkedArrayListSlot(indexPos, key, shift, writeMode, isTopLevel) {
2785
- if (shift >= MAX_BRANCH_LENGTH)
2786
- throw new MaxShiftExceededException;
2787
- const reader = this.core.reader();
2788
- const writer = this.core.writer();
2789
- const slotBlock = new Array(SLOT_COUNT);
2790
- this.core.seek(indexPos);
2791
- const indexBlock = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
2792
- reader.readFully(indexBlock);
2793
- for (let i2 = 0;i2 < SLOT_COUNT; i2++) {
2794
- const slotBytes = indexBlock.slice(i2 * LinkedArrayListSlot2.LENGTH, (i2 + 1) * LinkedArrayListSlot2.LENGTH);
2795
- slotBlock[i2] = LinkedArrayListSlot2.fromBytes(slotBytes);
2796
- }
2797
- const keyAndIndex = Database3.keyAndIndexForLinkedArrayList(slotBlock, key, shift);
2798
- if (keyAndIndex === null)
2799
- throw new NoAvailableSlotsException;
2800
- const nextKey = keyAndIndex.key;
2801
- const i = keyAndIndex.index;
2802
- const slot = slotBlock[i];
2803
- const slotPos = indexPos + LinkedArrayListSlot2.LENGTH * i;
2804
- if (shift === 0) {
2805
- const leafCount = Database3.blockLeafCount(slotBlock, shift, i);
2806
- return new LinkedArrayListSlotPointer(new SlotPointer(slotPos, slot.slot), leafCount);
2807
- }
2808
- const ptr = Number(slot.slot.value);
2809
- switch (slot.slot.tag) {
2810
- case 0 /* NONE */: {
2811
- switch (writeMode) {
2812
- case 0 /* READ_ONLY */:
2813
- throw new KeyNotFoundException;
2814
- case 1 /* READ_WRITE */: {
2815
- const nextIndexPos = this.core.length();
2816
- this.core.seek(nextIndexPos);
2817
- writer.write(new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE));
2818
- const nextSlotPtr = this.readLinkedArrayListSlot(nextIndexPos, nextKey, shift - 1, writeMode, isTopLevel);
2819
- slotBlock[i] = slotBlock[i].withSize(nextSlotPtr.leafCount);
2820
- const leafCount = Database3.blockLeafCount(slotBlock, shift, i);
2821
- this.core.seek(slotPos);
2822
- writer.write(new LinkedArrayListSlot2(nextSlotPtr.leafCount, new Slot(nextIndexPos, 1 /* INDEX */)).toBytes());
2823
- return new LinkedArrayListSlotPointer(nextSlotPtr.slotPtr, leafCount);
2824
- }
2825
- default:
2826
- throw new UnreachableException;
2827
- }
2828
- }
2829
- case 1 /* INDEX */: {
2830
- let nextPtr = ptr;
2831
- if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
2832
- if (this.txStart !== null) {
2833
- if (nextPtr < this.txStart) {
2834
- this.core.seek(ptr);
2835
- const indexBlockCopy = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
2836
- reader.readFully(indexBlockCopy);
2837
- nextPtr = this.core.length();
2838
- this.core.seek(nextPtr);
2839
- writer.write(indexBlockCopy);
2840
- }
2841
- } else if (this.header.tag === 2 /* ARRAY_LIST */) {
2842
- throw new ExpectedTxStartException;
2843
- }
2844
- }
2845
- const nextSlotPtr = this.readLinkedArrayListSlot(nextPtr, nextKey, shift - 1, writeMode, isTopLevel);
2846
- slotBlock[i] = slotBlock[i].withSize(nextSlotPtr.leafCount);
2847
- const leafCount = Database3.blockLeafCount(slotBlock, shift, i);
2848
- if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
2849
- this.core.seek(slotPos);
2850
- writer.write(new LinkedArrayListSlot2(nextSlotPtr.leafCount, new Slot(nextPtr, 1 /* INDEX */)).toBytes());
2851
- }
2852
- return new LinkedArrayListSlotPointer(nextSlotPtr.slotPtr, leafCount);
2853
- }
2854
- default:
2855
- throw new UnexpectedTagException;
2856
- }
2857
- }
2858
- readLinkedArrayListBlocks(indexPos, key, shift, blocks) {
2859
- const reader = this.core.reader();
2860
- const slotBlock = new Array(SLOT_COUNT);
2861
- this.core.seek(indexPos);
2862
- const indexBlock = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
2863
- reader.readFully(indexBlock);
2864
- for (let i2 = 0;i2 < SLOT_COUNT; i2++) {
2865
- const slotBytes = indexBlock.slice(i2 * LinkedArrayListSlot2.LENGTH, (i2 + 1) * LinkedArrayListSlot2.LENGTH);
2866
- slotBlock[i2] = LinkedArrayListSlot2.fromBytes(slotBytes);
2867
- }
2868
- const keyAndIndex = Database3.keyAndIndexForLinkedArrayList(slotBlock, key, shift);
2869
- if (keyAndIndex === null)
2870
- throw new NoAvailableSlotsException;
2871
- const nextKey = keyAndIndex.key;
2872
- const i = keyAndIndex.index;
2873
- const leafCount = Database3.blockLeafCount(slotBlock, shift, i);
2874
- blocks.push(new LinkedArrayListBlockInfo(slotBlock, i, new LinkedArrayListSlot2(leafCount, new Slot(indexPos, 1 /* INDEX */))));
2875
- if (shift === 0) {
2876
- return;
2877
- }
2878
- const slot = slotBlock[i];
2879
- switch (slot.slot.tag) {
2880
- case 0 /* NONE */:
2881
- throw new EmptySlotException;
2882
- case 1 /* INDEX */:
2883
- this.readLinkedArrayListBlocks(Number(slot.slot.value), nextKey, shift - 1, blocks);
2884
- break;
2885
- default:
2886
- throw new UnexpectedTagException;
2887
- }
2888
- }
2889
- populateArray(arr) {
2890
- for (let i = 0;i < arr.length; i++) {
2891
- arr[i] = new LinkedArrayListSlot2(0, new Slot);
2892
- }
2893
- }
2894
- readLinkedArrayListSlice(header, offset, size) {
2895
- const writer = this.core.writer();
2896
- if (offset + size > header.size) {
2897
- throw new KeyNotFoundException;
2898
- }
2899
- const leftBlocks = [];
2900
- this.readLinkedArrayListBlocks(header.ptr, offset, header.shift, leftBlocks);
2901
- const rightBlocks = [];
2902
- const rightKey = offset + size === 0 ? 0 : offset + size - 1;
2903
- this.readLinkedArrayListBlocks(header.ptr, rightKey, header.shift, rightBlocks);
2904
- const blockCount = leftBlocks.length;
2905
- let nextSlots = [null, null];
2906
- let nextShift = 0;
2907
- for (let i = 0;i < blockCount; i++) {
2908
- const isLeafNode = nextSlots[0] === null;
2909
- const leftBlock = leftBlocks[blockCount - i - 1];
2910
- const rightBlock = rightBlocks[blockCount - i - 1];
2911
- const origBlockInfos = [leftBlock, rightBlock];
2912
- let nextBlocks = [null, null];
2913
- if (leftBlock.parentSlot.slot.value === rightBlock.parentSlot.slot.value) {
2914
- let slotI = 0;
2915
- const newRootBlock = new Array(SLOT_COUNT);
2916
- this.populateArray(newRootBlock);
2917
- if (size > 0) {
2918
- if (nextSlots[0] !== null) {
2919
- newRootBlock[slotI] = nextSlots[0];
2920
- } else {
2921
- newRootBlock[slotI] = leftBlock.block[leftBlock.i];
2922
- }
2923
- slotI += 1;
2924
- }
2925
- if (size > 1) {
2926
- for (let j = leftBlock.i + 1;j < rightBlock.i; j++) {
2927
- const middleSlot = leftBlock.block[j];
2928
- newRootBlock[slotI] = middleSlot;
2929
- slotI += 1;
2930
- }
2931
- if (nextSlots[1] !== null) {
2932
- newRootBlock[slotI] = nextSlots[1];
2933
- } else {
2934
- newRootBlock[slotI] = leftBlock.block[rightBlock.i];
2935
- }
2936
- }
2937
- nextBlocks[0] = newRootBlock;
2938
- } else {
2939
- let slotI = 0;
2940
- const newLeftBlock = new Array(SLOT_COUNT);
2941
- this.populateArray(newLeftBlock);
2942
- if (nextSlots[0] !== null) {
2943
- newLeftBlock[slotI] = nextSlots[0];
2944
- } else {
2945
- newLeftBlock[slotI] = leftBlock.block[leftBlock.i];
2946
- }
2947
- slotI += 1;
2948
- for (let j = leftBlock.i + 1;j < leftBlock.block.length; j++) {
2949
- const nextSlot = leftBlock.block[j];
2950
- newLeftBlock[slotI] = nextSlot;
2951
- slotI += 1;
2952
- }
2953
- nextBlocks[0] = newLeftBlock;
2954
- slotI = 0;
2955
- const newRightBlock = new Array(SLOT_COUNT);
2956
- this.populateArray(newRightBlock);
2957
- for (let j = 0;j < rightBlock.i; j++) {
2958
- const firstSlot = rightBlock.block[j];
2959
- newRightBlock[slotI] = firstSlot;
2960
- slotI += 1;
2961
- }
2962
- if (nextSlots[1] !== null) {
2963
- newRightBlock[slotI] = nextSlots[1];
2964
- } else {
2965
- newRightBlock[slotI] = rightBlock.block[rightBlock.i];
2966
- }
2967
- nextBlocks[1] = newRightBlock;
2968
- nextShift += 1;
2969
- }
2970
- nextSlots = [null, null];
2971
- this.core.seek(this.core.length());
2972
- for (let j = 0;j < 2; j++) {
2973
- const blockMaybe = nextBlocks[j];
2974
- const origBlockInfo = origBlockInfos[j];
2975
- if (blockMaybe !== null) {
2976
- let eql = true;
2977
- for (let k = 0;k < blockMaybe.length; k++) {
2978
- const blockSlot = blockMaybe[k];
2979
- const origSlot = origBlockInfo.block[k];
2980
- if (!blockSlot.slot.equals(origSlot.slot)) {
2981
- eql = false;
2982
- break;
2983
- }
2984
- }
2985
- if (eql) {
2986
- nextSlots[j] = origBlockInfo.parentSlot;
2987
- } else {
2988
- const nextPtr = this.core.position();
2989
- let leafCount = 0;
2990
- for (let k = 0;k < blockMaybe.length; k++) {
2991
- const blockSlot = blockMaybe[k];
2992
- writer.write(blockSlot.toBytes());
2993
- if (isLeafNode) {
2994
- if (!blockSlot.slot.empty()) {
2995
- leafCount += 1;
2996
- }
2997
- } else {
2998
- leafCount += blockSlot.size;
2999
- }
3000
- }
3001
- nextSlots[j] = new LinkedArrayListSlot2(leafCount, j === 0 ? new Slot(nextPtr, 1 /* INDEX */, true) : new Slot(nextPtr, 1 /* INDEX */));
3002
- }
3003
- }
3004
- }
3005
- if (nextSlots[0] !== null && nextSlots[1] === null) {
3006
- break;
3007
- }
3008
- }
3009
- const rootSlot = nextSlots[0];
3010
- if (rootSlot === null)
3011
- throw new ExpectedRootNodeException;
3012
- return new LinkedArrayListHeader(nextShift, Number(rootSlot.slot.value), size);
3013
- }
3014
- readLinkedArrayListConcat(headerA, headerB) {
3015
- const writer = this.core.writer();
3016
- const blocksA = [];
3017
- const keyA = headerA.size === 0 ? 0 : headerA.size - 1;
3018
- this.readLinkedArrayListBlocks(headerA.ptr, keyA, headerA.shift, blocksA);
3019
- const blocksB = [];
3020
- this.readLinkedArrayListBlocks(headerB.ptr, 0, headerB.shift, blocksB);
3021
- let nextSlots = [null, null];
3022
- let nextShift = 0;
3023
- for (let i = 0;i < Math.max(blocksA.length, blocksB.length); i++) {
3024
- const blockInfos = [
3025
- i < blocksA.length ? blocksA[blocksA.length - 1 - i] : null,
3026
- i < blocksB.length ? blocksB[blocksB.length - 1 - i] : null
3027
- ];
3028
- let nextBlocks = [null, null];
3029
- const isLeafNode = nextSlots[0] === null;
3030
- if (!isLeafNode) {
3031
- nextShift += 1;
3032
- }
3033
- for (let j = 0;j < 2; j++) {
3034
- const blockInfoMaybe = blockInfos[j];
3035
- if (blockInfoMaybe !== null) {
3036
- const block = new Array(SLOT_COUNT);
3037
- this.populateArray(block);
3038
- let targetI = 0;
3039
- for (let sourceI = 0;sourceI < blockInfoMaybe.block.length; sourceI++) {
3040
- const blockSlot = blockInfoMaybe.block[sourceI];
3041
- if (!isLeafNode && blockInfoMaybe.i === sourceI) {
3042
- continue;
3043
- } else if (blockSlot.slot.empty()) {
3044
- break;
3045
- }
3046
- block[targetI] = blockSlot;
3047
- targetI += 1;
3048
- }
3049
- if (targetI === 0) {
3050
- continue;
3051
- }
3052
- nextBlocks[j] = block;
3053
- }
3054
- }
3055
- const slotsToWrite = new Array(SLOT_COUNT * 2);
3056
- this.populateArray(slotsToWrite);
3057
- let slotI = 0;
3058
- if (nextBlocks[0] !== null) {
3059
- for (const blockSlot of nextBlocks[0]) {
3060
- if (blockSlot.slot.empty()) {
3061
- break;
3062
- }
3063
- slotsToWrite[slotI] = blockSlot;
3064
- slotI += 1;
3065
- }
3066
- }
3067
- for (const slotMaybe of nextSlots) {
3068
- if (slotMaybe !== null) {
3069
- slotsToWrite[slotI] = slotMaybe;
3070
- slotI += 1;
3071
- }
3072
- }
3073
- if (nextBlocks[1] !== null) {
3074
- for (const blockSlot of nextBlocks[1]) {
3075
- if (blockSlot.slot.empty()) {
3076
- break;
3077
- }
3078
- slotsToWrite[slotI] = blockSlot;
3079
- slotI += 1;
3080
- }
3081
- }
3082
- nextSlots = [null, null];
3083
- const blocks = [new Array(SLOT_COUNT), new Array(SLOT_COUNT)];
3084
- this.populateArray(blocks[0]);
3085
- this.populateArray(blocks[1]);
3086
- if (slotI > SLOT_COUNT) {
3087
- if (headerA.size < headerB.size) {
3088
- for (let j = 0;j < slotI - SLOT_COUNT; j++) {
3089
- blocks[0][j] = slotsToWrite[j];
3090
- }
3091
- for (let j = 0;j < SLOT_COUNT; j++) {
3092
- blocks[1][j] = slotsToWrite[j + (slotI - SLOT_COUNT)];
3093
- }
3094
- } else {
3095
- for (let j = 0;j < SLOT_COUNT; j++) {
3096
- blocks[0][j] = slotsToWrite[j];
3097
- }
3098
- for (let j = 0;j < slotI - SLOT_COUNT; j++) {
3099
- blocks[1][j] = slotsToWrite[j + SLOT_COUNT];
3100
- }
3101
- }
3102
- } else {
3103
- for (let j = 0;j < slotI; j++) {
3104
- blocks[0][j] = slotsToWrite[j];
3105
- }
3106
- }
3107
- this.core.seek(this.core.length());
3108
- for (let blockI = 0;blockI < blocks.length; blockI++) {
3109
- const block = blocks[blockI];
3110
- if (block[0].slot.empty()) {
3111
- break;
3112
- }
3113
- const nextPtr = this.core.position();
3114
- let leafCount = 0;
3115
- for (const blockSlot of block) {
3116
- writer.write(blockSlot.toBytes());
3117
- if (isLeafNode) {
3118
- if (!blockSlot.slot.empty()) {
3119
- leafCount += 1;
3120
- }
3121
- } else {
3122
- leafCount += blockSlot.size;
3123
- }
3124
- }
3125
- nextSlots[blockI] = new LinkedArrayListSlot2(leafCount, new Slot(nextPtr, 1 /* INDEX */, true));
3126
- }
3127
- }
3128
- let rootPtr;
3129
- if (nextSlots[0] !== null) {
3130
- if (nextSlots[1] !== null) {
3131
- const block = new Array(SLOT_COUNT);
3132
- this.populateArray(block);
3133
- block[0] = nextSlots[0];
3134
- block[1] = nextSlots[1];
3135
- const newPtr = this.core.length();
3136
- for (const blockSlot of block) {
3137
- writer.write(blockSlot.toBytes());
3138
- }
3139
- if (nextShift === MAX_BRANCH_LENGTH)
3140
- throw new MaxShiftExceededException;
3141
- nextShift += 1;
3142
- rootPtr = newPtr;
3143
- } else {
3144
- rootPtr = Number(nextSlots[0].slot.value);
3145
- }
3146
- } else {
3147
- rootPtr = headerA.ptr;
3148
- }
3149
- return new LinkedArrayListHeader(nextShift, rootPtr, headerA.size + headerB.size);
3150
- }
3151
- }
3152
- function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
3153
- switch (slot.tag) {
3154
- case 0 /* NONE */:
3155
- case 8 /* UINT */:
3156
- case 9 /* INT */:
3157
- case 10 /* FLOAT */:
3158
- case 7 /* SHORT_BYTES */:
3159
- return slot;
3160
- case 6 /* BYTES */: {
3161
- const mapped = offsetMap.get(Number(slot.value));
3162
- if (mapped !== undefined)
3163
- return new Slot(mapped, slot.tag, slot.full);
3164
- const newOffset = remapBytes(sourceCore, targetCore, slot);
3165
- offsetMap.set(Number(slot.value), newOffset);
3166
- return new Slot(newOffset, slot.tag, slot.full);
3167
- }
3168
- case 1 /* INDEX */: {
3169
- const mapped = offsetMap.get(Number(slot.value));
3170
- if (mapped !== undefined)
3171
- return new Slot(mapped, slot.tag, slot.full);
3172
- const newOffset = remapIndex(sourceCore, targetCore, hashSize, offsetMap, slot);
3173
- offsetMap.set(Number(slot.value), newOffset);
3174
- return new Slot(newOffset, slot.tag, slot.full);
3175
- }
3176
- case 2 /* ARRAY_LIST */: {
3177
- const mapped = offsetMap.get(Number(slot.value));
3178
- if (mapped !== undefined)
3179
- return new Slot(mapped, slot.tag, slot.full);
3180
- const newOffset = remapArrayList(sourceCore, targetCore, hashSize, offsetMap, slot);
3181
- offsetMap.set(Number(slot.value), newOffset);
3182
- return new Slot(newOffset, slot.tag, slot.full);
3183
- }
3184
- case 3 /* LINKED_ARRAY_LIST */: {
3185
- const mapped = offsetMap.get(Number(slot.value));
3186
- if (mapped !== undefined)
3187
- return new Slot(mapped, slot.tag, slot.full);
3188
- const newOffset = remapLinkedArrayList(sourceCore, targetCore, hashSize, offsetMap, slot);
3189
- offsetMap.set(Number(slot.value), newOffset);
3190
- return new Slot(newOffset, slot.tag, slot.full);
3191
- }
3192
- case 4 /* HASH_MAP */:
3193
- case 11 /* HASH_SET */: {
3194
- const mapped = offsetMap.get(Number(slot.value));
3195
- if (mapped !== undefined)
3196
- return new Slot(mapped, slot.tag, slot.full);
3197
- const newOffset = remapHashMapOrSet(sourceCore, targetCore, hashSize, offsetMap, slot, false);
3198
- offsetMap.set(Number(slot.value), newOffset);
3199
- return new Slot(newOffset, slot.tag, slot.full);
3200
- }
3201
- case 12 /* COUNTED_HASH_MAP */:
3202
- case 13 /* COUNTED_HASH_SET */: {
3203
- const mapped = offsetMap.get(Number(slot.value));
3204
- if (mapped !== undefined)
3205
- return new Slot(mapped, slot.tag, slot.full);
3206
- const newOffset = remapHashMapOrSet(sourceCore, targetCore, hashSize, offsetMap, slot, true);
3207
- offsetMap.set(Number(slot.value), newOffset);
3208
- return new Slot(newOffset, slot.tag, slot.full);
3209
- }
3210
- case 5 /* KV_PAIR */: {
3211
- const mapped = offsetMap.get(Number(slot.value));
3212
- if (mapped !== undefined)
3213
- return new Slot(mapped, slot.tag, slot.full);
3214
- const newOffset = remapKvPair(sourceCore, targetCore, hashSize, offsetMap, slot);
3215
- offsetMap.set(Number(slot.value), newOffset);
3216
- return new Slot(newOffset, slot.tag, slot.full);
3217
- }
3218
- default:
3219
- throw new UnexpectedTagException;
3220
- }
3221
- }
3222
- function remapBytes(sourceCore, targetCore, slot) {
3223
- sourceCore.seek(Number(slot.value));
3224
- const sourceReader = sourceCore.reader();
3225
- const length = sourceReader.readLong();
3226
- const formatTagSize = slot.full ? 2 : 0;
3227
- const totalPayload = length + formatTagSize;
3228
- const newOffset = targetCore.length();
3229
- targetCore.seek(newOffset);
3230
- const targetWriter = targetCore.writer();
3231
- targetWriter.writeLong(length);
3232
- let remaining = totalPayload;
3233
- while (remaining > 0) {
3234
- const chunk = Math.min(remaining, 4096);
3235
- const buf = new Uint8Array(chunk);
3236
- sourceReader.readFully(buf);
3237
- targetWriter.write(buf);
3238
- remaining -= chunk;
3239
- }
3240
- return newOffset;
3241
- }
3242
- function remapIndex(sourceCore, targetCore, hashSize, offsetMap, slot) {
3243
- sourceCore.seek(Number(slot.value));
3244
- const sourceReader = sourceCore.reader();
3245
- const blockBytes = new Uint8Array(INDEX_BLOCK_SIZE);
3246
- sourceReader.readFully(blockBytes);
3247
- const remappedSlots = [];
3248
- for (let i = 0;i < SLOT_COUNT; i++) {
3249
- const slotBytes = blockBytes.slice(i * Slot.LENGTH, (i + 1) * Slot.LENGTH);
3250
- const childSlot = Slot.fromBytes(slotBytes);
3251
- remappedSlots.push(remapSlot(sourceCore, targetCore, hashSize, offsetMap, childSlot));
3252
- }
3253
- const newOffset = targetCore.length();
3254
- targetCore.seek(newOffset);
3255
- const targetWriter = targetCore.writer();
3256
- for (const s of remappedSlots) {
3257
- targetWriter.write(s.toBytes());
3258
- }
3259
- return newOffset;
3260
- }
3261
- function remapArrayList(sourceCore, targetCore, hashSize, offsetMap, slot) {
3262
- sourceCore.seek(Number(slot.value));
3263
- const sourceReader = sourceCore.reader();
3264
- const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
3265
- sourceReader.readFully(headerBytes);
3266
- const header = ArrayListHeader.fromBytes(headerBytes);
3267
- const indexSlot = new Slot(header.ptr, 1 /* INDEX */);
3268
- const remappedIndex = remapSlot(sourceCore, targetCore, hashSize, offsetMap, indexSlot);
3269
- const newOffset = targetCore.length();
3270
- targetCore.seek(newOffset);
3271
- const targetWriter = targetCore.writer();
3272
- targetWriter.write(new ArrayListHeader(Number(remappedIndex.value), header.size).toBytes());
3273
- return newOffset;
3274
- }
3275
- function remapLinkedArrayList(sourceCore, targetCore, hashSize, offsetMap, slot) {
3276
- sourceCore.seek(Number(slot.value));
3277
- const sourceReader = sourceCore.reader();
3278
- const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
3279
- sourceReader.readFully(headerBytes);
3280
- const header = LinkedArrayListHeader.fromBytes(headerBytes);
3281
- const remappedPtr = remapLinkedArrayListBlock(sourceCore, targetCore, hashSize, offsetMap, header.ptr);
3282
- const newOffset = targetCore.length();
3283
- targetCore.seek(newOffset);
3284
- const targetWriter = targetCore.writer();
3285
- targetWriter.write(new LinkedArrayListHeader(header.shift, remappedPtr, header.size).toBytes());
3286
- return newOffset;
3287
- }
3288
- function remapLinkedArrayListBlock(sourceCore, targetCore, hashSize, offsetMap, blockOffset) {
3289
- const mapped = offsetMap.get(blockOffset);
3290
- if (mapped !== undefined)
3291
- return mapped;
3292
- sourceCore.seek(blockOffset);
3293
- const sourceReader = sourceCore.reader();
3294
- const blockBytes = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
3295
- sourceReader.readFully(blockBytes);
3296
- const slots = [];
3297
- for (let i = 0;i < SLOT_COUNT; i++) {
3298
- const slotBytes = blockBytes.slice(i * LinkedArrayListSlot2.LENGTH, (i + 1) * LinkedArrayListSlot2.LENGTH);
3299
- slots.push(LinkedArrayListSlot2.fromBytes(slotBytes));
3300
- }
3301
- const remappedSlots = [];
3302
- for (const s of slots) {
3303
- if (s.slot.tag === 1 /* INDEX */) {
3304
- const remappedPtr = remapLinkedArrayListBlock(sourceCore, targetCore, hashSize, offsetMap, Number(s.slot.value));
3305
- remappedSlots.push(new LinkedArrayListSlot2(s.size, new Slot(remappedPtr, 1 /* INDEX */, s.slot.full)));
3306
- } else if (s.slot.empty()) {
3307
- remappedSlots.push(s);
3308
- } else {
3309
- const remapped = remapSlot(sourceCore, targetCore, hashSize, offsetMap, s.slot);
3310
- remappedSlots.push(new LinkedArrayListSlot2(s.size, remapped));
3311
- }
3312
- }
3313
- const newOffset = targetCore.length();
3314
- targetCore.seek(newOffset);
3315
- const targetWriter = targetCore.writer();
3316
- for (const s of remappedSlots) {
3317
- targetWriter.write(s.toBytes());
3318
- }
3319
- offsetMap.set(blockOffset, newOffset);
3320
- return newOffset;
3321
- }
3322
- function remapHashMapOrSet(sourceCore, targetCore, hashSize, offsetMap, slot, counted) {
3323
- sourceCore.seek(Number(slot.value));
3324
- const sourceReader = sourceCore.reader();
3325
- let countValue = -1;
3326
- if (counted) {
3327
- countValue = sourceReader.readLong();
3328
- }
3329
- const blockBytes = new Uint8Array(INDEX_BLOCK_SIZE);
3330
- sourceReader.readFully(blockBytes);
3331
- const remappedSlots = [];
3332
- for (let i = 0;i < SLOT_COUNT; i++) {
3333
- const slotBytes = blockBytes.slice(i * Slot.LENGTH, (i + 1) * Slot.LENGTH);
3334
- const childSlot = Slot.fromBytes(slotBytes);
3335
- remappedSlots.push(remapSlot(sourceCore, targetCore, hashSize, offsetMap, childSlot));
3336
- }
3337
- const newOffset = targetCore.length();
3338
- targetCore.seek(newOffset);
3339
- const targetWriter = targetCore.writer();
3340
- if (counted) {
3341
- targetWriter.writeLong(countValue);
3342
- }
3343
- for (const s of remappedSlots) {
3344
- targetWriter.write(s.toBytes());
3345
- }
3346
- return newOffset;
3347
- }
3348
- function remapKvPair(sourceCore, targetCore, hashSize, offsetMap, slot) {
3349
- sourceCore.seek(Number(slot.value));
3350
- const sourceReader = sourceCore.reader();
3351
- const kvPairBytes = new Uint8Array(KeyValuePair.length(hashSize));
3352
- sourceReader.readFully(kvPairBytes);
3353
- const kvPair = KeyValuePair.fromBytes(kvPairBytes, hashSize);
3354
- const remappedKey = remapSlot(sourceCore, targetCore, hashSize, offsetMap, kvPair.keySlot);
3355
- const remappedValue = remapSlot(sourceCore, targetCore, hashSize, offsetMap, kvPair.valueSlot);
3356
- const newOffset = targetCore.length();
3357
- targetCore.seek(newOffset);
3358
- const targetWriter = targetCore.writer();
3359
- targetWriter.write(new KeyValuePair(remappedValue, remappedKey, kvPair.hash).toBytes());
3360
- return newOffset;
3361
- }
3362
- // src/read-array-list.ts
3363
- class ReadArrayList {
3364
- cursor;
3365
- constructor(cursor) {
3366
- if (cursor) {
3367
- switch (cursor.slotPtr.slot.tag) {
3368
- case 0 /* NONE */:
3369
- case 2 /* ARRAY_LIST */:
3370
- this.cursor = cursor;
3371
- break;
3372
- default:
3373
- throw new UnexpectedTagException;
3374
- }
3375
- }
3376
- }
3377
- slot() {
3378
- return this.cursor.slot();
3379
- }
3380
- count() {
3381
- return this.cursor.count();
3382
- }
3383
- iterator() {
3384
- return this.cursor.iterator();
3385
- }
3386
- *[Symbol.iterator]() {
3387
- yield* this.cursor;
3388
- }
3389
- getCursor(index) {
3390
- return this.cursor.readPath([new ArrayListGet2(index)]);
3391
- }
3392
- getSlot(index) {
3393
- return this.cursor.readPathSlot([new ArrayListGet2(index)]);
3394
- }
3395
- }
3396
- // src/write-array-list.ts
3397
- class WriteArrayList extends ReadArrayList {
3398
- constructor(cursor) {
3399
- super();
3400
- this.cursor = cursor.writePath([new ArrayListInit]);
3401
- }
3402
- iterator() {
3403
- return this.cursor.iterator();
3404
- }
3405
- *[Symbol.iterator]() {
3406
- yield* this.cursor;
3407
- }
3408
- put(index, data) {
3409
- this.cursor.writePath([
3410
- new ArrayListGet2(index),
3411
- new WriteData(data)
3412
- ]);
3413
- }
3414
- putCursor(index) {
3415
- return this.cursor.writePath([new ArrayListGet2(index)]);
3416
- }
3417
- append(data) {
3418
- this.cursor.writePath([
3419
- new ArrayListAppend,
3420
- new WriteData(data)
3421
- ]);
3422
- }
3423
- appendCursor() {
3424
- return this.cursor.writePath([new ArrayListAppend]);
3425
- }
3426
- appendContext(data, fn) {
3427
- this.cursor.writePath([
3428
- new ArrayListAppend,
3429
- new WriteData(data),
3430
- new Context(fn)
3431
- ]);
3432
- }
3433
- slice(size) {
3434
- this.cursor.writePath([new ArrayListSlice(size)]);
3435
- }
3436
- }
3437
- // src/read-hash-map.ts
3438
- class ReadHashMap {
3439
- cursor;
3440
- constructor(cursor) {
3441
- if (cursor) {
3442
- switch (cursor.slotPtr.slot.tag) {
3443
- case 0 /* NONE */:
3444
- case 4 /* HASH_MAP */:
3445
- case 11 /* HASH_SET */:
3446
- this.cursor = cursor;
3447
- break;
3448
- default:
3449
- throw new UnexpectedTagException;
3450
- }
3451
- }
3452
- }
3453
- slot() {
3454
- return this.cursor.slot();
3455
- }
3456
- iterator() {
3457
- return this.cursor.iterator();
3458
- }
3459
- *[Symbol.iterator]() {
3460
- yield* this.cursor;
3461
- }
3462
- getCursor(key) {
3463
- const hash = this.resolveHash(key);
3464
- return this.cursor.readPath([new HashMapGet(new HashMapGetValue(hash))]);
3465
- }
3466
- getSlot(key) {
3467
- const hash = this.resolveHash(key);
3468
- return this.cursor.readPathSlot([new HashMapGet(new HashMapGetValue(hash))]);
3469
- }
3470
- getKeyCursor(key) {
3471
- const hash = this.resolveHash(key);
3472
- return this.cursor.readPath([new HashMapGet(new HashMapGetKey(hash))]);
3473
- }
3474
- getKeySlot(key) {
3475
- const hash = this.resolveHash(key);
3476
- return this.cursor.readPathSlot([new HashMapGet(new HashMapGetKey(hash))]);
3477
- }
3478
- getKeyValuePair(key) {
3479
- const hash = this.resolveHash(key);
3480
- const cursor = this.cursor.readPath([new HashMapGet(new HashMapGetKVPair(hash))]);
3481
- if (cursor === null) {
3482
- return null;
3483
- } else {
3484
- return cursor.readKeyValuePair();
3485
- }
3486
- }
3487
- resolveHash(key) {
3488
- if (key instanceof Uint8Array) {
3489
- return key;
3490
- } else if (typeof key === "string") {
3491
- return this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3492
- } else {
3493
- return this.cursor.db.hasher.digest(key.value);
3494
- }
3495
- }
3496
- }
3497
- // src/write-hash-map.ts
3498
- class WriteHashMap extends ReadHashMap {
3499
- constructor(cursor, counted = false) {
3500
- super();
3501
- this.cursor = cursor.writePath([new HashMapInit(counted, false)]);
3502
- }
3503
- iterator() {
3504
- return this.cursor.iterator();
3505
- }
3506
- *[Symbol.iterator]() {
3507
- yield* this.cursor;
3508
- }
3509
- put(key, data) {
3510
- if (typeof key === "string") {
3511
- const hash = this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3512
- this.putKeyInternal(hash, new Bytes(key));
3513
- this.putInternal(hash, data);
3514
- } else if (key instanceof Bytes) {
3515
- const hash = this.cursor.db.hasher.digest(key.value);
3516
- this.putKeyInternal(hash, key);
3517
- this.putInternal(hash, data);
3518
- } else {
3519
- this.putInternal(key, data);
3520
- }
3521
- }
3522
- putCursor(key) {
3523
- if (typeof key === "string") {
3524
- const hash = this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3525
- this.putKeyInternal(hash, new Bytes(key));
3526
- return this.putCursorInternal(hash);
3527
- } else if (key instanceof Bytes) {
3528
- const hash = this.cursor.db.hasher.digest(key.value);
3529
- this.putKeyInternal(hash, key);
3530
- return this.putCursorInternal(hash);
3531
- } else {
3532
- return this.putCursorInternal(key);
3533
- }
3534
- }
3535
- putKey(key, data) {
3536
- const hash = this.resolveHash(key);
3537
- this.putKeyInternal(hash, data);
3538
- }
3539
- putKeyCursor(key) {
3540
- const hash = this.resolveHash(key);
3541
- return this.putKeyCursorInternal(hash);
3542
- }
3543
- remove(key) {
3544
- const hash = this.resolveHash(key);
3545
- try {
3546
- this.cursor.writePath([new HashMapRemove(hash)]);
3547
- } catch (e) {
3548
- if (e instanceof KeyNotFoundException) {
3549
- return false;
3550
- }
3551
- throw e;
3552
- }
3553
- return true;
3554
- }
3555
- putInternal(hash, data) {
3556
- this.cursor.writePath([
3557
- new HashMapGet(new HashMapGetValue(hash)),
3558
- new WriteData(data)
3559
- ]);
3560
- }
3561
- putCursorInternal(hash) {
3562
- return this.cursor.writePath([
3563
- new HashMapGet(new HashMapGetValue(hash))
3564
- ]);
3565
- }
3566
- putKeyInternal(hash, data) {
3567
- const cursor = this.cursor.writePath([
3568
- new HashMapGet(new HashMapGetKey(hash))
3569
- ]);
3570
- cursor.writeIfEmpty(data);
3571
- }
3572
- putKeyCursorInternal(hash) {
3573
- return this.cursor.writePath([
3574
- new HashMapGet(new HashMapGetKey(hash))
3575
- ]);
3576
- }
3577
- }
3578
- // src/read-hash-set.ts
3579
- class ReadHashSet {
3580
- cursor;
3581
- constructor(cursor) {
3582
- if (cursor) {
3583
- switch (cursor.slotPtr.slot.tag) {
3584
- case 0 /* NONE */:
3585
- case 4 /* HASH_MAP */:
3586
- case 11 /* HASH_SET */:
3587
- this.cursor = cursor;
3588
- break;
3589
- default:
3590
- throw new UnexpectedTagException;
3591
- }
3592
- }
3593
- }
3594
- slot() {
3595
- return this.cursor.slot();
3596
- }
3597
- iterator() {
3598
- return this.cursor.iterator();
3599
- }
3600
- *[Symbol.iterator]() {
3601
- yield* this.cursor;
3602
- }
3603
- getCursor(key) {
3604
- const hash = this.resolveHash(key);
3605
- return this.cursor.readPath([new HashMapGet(new HashMapGetKey(hash))]);
3606
- }
3607
- getSlot(key) {
3608
- const hash = this.resolveHash(key);
3609
- return this.cursor.readPathSlot([new HashMapGet(new HashMapGetKey(hash))]);
3610
- }
3611
- resolveHash(key) {
3612
- if (key instanceof Uint8Array) {
3613
- return key;
3614
- } else if (typeof key === "string") {
3615
- return this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3616
- } else {
3617
- return this.cursor.db.hasher.digest(key.value);
3618
- }
3619
- }
3620
- }
3621
- // src/write-hash-set.ts
3622
- class WriteHashSet extends ReadHashSet {
3623
- constructor(cursor, counted = false) {
3624
- super();
3625
- this.cursor = cursor.writePath([new HashMapInit(counted, true)]);
3626
- }
3627
- iterator() {
3628
- return this.cursor.iterator();
3629
- }
3630
- *[Symbol.iterator]() {
3631
- yield* this.cursor;
3632
- }
3633
- put(key, data) {
3634
- if (typeof key === "string") {
3635
- const bytes = new TextEncoder().encode(key);
3636
- const hash = this.cursor.db.hasher.digest(bytes);
3637
- this.putInternal(hash, new Bytes(bytes));
3638
- } else if (key instanceof Bytes) {
3639
- const hash = this.cursor.db.hasher.digest(key.value);
3640
- this.putInternal(hash, key);
3641
- } else {
3642
- this.putInternal(key, data);
3643
- }
3644
- }
3645
- putCursor(key) {
3646
- const hash = this.resolveHash(key);
3647
- return this.putCursorInternal(hash);
3648
- }
3649
- remove(key) {
3650
- const hash = this.resolveHash(key);
3651
- try {
3652
- this.cursor.writePath([new HashMapRemove(hash)]);
3653
- } catch (e) {
3654
- if (e instanceof KeyNotFoundException) {
3655
- return false;
3656
- }
3657
- throw e;
3658
- }
3659
- return true;
3660
- }
3661
- putInternal(hash, data) {
3662
- const cursor = this.cursor.writePath([
3663
- new HashMapGet(new HashMapGetKey(hash))
3664
- ]);
3665
- cursor.writeIfEmpty(data);
3666
- }
3667
- putCursorInternal(hash) {
3668
- return this.cursor.writePath([
3669
- new HashMapGet(new HashMapGetKey(hash))
3670
- ]);
3671
- }
3672
- }
3673
- // src/read-linked-array-list.ts
3674
- class ReadLinkedArrayList {
3675
- cursor;
3676
- constructor(cursor) {
3677
- if (cursor) {
3678
- switch (cursor.slotPtr.slot.tag) {
3679
- case 0 /* NONE */:
3680
- case 3 /* LINKED_ARRAY_LIST */:
3681
- this.cursor = cursor;
3682
- break;
3683
- default:
3684
- throw new UnexpectedTagException;
3685
- }
3686
- }
3687
- }
3688
- slot() {
3689
- return this.cursor.slot();
3690
- }
3691
- count() {
3692
- return this.cursor.count();
3693
- }
3694
- iterator() {
3695
- return this.cursor.iterator();
3696
- }
3697
- *[Symbol.iterator]() {
3698
- yield* this.cursor;
3699
- }
3700
- getCursor(index) {
3701
- return this.cursor.readPath([new LinkedArrayListGet(index)]);
3702
- }
3703
- getSlot(index) {
3704
- return this.cursor.readPathSlot([new LinkedArrayListGet(index)]);
3705
- }
3706
- }
3707
- // src/write-linked-array-list.ts
3708
- class WriteLinkedArrayList extends ReadLinkedArrayList {
3709
- constructor(cursor) {
3710
- super();
3711
- this.cursor = cursor.writePath([new LinkedArrayListInit]);
3712
- }
3713
- iterator() {
3714
- return this.cursor.iterator();
3715
- }
3716
- *[Symbol.iterator]() {
3717
- yield* this.cursor;
3718
- }
3719
- put(index, data) {
3720
- this.cursor.writePath([
3721
- new LinkedArrayListGet(index),
3722
- new WriteData(data)
3723
- ]);
3724
- }
3725
- putCursor(index) {
3726
- return this.cursor.writePath([new LinkedArrayListGet(index)]);
3727
- }
3728
- append(data) {
3729
- this.cursor.writePath([
3730
- new LinkedArrayListAppend,
3731
- new WriteData(data)
3732
- ]);
3733
- }
3734
- appendCursor() {
3735
- return this.cursor.writePath([new LinkedArrayListAppend]);
3736
- }
3737
- slice(offset, size) {
3738
- this.cursor.writePath([
3739
- new LinkedArrayListSlice(offset, size)
3740
- ]);
3741
- }
3742
- concat(list) {
3743
- this.cursor.writePath([new LinkedArrayListConcat(list)]);
3744
- }
3745
- insert(index, data) {
3746
- this.cursor.writePath([
3747
- new LinkedArrayListInsert(index),
3748
- new WriteData(data)
3749
- ]);
3750
- }
3751
- insertCursor(index) {
3752
- return this.cursor.writePath([new LinkedArrayListInsert(index)]);
3753
- }
3754
- remove(index) {
3755
- this.cursor.writePath([new LinkedArrayListRemove(index)]);
3756
- }
3757
- }
3758
- // src/read-counted-hash-map.ts
3759
- class ReadCountedHashMap extends ReadHashMap {
3760
- constructor(cursor) {
3761
- super();
3762
- switch (cursor.slotPtr.slot.tag) {
3763
- case 0 /* NONE */:
3764
- case 12 /* COUNTED_HASH_MAP */:
3765
- case 13 /* COUNTED_HASH_SET */:
3766
- this.cursor = cursor;
3767
- break;
3768
- default:
3769
- throw new UnexpectedTagException;
3770
- }
3771
- }
3772
- count() {
3773
- return this.cursor.count();
3774
- }
3775
- }
3776
- // src/write-counted-hash-map.ts
3777
- class WriteCountedHashMap extends WriteHashMap {
3778
- constructor(cursor) {
3779
- switch (cursor.slotPtr.slot.tag) {
3780
- case 0 /* NONE */:
3781
- case 12 /* COUNTED_HASH_MAP */:
3782
- case 13 /* COUNTED_HASH_SET */:
3783
- super(cursor, true);
3784
- break;
3785
- default:
3786
- throw new UnexpectedTagException;
3787
- }
3788
- }
3789
- count() {
3790
- return this.cursor.count();
3791
- }
3792
- }
3793
- // src/read-counted-hash-set.ts
3794
- class ReadCountedHashSet extends ReadHashSet {
3795
- constructor(cursor) {
3796
- super();
3797
- switch (cursor.slotPtr.slot.tag) {
3798
- case 0 /* NONE */:
3799
- case 12 /* COUNTED_HASH_MAP */:
3800
- case 13 /* COUNTED_HASH_SET */:
3801
- this.cursor = cursor;
3802
- break;
3803
- default:
3804
- throw new UnexpectedTagException;
3805
- }
3806
- }
3807
- count() {
3808
- return this.cursor.count();
3809
- }
3810
- }
3811
- // src/write-counted-hash-set.ts
3812
- class WriteCountedHashSet extends WriteHashSet {
3813
- constructor(cursor) {
3814
- switch (cursor.slotPtr.slot.tag) {
3815
- case 0 /* NONE */:
3816
- case 12 /* COUNTED_HASH_MAP */:
3817
- case 13 /* COUNTED_HASH_SET */:
3818
- super(cursor, true);
3819
- break;
3820
- default:
3821
- throw new UnexpectedTagException;
3822
- }
3823
- }
3824
- count() {
3825
- return this.cursor.count();
3826
- }
3827
- }
3828
- export {
3829
- tagValueOf,
3830
- Writer,
3831
- WriteNotAllowedException,
3832
- WriteMode,
3833
- WriteLinkedArrayList,
3834
- WriteKeyValuePairCursor,
3835
- WriteHashSet,
3836
- WriteHashMap,
3837
- WriteData,
3838
- WriteCursorIterator,
3839
- WriteCursor,
3840
- WriteCountedHashSet,
3841
- WriteCountedHashMap,
3842
- WriteArrayList,
3843
- VERSION,
3844
- UnreachableException,
3845
- UnexpectedWriterPositionException,
3846
- UnexpectedTagException,
3847
- Uint,
3848
- TopLevelArrayListHeader,
3849
- Tag,
3850
- StreamTooLongException,
3851
- SlotPointer,
3852
- Slot,
3853
- SLOT_COUNT,
3854
- Reader,
3855
- ReadLinkedArrayList,
3856
- ReadHashSet,
3857
- ReadHashMap,
3858
- ReadCursor,
3859
- ReadCountedHashSet,
3860
- ReadCountedHashMap,
3861
- ReadArrayList,
3862
- PathPartMustBeAtEndException,
3863
- NotImplementedException,
3864
- NoAvailableSlotsException,
3865
- MustSetNewSlotsToFullException,
3866
- MaxShiftExceededException,
3867
- MAX_BRANCH_LENGTH,
3868
- MASK,
3869
- MAGIC_NUMBER,
3870
- LinkedArrayListSlotPointer,
3871
- LinkedArrayListSlot2 as LinkedArrayListSlot,
3872
- LinkedArrayListSlice,
3873
- LinkedArrayListRemove,
3874
- LinkedArrayListInsert,
3875
- LinkedArrayListInit,
3876
- LinkedArrayListHeader,
3877
- LinkedArrayListGet,
3878
- LinkedArrayListConcat,
3879
- LinkedArrayListBlockInfo,
3880
- LinkedArrayListAppend,
3881
- LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE,
3882
- KeyValuePairCursor,
3883
- KeyValuePair,
3884
- KeyOffsetExceededException,
3885
- KeyNotFoundException,
3886
- InvalidVersionException,
3887
- InvalidTopLevelTypeException,
3888
- InvalidOffsetException,
3889
- InvalidHashSizeException,
3890
- InvalidFormatTagSizeException,
3891
- InvalidDatabaseException,
3892
- Int,
3893
- INDEX_BLOCK_SIZE,
3894
- Header,
3895
- Hasher,
3896
- HashMapRemove,
3897
- HashMapInit,
3898
- HashMapGetValue,
3899
- HashMapGetKey,
3900
- HashMapGetKVPair,
3901
- HashMapGet,
3902
- Float,
3903
- ExpectedUnsignedLongException,
3904
- ExpectedTxStartException,
3905
- ExpectedRootNodeException,
3906
- EndOfStreamException,
3907
- EmptySlotException,
3908
- DatabaseException,
3909
- Database3 as Database,
3910
- CursorNotWriteableException,
3911
- CursorIterator,
3912
- CoreMemory,
3913
- CoreFile,
3914
- CoreBufferedFile,
3915
- Context,
3916
- Bytes,
3917
- BIT_COUNT,
3918
- ArrayListSlice,
3919
- ArrayListInit,
3920
- ArrayListHeader,
3921
- ArrayListGet2 as ArrayListGet,
3922
- ArrayListAppend
3923
- };
1
+ // Tag
2
+ export { Tag, tagValueOf } from './tag.js';
3
+ // Slot
4
+ export { Slot } from './slot.js';
5
+ export { SlotPointer } from './slot-pointer.js';
6
+ // Writeable Data
7
+ export { Uint, Int, Float, Bytes } from './writeable-data.js';
8
+ // Exceptions
9
+ export { DatabaseException, NotImplementedException, UnreachableException, InvalidDatabaseException, InvalidVersionException, InvalidHashSizeException, KeyNotFoundException, WriteNotAllowedException, UnexpectedTagException, CursorNotWriteableException, ExpectedTxStartException, KeyOffsetExceededException, PathPartMustBeAtEndException, StreamTooLongException, EndOfStreamException, InvalidOffsetException, InvalidTopLevelTypeException, ExpectedUnsignedLongException, NoAvailableSlotsException, MustSetNewSlotsToFullException, EmptySlotException, ExpectedRootNodeException, InvalidFormatTagSizeException, UnexpectedWriterPositionException, MaxShiftExceededException, } from './exceptions.js';
10
+ export { CoreMemory } from './core-memory.js';
11
+ export { CoreFile } from './core-file.js';
12
+ export { CoreBufferedFile } from './core-buffered-file.js';
13
+ export { Hasher } from './hasher.js';
14
+ // Database
15
+ export { Database, WriteMode, Header, ArrayListHeader, TopLevelArrayListHeader, BTreeHeader, KeyValuePair, BTreeNode, BTreeNodeKind, BTreeNodeRef, BTreeInsertResult, BTreeWriteSlot, BTreeJoinResult, BTreeSplitResult, SortedNode, SortedSplit, SortedInsertResult, SortedRemoveResult, SortedSlot, SortedEntry, VERSION, MAGIC_NUMBER, BIT_COUNT, SLOT_COUNT, MASK, INDEX_BLOCK_SIZE, MAX_BRANCH_LENGTH, BTREE_SLOT_COUNT, BTREE_SPLIT_COUNT, BTREE_NODE_HEADER_SIZE, BTREE_LEAF_BLOCK_SIZE, BTREE_BRANCH_BLOCK_SIZE, SORTED_LEAF_BLOCK_SIZE, SORTED_BRANCH_BLOCK_SIZE, ArrayListInit, ArrayListGet, ArrayListAppend, ArrayListSlice, LinkedArrayListInit, LinkedArrayListGet, LinkedArrayListAppend, LinkedArrayListSlice, LinkedArrayListConcat, LinkedArrayListInsert, LinkedArrayListRemove, HashMapInit, HashMapGet, HashMapRemove, SortedMapInit, SortedMapGet, SortedMapGetIndex, SortedMapRemove, WriteData, Context, HashMapGetKVPair, HashMapGetKey, HashMapGetValue, SortedMapGetKVPair, SortedMapGetKey, SortedMapGetValue, } from './database.js';
16
+ // Cursors
17
+ export { ReadCursor, Reader, CursorIterator, KeyValuePairCursor } from './read-cursor.js';
18
+ export { WriteCursor, Writer, WriteCursorIterator, WriteKeyValuePairCursor } from './write-cursor.js';
19
+ // Collections
20
+ export { ReadArrayList } from './read-array-list.js';
21
+ export { WriteArrayList } from './write-array-list.js';
22
+ export { ReadHashMap } from './read-hash-map.js';
23
+ export { WriteHashMap } from './write-hash-map.js';
24
+ export { ReadHashSet } from './read-hash-set.js';
25
+ export { WriteHashSet } from './write-hash-set.js';
26
+ export { ReadLinkedArrayList } from './read-linked-array-list.js';
27
+ export { WriteLinkedArrayList } from './write-linked-array-list.js';
28
+ export { ReadCountedHashMap } from './read-counted-hash-map.js';
29
+ export { WriteCountedHashMap } from './write-counted-hash-map.js';
30
+ export { ReadCountedHashSet } from './read-counted-hash-set.js';
31
+ export { WriteCountedHashSet } from './write-counted-hash-set.js';
32
+ export { ReadSortedMap } from './read-sorted-map.js';
33
+ export { WriteSortedMap } from './write-sorted-map.js';
34
+ export { ReadSortedSet } from './read-sorted-set.js';
35
+ export { WriteSortedSet } from './write-sorted-set.js';