xitdb 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -115
- package/dist/core-buffered-file.d.ts +21 -23
- package/dist/core-file.d.ts +7 -9
- package/dist/core-memory.d.ts +14 -14
- package/dist/core.d.ts +14 -14
- package/dist/database.d.ts +35 -36
- package/dist/hasher.d.ts +2 -1
- package/dist/index.js +728 -791
- package/dist/read-array-list.d.ts +5 -5
- package/dist/read-counted-hash-map.d.ts +1 -1
- package/dist/read-counted-hash-set.d.ts +1 -1
- package/dist/read-cursor.d.ts +18 -18
- package/dist/read-hash-map.d.ts +18 -18
- package/dist/read-hash-set.d.ts +9 -9
- package/dist/read-linked-array-list.d.ts +5 -5
- package/dist/write-array-list.d.ts +9 -10
- package/dist/write-counted-hash-map.d.ts +2 -3
- package/dist/write-counted-hash-set.d.ts +2 -3
- package/dist/write-cursor.d.ts +10 -10
- package/dist/write-hash-map.d.ts +18 -19
- package/dist/write-hash-set.d.ts +12 -13
- package/dist/write-linked-array-list.d.ts +12 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,22 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
-
for (let key of __getOwnPropNames(mod))
|
|
11
|
-
if (!__hasOwnProp.call(to, key))
|
|
12
|
-
__defProp(to, key, {
|
|
13
|
-
get: () => mod[key],
|
|
14
|
-
enumerable: true
|
|
15
|
-
});
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __require = import.meta.require;
|
|
19
|
-
|
|
20
2
|
// src/tag.ts
|
|
21
3
|
var Tag;
|
|
22
4
|
((Tag2) => {
|
|
@@ -261,20 +243,20 @@ class CoreMemory {
|
|
|
261
243
|
writer() {
|
|
262
244
|
return this.memory;
|
|
263
245
|
}
|
|
264
|
-
|
|
246
|
+
length() {
|
|
265
247
|
return this.memory.size();
|
|
266
248
|
}
|
|
267
|
-
|
|
249
|
+
seek(pos) {
|
|
268
250
|
this.memory.seek(pos);
|
|
269
251
|
}
|
|
270
252
|
position() {
|
|
271
253
|
return this.memory.getPosition();
|
|
272
254
|
}
|
|
273
|
-
|
|
255
|
+
setLength(len) {
|
|
274
256
|
this.memory.setLength(len);
|
|
275
257
|
}
|
|
276
|
-
|
|
277
|
-
|
|
258
|
+
flush() {}
|
|
259
|
+
sync() {}
|
|
278
260
|
}
|
|
279
261
|
|
|
280
262
|
class RandomAccessMemory {
|
|
@@ -327,7 +309,7 @@ class RandomAccessMemory {
|
|
|
327
309
|
toByteArray() {
|
|
328
310
|
return this.buffer.slice(0, this._count);
|
|
329
311
|
}
|
|
330
|
-
|
|
312
|
+
write(data) {
|
|
331
313
|
const pos = this._position;
|
|
332
314
|
if (pos < this._count) {
|
|
333
315
|
const bytesBeforeEnd = Math.min(data.length, this._count - pos);
|
|
@@ -347,22 +329,22 @@ class RandomAccessMemory {
|
|
|
347
329
|
}
|
|
348
330
|
this._position = pos + data.length;
|
|
349
331
|
}
|
|
350
|
-
|
|
351
|
-
|
|
332
|
+
writeByte(v) {
|
|
333
|
+
this.write(new Uint8Array([v & 255]));
|
|
352
334
|
}
|
|
353
|
-
|
|
335
|
+
writeShort(v) {
|
|
354
336
|
const buffer = new ArrayBuffer(2);
|
|
355
337
|
const view = new DataView(buffer);
|
|
356
338
|
view.setInt16(0, v, false);
|
|
357
|
-
|
|
339
|
+
this.write(new Uint8Array(buffer));
|
|
358
340
|
}
|
|
359
|
-
|
|
341
|
+
writeLong(v) {
|
|
360
342
|
const buffer = new ArrayBuffer(8);
|
|
361
343
|
const view = new DataView(buffer);
|
|
362
344
|
view.setBigInt64(0, BigInt(v), false);
|
|
363
|
-
|
|
345
|
+
this.write(new Uint8Array(buffer));
|
|
364
346
|
}
|
|
365
|
-
|
|
347
|
+
readFully(b) {
|
|
366
348
|
const pos = this._position;
|
|
367
349
|
if (pos + b.length > this._count) {
|
|
368
350
|
throw new Error("End of stream");
|
|
@@ -370,49 +352,45 @@ class RandomAccessMemory {
|
|
|
370
352
|
b.set(this.buffer.subarray(pos, pos + b.length));
|
|
371
353
|
this._position = pos + b.length;
|
|
372
354
|
}
|
|
373
|
-
|
|
355
|
+
readByte() {
|
|
374
356
|
const bytes = new Uint8Array(1);
|
|
375
|
-
|
|
357
|
+
this.readFully(bytes);
|
|
376
358
|
return bytes[0];
|
|
377
359
|
}
|
|
378
|
-
|
|
360
|
+
readShort() {
|
|
379
361
|
const bytes = new Uint8Array(2);
|
|
380
|
-
|
|
362
|
+
this.readFully(bytes);
|
|
381
363
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
382
364
|
return view.getInt16(0, false);
|
|
383
365
|
}
|
|
384
|
-
|
|
366
|
+
readInt() {
|
|
385
367
|
const bytes = new Uint8Array(4);
|
|
386
|
-
|
|
368
|
+
this.readFully(bytes);
|
|
387
369
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
388
370
|
return view.getInt32(0, false);
|
|
389
371
|
}
|
|
390
|
-
|
|
372
|
+
readLong() {
|
|
391
373
|
const bytes = new Uint8Array(8);
|
|
392
|
-
|
|
374
|
+
this.readFully(bytes);
|
|
393
375
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
394
376
|
return Number(view.getBigInt64(0, false));
|
|
395
377
|
}
|
|
396
378
|
}
|
|
397
379
|
// src/core-file.ts
|
|
398
|
-
import * as fs from "fs
|
|
380
|
+
import * as fs from "fs";
|
|
399
381
|
|
|
400
382
|
class CoreFile {
|
|
401
383
|
filePath;
|
|
402
384
|
_position = 0;
|
|
403
|
-
|
|
404
|
-
constructor(filePath
|
|
385
|
+
fd;
|
|
386
|
+
constructor(filePath) {
|
|
405
387
|
this.filePath = filePath;
|
|
406
|
-
this.fileHandle = fileHandle;
|
|
407
|
-
}
|
|
408
|
-
static async create(filePath) {
|
|
409
388
|
try {
|
|
410
|
-
|
|
389
|
+
fs.accessSync(filePath);
|
|
411
390
|
} catch {
|
|
412
|
-
|
|
391
|
+
fs.writeFileSync(filePath, new Uint8Array(0));
|
|
413
392
|
}
|
|
414
|
-
|
|
415
|
-
return new CoreFile(filePath, fileHandle);
|
|
393
|
+
this.fd = fs.openSync(filePath, "r+");
|
|
416
394
|
}
|
|
417
395
|
reader() {
|
|
418
396
|
return new FileDataReader(this);
|
|
@@ -420,27 +398,25 @@ class CoreFile {
|
|
|
420
398
|
writer() {
|
|
421
399
|
return new FileDataWriter(this);
|
|
422
400
|
}
|
|
423
|
-
|
|
424
|
-
const stats =
|
|
401
|
+
length() {
|
|
402
|
+
const stats = fs.fstatSync(this.fd);
|
|
425
403
|
return stats.size;
|
|
426
404
|
}
|
|
427
|
-
|
|
405
|
+
seek(pos) {
|
|
428
406
|
this._position = pos;
|
|
429
407
|
}
|
|
430
408
|
position() {
|
|
431
409
|
return this._position;
|
|
432
410
|
}
|
|
433
|
-
|
|
434
|
-
|
|
411
|
+
setLength(len) {
|
|
412
|
+
fs.ftruncateSync(this.fd, len);
|
|
435
413
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
414
|
+
flush() {}
|
|
415
|
+
sync() {
|
|
416
|
+
fs.fsyncSync(this.fd);
|
|
439
417
|
}
|
|
440
418
|
[Symbol.dispose]() {
|
|
441
|
-
|
|
442
|
-
fs2.closeSync(this.fileHandle.fd);
|
|
443
|
-
});
|
|
419
|
+
fs.closeSync(this.fd);
|
|
444
420
|
}
|
|
445
421
|
}
|
|
446
422
|
|
|
@@ -449,31 +425,31 @@ class FileDataReader {
|
|
|
449
425
|
constructor(core) {
|
|
450
426
|
this.core = core;
|
|
451
427
|
}
|
|
452
|
-
|
|
428
|
+
readFully(b) {
|
|
453
429
|
const position = this.core.position();
|
|
454
|
-
|
|
430
|
+
fs.readSync(this.core.fd, b, 0, b.length, position);
|
|
455
431
|
this.core.seek(position + b.length);
|
|
456
432
|
}
|
|
457
|
-
|
|
433
|
+
readByte() {
|
|
458
434
|
const bytes = new Uint8Array(1);
|
|
459
|
-
|
|
435
|
+
this.readFully(bytes);
|
|
460
436
|
return bytes[0];
|
|
461
437
|
}
|
|
462
|
-
|
|
438
|
+
readShort() {
|
|
463
439
|
const bytes = new Uint8Array(2);
|
|
464
|
-
|
|
440
|
+
this.readFully(bytes);
|
|
465
441
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
466
442
|
return view.getInt16(0, false);
|
|
467
443
|
}
|
|
468
|
-
|
|
444
|
+
readInt() {
|
|
469
445
|
const bytes = new Uint8Array(4);
|
|
470
|
-
|
|
446
|
+
this.readFully(bytes);
|
|
471
447
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
472
448
|
return view.getInt32(0, false);
|
|
473
449
|
}
|
|
474
|
-
|
|
450
|
+
readLong() {
|
|
475
451
|
const bytes = new Uint8Array(8);
|
|
476
|
-
|
|
452
|
+
this.readFully(bytes);
|
|
477
453
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
478
454
|
return Number(view.getBigInt64(0, false));
|
|
479
455
|
}
|
|
@@ -484,36 +460,32 @@ class FileDataWriter {
|
|
|
484
460
|
constructor(core) {
|
|
485
461
|
this.core = core;
|
|
486
462
|
}
|
|
487
|
-
|
|
463
|
+
write(buffer) {
|
|
488
464
|
const position = this.core.position();
|
|
489
|
-
|
|
465
|
+
fs.writeSync(this.core.fd, buffer, 0, buffer.length, position);
|
|
490
466
|
this.core.seek(position + buffer.length);
|
|
491
467
|
}
|
|
492
|
-
|
|
493
|
-
|
|
468
|
+
writeByte(v) {
|
|
469
|
+
this.write(new Uint8Array([v & 255]));
|
|
494
470
|
}
|
|
495
|
-
|
|
471
|
+
writeShort(v) {
|
|
496
472
|
const buffer = new ArrayBuffer(2);
|
|
497
473
|
const view = new DataView(buffer);
|
|
498
474
|
view.setInt16(0, v, false);
|
|
499
|
-
|
|
475
|
+
this.write(new Uint8Array(buffer));
|
|
500
476
|
}
|
|
501
|
-
|
|
477
|
+
writeLong(v) {
|
|
502
478
|
const buffer = new ArrayBuffer(8);
|
|
503
479
|
const view = new DataView(buffer);
|
|
504
480
|
view.setBigInt64(0, BigInt(v), false);
|
|
505
|
-
|
|
481
|
+
this.write(new Uint8Array(buffer));
|
|
506
482
|
}
|
|
507
483
|
}
|
|
508
484
|
// src/core-buffered-file.ts
|
|
509
485
|
class CoreBufferedFile {
|
|
510
486
|
file;
|
|
511
|
-
constructor(
|
|
512
|
-
this.file =
|
|
513
|
-
}
|
|
514
|
-
static async create(filePath, bufferSize) {
|
|
515
|
-
const file = await RandomAccessBufferedFile.create(filePath, bufferSize);
|
|
516
|
-
return new CoreBufferedFile(file);
|
|
487
|
+
constructor(filePath, bufferSize) {
|
|
488
|
+
this.file = new RandomAccessBufferedFile(filePath, bufferSize);
|
|
517
489
|
}
|
|
518
490
|
reader() {
|
|
519
491
|
return this.file;
|
|
@@ -521,23 +493,23 @@ class CoreBufferedFile {
|
|
|
521
493
|
writer() {
|
|
522
494
|
return this.file;
|
|
523
495
|
}
|
|
524
|
-
|
|
525
|
-
return
|
|
496
|
+
length() {
|
|
497
|
+
return this.file.length();
|
|
526
498
|
}
|
|
527
|
-
|
|
528
|
-
|
|
499
|
+
seek(pos) {
|
|
500
|
+
this.file.seek(pos);
|
|
529
501
|
}
|
|
530
502
|
position() {
|
|
531
503
|
return this.file.position();
|
|
532
504
|
}
|
|
533
|
-
|
|
534
|
-
|
|
505
|
+
setLength(len) {
|
|
506
|
+
this.file.setLength(len);
|
|
535
507
|
}
|
|
536
|
-
|
|
537
|
-
|
|
508
|
+
flush() {
|
|
509
|
+
this.file.flush();
|
|
538
510
|
}
|
|
539
|
-
|
|
540
|
-
|
|
511
|
+
sync() {
|
|
512
|
+
this.file.sync();
|
|
541
513
|
}
|
|
542
514
|
[Symbol.dispose]() {
|
|
543
515
|
this.file.file[Symbol.dispose]();
|
|
@@ -551,139 +523,138 @@ class RandomAccessBufferedFile {
|
|
|
551
523
|
bufferSize;
|
|
552
524
|
filePos;
|
|
553
525
|
memoryPos;
|
|
554
|
-
constructor(
|
|
555
|
-
this.file =
|
|
526
|
+
constructor(filePath, bufferSize = DEFAULT_BUFFER_SIZE) {
|
|
527
|
+
this.file = new CoreFile(filePath);
|
|
556
528
|
this.memory = new CoreMemory;
|
|
557
529
|
this.bufferSize = bufferSize;
|
|
558
530
|
this.filePos = 0;
|
|
559
531
|
this.memoryPos = 0;
|
|
560
532
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
}
|
|
565
|
-
async seek(pos) {
|
|
566
|
-
if (pos > this.memoryPos + await this.memory.length()) {
|
|
567
|
-
await this.flush();
|
|
533
|
+
seek(pos) {
|
|
534
|
+
if (pos > this.memoryPos + this.memory.length()) {
|
|
535
|
+
this.flush();
|
|
568
536
|
}
|
|
569
537
|
this.filePos = pos;
|
|
570
|
-
if (
|
|
538
|
+
if (this.memory.length() === 0) {
|
|
571
539
|
this.memoryPos = pos;
|
|
572
540
|
}
|
|
573
541
|
}
|
|
574
|
-
|
|
575
|
-
return Math.max(this.memoryPos +
|
|
542
|
+
length() {
|
|
543
|
+
return Math.max(this.memoryPos + this.memory.length(), this.file.length());
|
|
576
544
|
}
|
|
577
545
|
position() {
|
|
578
546
|
return this.filePos;
|
|
579
547
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
548
|
+
setLength(len) {
|
|
549
|
+
this.flush();
|
|
550
|
+
this.file.setLength(len);
|
|
583
551
|
this.filePos = Math.min(len, this.filePos);
|
|
584
552
|
}
|
|
585
|
-
|
|
586
|
-
if (
|
|
587
|
-
|
|
588
|
-
|
|
553
|
+
flush() {
|
|
554
|
+
if (this.memory.length() > 0) {
|
|
555
|
+
this.file.seek(this.memoryPos);
|
|
556
|
+
this.file.writer().write(this.memory.memory.toByteArray());
|
|
589
557
|
this.memoryPos = 0;
|
|
590
558
|
this.memory.memory.reset();
|
|
591
559
|
}
|
|
592
560
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
561
|
+
sync() {
|
|
562
|
+
this.flush();
|
|
563
|
+
this.file.sync();
|
|
596
564
|
}
|
|
597
|
-
|
|
598
|
-
if (
|
|
599
|
-
|
|
565
|
+
write(buffer) {
|
|
566
|
+
if (this.memory.length() + buffer.length > this.bufferSize) {
|
|
567
|
+
this.flush();
|
|
600
568
|
}
|
|
601
|
-
if (this.filePos >= this.memoryPos && this.filePos <= this.memoryPos +
|
|
569
|
+
if (this.filePos >= this.memoryPos && this.filePos <= this.memoryPos + this.memory.length()) {
|
|
602
570
|
this.memory.seek(this.filePos - this.memoryPos);
|
|
603
|
-
|
|
571
|
+
this.memory.memory.write(buffer);
|
|
604
572
|
} else {
|
|
605
|
-
|
|
606
|
-
|
|
573
|
+
this.file.seek(this.filePos);
|
|
574
|
+
this.file.writer().write(buffer);
|
|
607
575
|
}
|
|
608
576
|
this.filePos += buffer.length;
|
|
609
577
|
}
|
|
610
|
-
|
|
611
|
-
|
|
578
|
+
writeByte(v) {
|
|
579
|
+
this.write(new Uint8Array([v & 255]));
|
|
612
580
|
}
|
|
613
|
-
|
|
581
|
+
writeShort(v) {
|
|
614
582
|
const buffer = new ArrayBuffer(2);
|
|
615
583
|
const view = new DataView(buffer);
|
|
616
584
|
view.setInt16(0, v & 65535, false);
|
|
617
|
-
|
|
585
|
+
this.write(new Uint8Array(buffer));
|
|
618
586
|
}
|
|
619
|
-
|
|
587
|
+
writeLong(v) {
|
|
620
588
|
const buffer = new ArrayBuffer(8);
|
|
621
589
|
const view = new DataView(buffer);
|
|
622
590
|
view.setBigInt64(0, BigInt(v), false);
|
|
623
|
-
|
|
591
|
+
this.write(new Uint8Array(buffer));
|
|
624
592
|
}
|
|
625
|
-
|
|
593
|
+
readFully(buffer) {
|
|
626
594
|
let pos = 0;
|
|
627
595
|
if (this.filePos < this.memoryPos) {
|
|
628
596
|
const sizeBeforeMem = Math.min(this.memoryPos - this.filePos, buffer.length);
|
|
629
597
|
const tempBuffer = new Uint8Array(sizeBeforeMem);
|
|
630
|
-
|
|
631
|
-
|
|
598
|
+
this.file.seek(this.filePos);
|
|
599
|
+
this.file.reader().readFully(tempBuffer);
|
|
632
600
|
buffer.set(tempBuffer, pos);
|
|
633
601
|
pos += sizeBeforeMem;
|
|
634
602
|
this.filePos += sizeBeforeMem;
|
|
635
603
|
}
|
|
636
604
|
if (pos === buffer.length)
|
|
637
605
|
return;
|
|
638
|
-
if (this.filePos >= this.memoryPos && this.filePos < this.memoryPos +
|
|
606
|
+
if (this.filePos >= this.memoryPos && this.filePos < this.memoryPos + this.memory.length()) {
|
|
639
607
|
const memPos = this.filePos - this.memoryPos;
|
|
640
|
-
const sizeInMem = Math.min(
|
|
608
|
+
const sizeInMem = Math.min(this.memory.length() - memPos, buffer.length - pos);
|
|
641
609
|
this.memory.seek(memPos);
|
|
642
610
|
const memBuffer = new Uint8Array(sizeInMem);
|
|
643
|
-
|
|
611
|
+
this.memory.memory.readFully(memBuffer);
|
|
644
612
|
buffer.set(memBuffer, pos);
|
|
645
613
|
pos += sizeInMem;
|
|
646
614
|
this.filePos += sizeInMem;
|
|
647
615
|
}
|
|
648
616
|
if (pos === buffer.length)
|
|
649
617
|
return;
|
|
650
|
-
if (this.filePos >= this.memoryPos +
|
|
618
|
+
if (this.filePos >= this.memoryPos + this.memory.length()) {
|
|
651
619
|
const sizeAfterMem = buffer.length - pos;
|
|
652
620
|
const tempBuffer = new Uint8Array(sizeAfterMem);
|
|
653
|
-
|
|
654
|
-
|
|
621
|
+
this.file.seek(this.filePos);
|
|
622
|
+
this.file.reader().readFully(tempBuffer);
|
|
655
623
|
buffer.set(tempBuffer, pos);
|
|
656
624
|
pos += sizeAfterMem;
|
|
657
625
|
this.filePos += sizeAfterMem;
|
|
658
626
|
}
|
|
659
627
|
}
|
|
660
|
-
|
|
628
|
+
readByte() {
|
|
661
629
|
const bytes = new Uint8Array(1);
|
|
662
|
-
|
|
630
|
+
this.readFully(bytes);
|
|
663
631
|
return bytes[0];
|
|
664
632
|
}
|
|
665
|
-
|
|
633
|
+
readShort() {
|
|
666
634
|
const bytes = new Uint8Array(2);
|
|
667
|
-
|
|
635
|
+
this.readFully(bytes);
|
|
668
636
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
669
637
|
return view.getInt16(0, false);
|
|
670
638
|
}
|
|
671
|
-
|
|
639
|
+
readInt() {
|
|
672
640
|
const bytes = new Uint8Array(4);
|
|
673
|
-
|
|
641
|
+
this.readFully(bytes);
|
|
674
642
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
675
643
|
return view.getInt32(0, false);
|
|
676
644
|
}
|
|
677
|
-
|
|
645
|
+
readLong() {
|
|
678
646
|
const bytes = new Uint8Array(8);
|
|
679
|
-
|
|
647
|
+
this.readFully(bytes);
|
|
680
648
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
681
649
|
return Number(view.getBigInt64(0, false));
|
|
682
650
|
}
|
|
683
651
|
}
|
|
684
652
|
// src/hasher.ts
|
|
653
|
+
import { createHash } from "crypto";
|
|
654
|
+
|
|
685
655
|
class Hasher {
|
|
686
656
|
algorithm;
|
|
657
|
+
nodeAlgorithm;
|
|
687
658
|
id;
|
|
688
659
|
digestLength;
|
|
689
660
|
constructor(algorithm, id = 0) {
|
|
@@ -692,26 +663,26 @@ class Hasher {
|
|
|
692
663
|
switch (algorithm) {
|
|
693
664
|
case "SHA-1":
|
|
694
665
|
this.digestLength = 20;
|
|
666
|
+
this.nodeAlgorithm = "sha1";
|
|
695
667
|
break;
|
|
696
668
|
case "SHA-256":
|
|
697
669
|
this.digestLength = 32;
|
|
670
|
+
this.nodeAlgorithm = "sha256";
|
|
698
671
|
break;
|
|
699
672
|
case "SHA-384":
|
|
700
673
|
this.digestLength = 48;
|
|
674
|
+
this.nodeAlgorithm = "sha384";
|
|
701
675
|
break;
|
|
702
676
|
case "SHA-512":
|
|
703
677
|
this.digestLength = 64;
|
|
678
|
+
this.nodeAlgorithm = "sha512";
|
|
704
679
|
break;
|
|
705
680
|
default:
|
|
706
681
|
throw new Error(`Unsupported hash algorithm: ${algorithm}`);
|
|
707
682
|
}
|
|
708
683
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
const view = new Uint8Array(buffer);
|
|
712
|
-
view.set(data);
|
|
713
|
-
const hashBuffer = await crypto.subtle.digest(this.algorithm, buffer);
|
|
714
|
-
return new Uint8Array(hashBuffer);
|
|
684
|
+
digest(data) {
|
|
685
|
+
return new Uint8Array(createHash(this.nodeAlgorithm).update(data).digest());
|
|
715
686
|
}
|
|
716
687
|
static stringToId(hashIdName) {
|
|
717
688
|
const bytes = new TextEncoder().encode(hashIdName);
|
|
@@ -750,9 +721,9 @@ class ReadCursor {
|
|
|
750
721
|
slot() {
|
|
751
722
|
return this.slotPtr.slot;
|
|
752
723
|
}
|
|
753
|
-
|
|
724
|
+
readPath(path) {
|
|
754
725
|
try {
|
|
755
|
-
const slotPtr =
|
|
726
|
+
const slotPtr = this.db.readSlotPointer(0 /* READ_ONLY */, path, 0, this.slotPtr);
|
|
756
727
|
return new ReadCursor(slotPtr, this.db);
|
|
757
728
|
} catch (e) {
|
|
758
729
|
if (e instanceof KeyNotFoundException) {
|
|
@@ -761,9 +732,9 @@ class ReadCursor {
|
|
|
761
732
|
throw e;
|
|
762
733
|
}
|
|
763
734
|
}
|
|
764
|
-
|
|
735
|
+
readPathSlot(path) {
|
|
765
736
|
try {
|
|
766
|
-
const slotPtr =
|
|
737
|
+
const slotPtr = this.db.readSlotPointer(0 /* READ_ONLY */, path, 0, this.slotPtr);
|
|
767
738
|
if (!slotPtr.slot.empty()) {
|
|
768
739
|
return slotPtr.slot;
|
|
769
740
|
} else {
|
|
@@ -799,29 +770,29 @@ class ReadCursor {
|
|
|
799
770
|
view.setBigInt64(0, this.slotPtr.slot.value, false);
|
|
800
771
|
return view.getFloat64(0, false);
|
|
801
772
|
}
|
|
802
|
-
|
|
803
|
-
const bytesObj =
|
|
773
|
+
readBytes(maxSizeMaybe = null) {
|
|
774
|
+
const bytesObj = this.readBytesObject(maxSizeMaybe);
|
|
804
775
|
return bytesObj.value;
|
|
805
776
|
}
|
|
806
|
-
|
|
777
|
+
readBytesObject(maxSizeMaybe = null) {
|
|
807
778
|
const reader = this.db.core.reader();
|
|
808
779
|
switch (this.slotPtr.slot.tag) {
|
|
809
780
|
case 0 /* NONE */:
|
|
810
781
|
return new Bytes(new Uint8Array(0));
|
|
811
782
|
case 6 /* BYTES */: {
|
|
812
|
-
|
|
813
|
-
const valueSize =
|
|
783
|
+
this.db.core.seek(Number(this.slotPtr.slot.value));
|
|
784
|
+
const valueSize = reader.readLong();
|
|
814
785
|
if (maxSizeMaybe !== null && valueSize > maxSizeMaybe) {
|
|
815
786
|
throw new StreamTooLongException;
|
|
816
787
|
}
|
|
817
788
|
const startPosition = this.db.core.position();
|
|
818
789
|
const value = new Uint8Array(valueSize);
|
|
819
|
-
|
|
790
|
+
reader.readFully(value);
|
|
820
791
|
let formatTag = null;
|
|
821
792
|
if (this.slotPtr.slot.full) {
|
|
822
|
-
|
|
793
|
+
this.db.core.seek(startPosition + valueSize);
|
|
823
794
|
formatTag = new Uint8Array(2);
|
|
824
|
-
|
|
795
|
+
reader.readFully(formatTag);
|
|
825
796
|
}
|
|
826
797
|
return new Bytes(value, formatTag);
|
|
827
798
|
}
|
|
@@ -850,26 +821,26 @@ class ReadCursor {
|
|
|
850
821
|
throw new UnexpectedTagException;
|
|
851
822
|
}
|
|
852
823
|
}
|
|
853
|
-
|
|
824
|
+
readKeyValuePair() {
|
|
854
825
|
const reader = this.db.core.reader();
|
|
855
826
|
if (this.slotPtr.slot.tag !== 5 /* KV_PAIR */) {
|
|
856
827
|
throw new UnexpectedTagException;
|
|
857
828
|
}
|
|
858
|
-
|
|
829
|
+
this.db.core.seek(Number(this.slotPtr.slot.value));
|
|
859
830
|
const kvPairBytes = new Uint8Array(KeyValuePair.length(this.db.header.hashSize));
|
|
860
|
-
|
|
831
|
+
reader.readFully(kvPairBytes);
|
|
861
832
|
const kvPair = KeyValuePair.fromBytes(kvPairBytes, this.db.header.hashSize);
|
|
862
833
|
const hashPos = Number(this.slotPtr.slot.value);
|
|
863
834
|
const keySlotPos = hashPos + this.db.header.hashSize;
|
|
864
835
|
const valueSlotPos = keySlotPos + Slot.LENGTH;
|
|
865
836
|
return new KeyValuePairCursor(new ReadCursor(new SlotPointer(valueSlotPos, kvPair.valueSlot), this.db), new ReadCursor(new SlotPointer(keySlotPos, kvPair.keySlot), this.db), kvPair.hash);
|
|
866
837
|
}
|
|
867
|
-
|
|
838
|
+
reader() {
|
|
868
839
|
const reader = this.db.core.reader();
|
|
869
840
|
switch (this.slotPtr.slot.tag) {
|
|
870
841
|
case 6 /* BYTES */: {
|
|
871
|
-
|
|
872
|
-
const size =
|
|
842
|
+
this.db.core.seek(Number(this.slotPtr.slot.value));
|
|
843
|
+
const size = reader.readLong();
|
|
873
844
|
const startPosition = this.db.core.position();
|
|
874
845
|
return new Reader(this, size, startPosition, 0);
|
|
875
846
|
}
|
|
@@ -892,27 +863,27 @@ class ReadCursor {
|
|
|
892
863
|
throw new UnexpectedTagException;
|
|
893
864
|
}
|
|
894
865
|
}
|
|
895
|
-
|
|
866
|
+
count() {
|
|
896
867
|
const reader = this.db.core.reader();
|
|
897
868
|
switch (this.slotPtr.slot.tag) {
|
|
898
869
|
case 0 /* NONE */:
|
|
899
870
|
return 0;
|
|
900
871
|
case 2 /* ARRAY_LIST */: {
|
|
901
|
-
|
|
872
|
+
this.db.core.seek(Number(this.slotPtr.slot.value));
|
|
902
873
|
const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
|
|
903
|
-
|
|
874
|
+
reader.readFully(headerBytes);
|
|
904
875
|
const header = ArrayListHeader.fromBytes(headerBytes);
|
|
905
876
|
return header.size;
|
|
906
877
|
}
|
|
907
878
|
case 3 /* LINKED_ARRAY_LIST */: {
|
|
908
|
-
|
|
879
|
+
this.db.core.seek(Number(this.slotPtr.slot.value));
|
|
909
880
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
910
|
-
|
|
881
|
+
reader.readFully(headerBytes);
|
|
911
882
|
const header = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
912
883
|
return header.size;
|
|
913
884
|
}
|
|
914
885
|
case 6 /* BYTES */: {
|
|
915
|
-
|
|
886
|
+
this.db.core.seek(Number(this.slotPtr.slot.value));
|
|
916
887
|
return reader.readLong();
|
|
917
888
|
}
|
|
918
889
|
case 7 /* SHORT_BYTES */: {
|
|
@@ -931,25 +902,25 @@ class ReadCursor {
|
|
|
931
902
|
}
|
|
932
903
|
case 12 /* COUNTED_HASH_MAP */:
|
|
933
904
|
case 13 /* COUNTED_HASH_SET */: {
|
|
934
|
-
|
|
905
|
+
this.db.core.seek(Number(this.slotPtr.slot.value));
|
|
935
906
|
return reader.readLong();
|
|
936
907
|
}
|
|
937
908
|
default:
|
|
938
909
|
throw new UnexpectedTagException;
|
|
939
910
|
}
|
|
940
911
|
}
|
|
941
|
-
|
|
942
|
-
const iterator =
|
|
943
|
-
while (
|
|
944
|
-
const next =
|
|
912
|
+
*[Symbol.iterator]() {
|
|
913
|
+
const iterator = this.iterator();
|
|
914
|
+
while (iterator.hasNext()) {
|
|
915
|
+
const next = iterator.next();
|
|
945
916
|
if (next !== null) {
|
|
946
917
|
yield next;
|
|
947
918
|
}
|
|
948
919
|
}
|
|
949
920
|
}
|
|
950
|
-
|
|
921
|
+
iterator() {
|
|
951
922
|
const iterator = new CursorIterator(this);
|
|
952
|
-
|
|
923
|
+
iterator.init();
|
|
953
924
|
return iterator;
|
|
954
925
|
}
|
|
955
926
|
}
|
|
@@ -965,52 +936,52 @@ class Reader {
|
|
|
965
936
|
this.startPosition = startPosition;
|
|
966
937
|
this.relativePosition = relativePosition;
|
|
967
938
|
}
|
|
968
|
-
|
|
939
|
+
read(buffer) {
|
|
969
940
|
if (this.size < this.relativePosition)
|
|
970
941
|
throw new EndOfStreamException;
|
|
971
|
-
|
|
942
|
+
this.parent.db.core.seek(this.startPosition + this.relativePosition);
|
|
972
943
|
const readSize = Math.min(buffer.length, this.size - this.relativePosition);
|
|
973
944
|
if (readSize === 0)
|
|
974
945
|
return -1;
|
|
975
946
|
const reader = this.parent.db.core.reader();
|
|
976
947
|
const tempBuffer = new Uint8Array(readSize);
|
|
977
|
-
|
|
948
|
+
reader.readFully(tempBuffer);
|
|
978
949
|
buffer.set(tempBuffer);
|
|
979
950
|
this.relativePosition += readSize;
|
|
980
951
|
return readSize;
|
|
981
952
|
}
|
|
982
|
-
|
|
953
|
+
readFully(buffer) {
|
|
983
954
|
if (this.size < this.relativePosition || this.size - this.relativePosition < buffer.length) {
|
|
984
955
|
throw new EndOfStreamException;
|
|
985
956
|
}
|
|
986
|
-
|
|
957
|
+
this.parent.db.core.seek(this.startPosition + this.relativePosition);
|
|
987
958
|
const reader = this.parent.db.core.reader();
|
|
988
|
-
|
|
959
|
+
reader.readFully(buffer);
|
|
989
960
|
this.relativePosition += buffer.length;
|
|
990
961
|
}
|
|
991
|
-
|
|
962
|
+
readByte() {
|
|
992
963
|
const bytes = new Uint8Array(1);
|
|
993
|
-
|
|
964
|
+
this.readFully(bytes);
|
|
994
965
|
return bytes[0];
|
|
995
966
|
}
|
|
996
|
-
|
|
967
|
+
readShort() {
|
|
997
968
|
const readSize = 2;
|
|
998
969
|
const bytes = new Uint8Array(readSize);
|
|
999
|
-
|
|
970
|
+
this.readFully(bytes);
|
|
1000
971
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1001
972
|
return view.getInt16(0, false);
|
|
1002
973
|
}
|
|
1003
|
-
|
|
974
|
+
readInt() {
|
|
1004
975
|
const readSize = 4;
|
|
1005
976
|
const bytes = new Uint8Array(readSize);
|
|
1006
|
-
|
|
977
|
+
this.readFully(bytes);
|
|
1007
978
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1008
979
|
return view.getInt32(0, false);
|
|
1009
980
|
}
|
|
1010
|
-
|
|
981
|
+
readLong() {
|
|
1011
982
|
const readSize = 8;
|
|
1012
983
|
const bytes = new Uint8Array(readSize);
|
|
1013
|
-
|
|
984
|
+
this.readFully(bytes);
|
|
1014
985
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1015
986
|
return Number(view.getBigInt64(0, false));
|
|
1016
987
|
}
|
|
@@ -1042,7 +1013,7 @@ class CursorIterator {
|
|
|
1042
1013
|
constructor(cursor) {
|
|
1043
1014
|
this.cursor = cursor;
|
|
1044
1015
|
}
|
|
1045
|
-
|
|
1016
|
+
init() {
|
|
1046
1017
|
switch (this.cursor.slotPtr.slot.tag) {
|
|
1047
1018
|
case 0 /* NONE */:
|
|
1048
1019
|
this.size = 0;
|
|
@@ -1051,49 +1022,49 @@ class CursorIterator {
|
|
|
1051
1022
|
break;
|
|
1052
1023
|
case 2 /* ARRAY_LIST */: {
|
|
1053
1024
|
const position = Number(this.cursor.slotPtr.slot.value);
|
|
1054
|
-
|
|
1025
|
+
this.cursor.db.core.seek(position);
|
|
1055
1026
|
const reader = this.cursor.db.core.reader();
|
|
1056
1027
|
const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
|
|
1057
|
-
|
|
1028
|
+
reader.readFully(headerBytes);
|
|
1058
1029
|
const header = ArrayListHeader.fromBytes(headerBytes);
|
|
1059
|
-
this.size =
|
|
1030
|
+
this.size = this.cursor.count();
|
|
1060
1031
|
this.index = 0;
|
|
1061
|
-
this.stack =
|
|
1032
|
+
this.stack = this.initStack(this.cursor, header.ptr, INDEX_BLOCK_SIZE);
|
|
1062
1033
|
break;
|
|
1063
1034
|
}
|
|
1064
1035
|
case 3 /* LINKED_ARRAY_LIST */: {
|
|
1065
1036
|
const position = Number(this.cursor.slotPtr.slot.value);
|
|
1066
|
-
|
|
1037
|
+
this.cursor.db.core.seek(position);
|
|
1067
1038
|
const reader = this.cursor.db.core.reader();
|
|
1068
1039
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1069
|
-
|
|
1040
|
+
reader.readFully(headerBytes);
|
|
1070
1041
|
const header = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
1071
|
-
this.size =
|
|
1042
|
+
this.size = this.cursor.count();
|
|
1072
1043
|
this.index = 0;
|
|
1073
|
-
this.stack =
|
|
1044
|
+
this.stack = this.initStack(this.cursor, header.ptr, LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
|
|
1074
1045
|
break;
|
|
1075
1046
|
}
|
|
1076
1047
|
case 4 /* HASH_MAP */:
|
|
1077
1048
|
case 11 /* HASH_SET */:
|
|
1078
1049
|
this.size = 0;
|
|
1079
1050
|
this.index = 0;
|
|
1080
|
-
this.stack =
|
|
1051
|
+
this.stack = this.initStack(this.cursor, Number(this.cursor.slotPtr.slot.value), INDEX_BLOCK_SIZE);
|
|
1081
1052
|
break;
|
|
1082
1053
|
case 12 /* COUNTED_HASH_MAP */:
|
|
1083
1054
|
case 13 /* COUNTED_HASH_SET */:
|
|
1084
1055
|
this.size = 0;
|
|
1085
1056
|
this.index = 0;
|
|
1086
|
-
this.stack =
|
|
1057
|
+
this.stack = this.initStack(this.cursor, Number(this.cursor.slotPtr.slot.value) + 8, INDEX_BLOCK_SIZE);
|
|
1087
1058
|
break;
|
|
1088
1059
|
default:
|
|
1089
1060
|
throw new UnexpectedTagException;
|
|
1090
1061
|
}
|
|
1091
1062
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1063
|
+
initStack(cursor, position, blockSize) {
|
|
1064
|
+
cursor.db.core.seek(position);
|
|
1094
1065
|
const reader = cursor.db.core.reader();
|
|
1095
1066
|
const indexBlockBytes = new Uint8Array(blockSize);
|
|
1096
|
-
|
|
1067
|
+
reader.readFully(indexBlockBytes);
|
|
1097
1068
|
const indexBlock = new Array(SLOT_COUNT);
|
|
1098
1069
|
const slotSize = blockSize / SLOT_COUNT;
|
|
1099
1070
|
for (let i = 0;i < SLOT_COUNT; i++) {
|
|
@@ -1102,7 +1073,7 @@ class CursorIterator {
|
|
|
1102
1073
|
}
|
|
1103
1074
|
return [new IteratorLevel(position, indexBlock, 0)];
|
|
1104
1075
|
}
|
|
1105
|
-
|
|
1076
|
+
hasNext() {
|
|
1106
1077
|
switch (this.cursor.slotPtr.slot.tag) {
|
|
1107
1078
|
case 0 /* NONE */:
|
|
1108
1079
|
return false;
|
|
@@ -1115,24 +1086,24 @@ class CursorIterator {
|
|
|
1115
1086
|
case 12 /* COUNTED_HASH_MAP */:
|
|
1116
1087
|
case 13 /* COUNTED_HASH_SET */:
|
|
1117
1088
|
if (this.nextCursorMaybe === null) {
|
|
1118
|
-
this.nextCursorMaybe =
|
|
1089
|
+
this.nextCursorMaybe = this.nextInternal(INDEX_BLOCK_SIZE);
|
|
1119
1090
|
}
|
|
1120
1091
|
return this.nextCursorMaybe !== null;
|
|
1121
1092
|
default:
|
|
1122
1093
|
return false;
|
|
1123
1094
|
}
|
|
1124
1095
|
}
|
|
1125
|
-
|
|
1096
|
+
next() {
|
|
1126
1097
|
switch (this.cursor.slotPtr.slot.tag) {
|
|
1127
1098
|
case 0 /* NONE */:
|
|
1128
1099
|
return null;
|
|
1129
1100
|
case 2 /* ARRAY_LIST */:
|
|
1130
|
-
if (!
|
|
1101
|
+
if (!this.hasNext())
|
|
1131
1102
|
return null;
|
|
1132
1103
|
this.index += 1;
|
|
1133
1104
|
return this.nextInternal(INDEX_BLOCK_SIZE);
|
|
1134
1105
|
case 3 /* LINKED_ARRAY_LIST */:
|
|
1135
|
-
if (!
|
|
1106
|
+
if (!this.hasNext())
|
|
1136
1107
|
return null;
|
|
1137
1108
|
this.index += 1;
|
|
1138
1109
|
return this.nextInternal(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
|
|
@@ -1151,7 +1122,7 @@ class CursorIterator {
|
|
|
1151
1122
|
throw new UnexpectedTagException;
|
|
1152
1123
|
}
|
|
1153
1124
|
}
|
|
1154
|
-
|
|
1125
|
+
nextInternal(blockSize) {
|
|
1155
1126
|
while (this.stack.length > 0) {
|
|
1156
1127
|
const level = this.stack[this.stack.length - 1];
|
|
1157
1128
|
if (level.index === level.block.length) {
|
|
@@ -1164,10 +1135,10 @@ class CursorIterator {
|
|
|
1164
1135
|
const nextSlot = level.block[level.index];
|
|
1165
1136
|
if (nextSlot.tag === 1 /* INDEX */) {
|
|
1166
1137
|
const nextPos = Number(nextSlot.value);
|
|
1167
|
-
|
|
1138
|
+
this.cursor.db.core.seek(nextPos);
|
|
1168
1139
|
const reader = this.cursor.db.core.reader();
|
|
1169
1140
|
const indexBlockBytes = new Uint8Array(blockSize);
|
|
1170
|
-
|
|
1141
|
+
reader.readFully(indexBlockBytes);
|
|
1171
1142
|
const indexBlock = new Array(SLOT_COUNT);
|
|
1172
1143
|
const slotSize = blockSize / SLOT_COUNT;
|
|
1173
1144
|
for (let i = 0;i < SLOT_COUNT; i++) {
|
|
@@ -1206,46 +1177,46 @@ class WriteCursor extends ReadCursor {
|
|
|
1206
1177
|
constructor(slotPtr, db) {
|
|
1207
1178
|
super(slotPtr, db);
|
|
1208
1179
|
}
|
|
1209
|
-
|
|
1210
|
-
const slotPtr =
|
|
1180
|
+
writePath(path) {
|
|
1181
|
+
const slotPtr = this.db.readSlotPointer(1 /* READ_WRITE */, path, 0, this.slotPtr);
|
|
1211
1182
|
if (this.db.txStart === null) {
|
|
1212
|
-
|
|
1183
|
+
this.db.core.sync();
|
|
1213
1184
|
}
|
|
1214
1185
|
return new WriteCursor(slotPtr, this.db);
|
|
1215
1186
|
}
|
|
1216
|
-
|
|
1217
|
-
const cursor =
|
|
1187
|
+
write(data) {
|
|
1188
|
+
const cursor = this.writePath([new WriteData(data)]);
|
|
1218
1189
|
this.slotPtr = cursor.slotPtr;
|
|
1219
1190
|
}
|
|
1220
|
-
|
|
1191
|
+
writeIfEmpty(data) {
|
|
1221
1192
|
if (this.slotPtr.slot.empty()) {
|
|
1222
|
-
|
|
1193
|
+
this.write(data);
|
|
1223
1194
|
}
|
|
1224
1195
|
}
|
|
1225
|
-
|
|
1226
|
-
const kvPairCursor =
|
|
1196
|
+
readKeyValuePair() {
|
|
1197
|
+
const kvPairCursor = super.readKeyValuePair();
|
|
1227
1198
|
return new WriteKeyValuePairCursor(new WriteCursor(kvPairCursor.valueCursor.slotPtr, this.db), new WriteCursor(kvPairCursor.keyCursor.slotPtr, this.db), kvPairCursor.hash);
|
|
1228
1199
|
}
|
|
1229
|
-
|
|
1200
|
+
writer() {
|
|
1230
1201
|
const writer = this.db.core.writer();
|
|
1231
|
-
const ptrPos =
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
const startPosition =
|
|
1202
|
+
const ptrPos = this.db.core.length();
|
|
1203
|
+
this.db.core.seek(ptrPos);
|
|
1204
|
+
writer.writeLong(0);
|
|
1205
|
+
const startPosition = this.db.core.length();
|
|
1235
1206
|
return new Writer(this, 0, new Slot(ptrPos, 6 /* BYTES */), startPosition, 0);
|
|
1236
1207
|
}
|
|
1237
|
-
|
|
1238
|
-
const iterator =
|
|
1239
|
-
while (
|
|
1240
|
-
const next =
|
|
1208
|
+
*[Symbol.iterator]() {
|
|
1209
|
+
const iterator = this.iterator();
|
|
1210
|
+
while (iterator.hasNext()) {
|
|
1211
|
+
const next = iterator.next();
|
|
1241
1212
|
if (next !== null) {
|
|
1242
1213
|
yield next;
|
|
1243
1214
|
}
|
|
1244
1215
|
}
|
|
1245
1216
|
}
|
|
1246
|
-
|
|
1217
|
+
iterator() {
|
|
1247
1218
|
const iterator = new WriteCursorIterator(this);
|
|
1248
|
-
|
|
1219
|
+
iterator.init();
|
|
1249
1220
|
return iterator;
|
|
1250
1221
|
}
|
|
1251
1222
|
}
|
|
@@ -1264,34 +1235,34 @@ class Writer {
|
|
|
1264
1235
|
this.startPosition = startPosition;
|
|
1265
1236
|
this.relativePosition = relativePosition;
|
|
1266
1237
|
}
|
|
1267
|
-
|
|
1238
|
+
write(buffer) {
|
|
1268
1239
|
if (this.size < this.relativePosition)
|
|
1269
1240
|
throw new EndOfStreamException;
|
|
1270
|
-
|
|
1241
|
+
this.parent.db.core.seek(this.startPosition + this.relativePosition);
|
|
1271
1242
|
const writer = this.parent.db.core.writer();
|
|
1272
|
-
|
|
1243
|
+
writer.write(buffer);
|
|
1273
1244
|
this.relativePosition += buffer.length;
|
|
1274
1245
|
if (this.relativePosition > this.size) {
|
|
1275
1246
|
this.size = this.relativePosition;
|
|
1276
1247
|
}
|
|
1277
1248
|
}
|
|
1278
|
-
|
|
1249
|
+
finish() {
|
|
1279
1250
|
const writer = this.parent.db.core.writer();
|
|
1280
1251
|
if (this.formatTag !== null) {
|
|
1281
1252
|
this.slot = this.slot.withFull(true);
|
|
1282
|
-
const formatTagPos =
|
|
1283
|
-
|
|
1253
|
+
const formatTagPos = this.parent.db.core.length();
|
|
1254
|
+
this.parent.db.core.seek(formatTagPos);
|
|
1284
1255
|
if (this.startPosition + this.size !== formatTagPos)
|
|
1285
1256
|
throw new UnexpectedWriterPositionException;
|
|
1286
|
-
|
|
1257
|
+
writer.write(this.formatTag);
|
|
1287
1258
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1259
|
+
this.parent.db.core.seek(Number(this.slot.value));
|
|
1260
|
+
writer.writeLong(this.size);
|
|
1290
1261
|
if (this.parent.slotPtr.position === null)
|
|
1291
1262
|
throw new CursorNotWriteableException;
|
|
1292
1263
|
const position = this.parent.slotPtr.position;
|
|
1293
|
-
|
|
1294
|
-
|
|
1264
|
+
this.parent.db.core.seek(position);
|
|
1265
|
+
writer.write(this.slot.toBytes());
|
|
1295
1266
|
this.parent.slotPtr = this.parent.slotPtr.withSlot(this.slot);
|
|
1296
1267
|
}
|
|
1297
1268
|
seek(position) {
|
|
@@ -1305,8 +1276,8 @@ class WriteCursorIterator extends CursorIterator {
|
|
|
1305
1276
|
constructor(cursor) {
|
|
1306
1277
|
super(cursor);
|
|
1307
1278
|
}
|
|
1308
|
-
|
|
1309
|
-
const readCursor =
|
|
1279
|
+
next() {
|
|
1280
|
+
const readCursor = super.next();
|
|
1310
1281
|
if (readCursor !== null) {
|
|
1311
1282
|
return new WriteCursor(readCursor.slotPtr, readCursor.db);
|
|
1312
1283
|
} else {
|
|
@@ -1356,20 +1327,20 @@ class Header {
|
|
|
1356
1327
|
view.setInt32(8, this.hashId, false);
|
|
1357
1328
|
return arr;
|
|
1358
1329
|
}
|
|
1359
|
-
static
|
|
1330
|
+
static read(core) {
|
|
1360
1331
|
const reader = core.reader();
|
|
1361
1332
|
const magicNumber = new Uint8Array(3);
|
|
1362
|
-
|
|
1363
|
-
const tagByte =
|
|
1333
|
+
reader.readFully(magicNumber);
|
|
1334
|
+
const tagByte = reader.readByte();
|
|
1364
1335
|
const tag = tagValueOf(tagByte & 127);
|
|
1365
|
-
const version =
|
|
1366
|
-
const hashSize =
|
|
1367
|
-
const hashId =
|
|
1336
|
+
const version = reader.readShort();
|
|
1337
|
+
const hashSize = reader.readShort();
|
|
1338
|
+
const hashId = reader.readInt();
|
|
1368
1339
|
return new Header(hashId, hashSize, version, tag, magicNumber);
|
|
1369
1340
|
}
|
|
1370
|
-
|
|
1341
|
+
write(core) {
|
|
1371
1342
|
const writer = core.writer();
|
|
1372
|
-
|
|
1343
|
+
writer.write(this.toBytes());
|
|
1373
1344
|
}
|
|
1374
1345
|
validate() {
|
|
1375
1346
|
if (!arraysEqual(this.magicNumber, MAGIC_NUMBER)) {
|
|
@@ -1569,19 +1540,19 @@ class HashMapGetValue {
|
|
|
1569
1540
|
|
|
1570
1541
|
class ArrayListInit {
|
|
1571
1542
|
kind = "ArrayListInit";
|
|
1572
|
-
|
|
1543
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1573
1544
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1574
1545
|
throw new WriteNotAllowedException;
|
|
1575
1546
|
if (isTopLevel) {
|
|
1576
1547
|
const writer = db.core.writer();
|
|
1577
1548
|
if (db.header.tag === 0 /* NONE */) {
|
|
1578
|
-
|
|
1549
|
+
db.core.seek(Header.LENGTH);
|
|
1579
1550
|
const arrayListPtr = Header.LENGTH + TopLevelArrayListHeader.LENGTH;
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1551
|
+
writer.write(new TopLevelArrayListHeader(0, new ArrayListHeader(arrayListPtr, 0)).toBytes());
|
|
1552
|
+
writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
|
|
1553
|
+
db.core.seek(0);
|
|
1583
1554
|
db.header = db.header.withTag(2 /* ARRAY_LIST */);
|
|
1584
|
-
|
|
1555
|
+
writer.write(db.header.toBytes());
|
|
1585
1556
|
}
|
|
1586
1557
|
const nextSlotPtr = slotPtr.withSlot(slotPtr.slot.withTag(2 /* ARRAY_LIST */));
|
|
1587
1558
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
@@ -1592,14 +1563,14 @@ class ArrayListInit {
|
|
|
1592
1563
|
switch (slotPtr.slot.tag) {
|
|
1593
1564
|
case 0 /* NONE */: {
|
|
1594
1565
|
const writer = db.core.writer();
|
|
1595
|
-
let arrayListStart =
|
|
1596
|
-
|
|
1566
|
+
let arrayListStart = db.core.length();
|
|
1567
|
+
db.core.seek(arrayListStart);
|
|
1597
1568
|
const arrayListPtr = arrayListStart + ArrayListHeader.LENGTH;
|
|
1598
|
-
|
|
1599
|
-
|
|
1569
|
+
writer.write(new ArrayListHeader(arrayListPtr, 0).toBytes());
|
|
1570
|
+
writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
|
|
1600
1571
|
const nextSlotPtr = new SlotPointer(position, new Slot(arrayListStart, 2 /* ARRAY_LIST */));
|
|
1601
|
-
|
|
1602
|
-
|
|
1572
|
+
db.core.seek(position);
|
|
1573
|
+
writer.write(nextSlotPtr.slot.toBytes());
|
|
1603
1574
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
1604
1575
|
}
|
|
1605
1576
|
case 2 /* ARRAY_LIST */: {
|
|
@@ -1608,26 +1579,26 @@ class ArrayListInit {
|
|
|
1608
1579
|
let arrayListStart = Number(slotPtr.slot.value);
|
|
1609
1580
|
if (db.txStart !== null) {
|
|
1610
1581
|
if (arrayListStart < db.txStart) {
|
|
1611
|
-
|
|
1582
|
+
db.core.seek(arrayListStart);
|
|
1612
1583
|
const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
|
|
1613
|
-
|
|
1584
|
+
reader.readFully(headerBytes);
|
|
1614
1585
|
const header = ArrayListHeader.fromBytes(headerBytes);
|
|
1615
|
-
|
|
1586
|
+
db.core.seek(header.ptr);
|
|
1616
1587
|
const arrayListIndexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
|
|
1617
|
-
|
|
1618
|
-
arrayListStart =
|
|
1619
|
-
|
|
1588
|
+
reader.readFully(arrayListIndexBlock);
|
|
1589
|
+
arrayListStart = db.core.length();
|
|
1590
|
+
db.core.seek(arrayListStart);
|
|
1620
1591
|
const nextArrayListPtr = arrayListStart + ArrayListHeader.LENGTH;
|
|
1621
1592
|
const newHeader = header.withPtr(nextArrayListPtr);
|
|
1622
|
-
|
|
1623
|
-
|
|
1593
|
+
writer.write(newHeader.toBytes());
|
|
1594
|
+
writer.write(arrayListIndexBlock);
|
|
1624
1595
|
}
|
|
1625
1596
|
} else if (db.header.tag === 2 /* ARRAY_LIST */) {
|
|
1626
1597
|
throw new ExpectedTxStartException;
|
|
1627
1598
|
}
|
|
1628
1599
|
const nextSlotPtr = new SlotPointer(position, new Slot(arrayListStart, 2 /* ARRAY_LIST */));
|
|
1629
|
-
|
|
1630
|
-
|
|
1600
|
+
db.core.seek(position);
|
|
1601
|
+
writer.write(nextSlotPtr.slot.toBytes());
|
|
1631
1602
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
1632
1603
|
}
|
|
1633
1604
|
default:
|
|
@@ -1642,7 +1613,7 @@ class ArrayListGet2 {
|
|
|
1642
1613
|
constructor(index) {
|
|
1643
1614
|
this.index = index;
|
|
1644
1615
|
}
|
|
1645
|
-
|
|
1616
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1646
1617
|
const tag = isTopLevel ? db.header.tag : slotPtr.slot.tag;
|
|
1647
1618
|
switch (tag) {
|
|
1648
1619
|
case 0 /* NONE */:
|
|
@@ -1654,10 +1625,10 @@ class ArrayListGet2 {
|
|
|
1654
1625
|
}
|
|
1655
1626
|
const nextArrayListStart = Number(slotPtr.slot.value);
|
|
1656
1627
|
let index = this.index;
|
|
1657
|
-
|
|
1628
|
+
db.core.seek(nextArrayListStart);
|
|
1658
1629
|
const reader = db.core.reader();
|
|
1659
1630
|
const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
|
|
1660
|
-
|
|
1631
|
+
reader.readFully(headerBytes);
|
|
1661
1632
|
const header = ArrayListHeader.fromBytes(headerBytes);
|
|
1662
1633
|
if (index >= header.size || index < -header.size) {
|
|
1663
1634
|
throw new KeyNotFoundException;
|
|
@@ -1665,14 +1636,14 @@ class ArrayListGet2 {
|
|
|
1665
1636
|
const key = index < 0 ? header.size - Math.abs(index) : index;
|
|
1666
1637
|
const lastKey = header.size - 1;
|
|
1667
1638
|
const shift = lastKey < SLOT_COUNT ? 0 : Math.floor(Math.log(lastKey) / Math.log(SLOT_COUNT));
|
|
1668
|
-
const finalSlotPtr =
|
|
1639
|
+
const finalSlotPtr = db.readArrayListSlot(header.ptr, key, shift, writeMode, isTopLevel);
|
|
1669
1640
|
return db.readSlotPointer(writeMode, path, pathI + 1, finalSlotPtr);
|
|
1670
1641
|
}
|
|
1671
1642
|
}
|
|
1672
1643
|
|
|
1673
1644
|
class ArrayListAppend {
|
|
1674
1645
|
kind = "ArrayListAppend";
|
|
1675
|
-
|
|
1646
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1676
1647
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1677
1648
|
throw new WriteNotAllowedException;
|
|
1678
1649
|
const tag = isTopLevel ? db.header.tag : slotPtr.slot.tag;
|
|
@@ -1680,22 +1651,22 @@ class ArrayListAppend {
|
|
|
1680
1651
|
throw new UnexpectedTagException;
|
|
1681
1652
|
const reader = db.core.reader();
|
|
1682
1653
|
const nextArrayListStart = Number(slotPtr.slot.value);
|
|
1683
|
-
|
|
1654
|
+
db.core.seek(nextArrayListStart);
|
|
1684
1655
|
const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
|
|
1685
|
-
|
|
1656
|
+
reader.readFully(headerBytes);
|
|
1686
1657
|
const origHeader = ArrayListHeader.fromBytes(headerBytes);
|
|
1687
|
-
const appendResult =
|
|
1688
|
-
const finalSlotPtr =
|
|
1658
|
+
const appendResult = db.readArrayListSlotAppend(origHeader, writeMode, isTopLevel);
|
|
1659
|
+
const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, appendResult.slotPtr);
|
|
1689
1660
|
const writer = db.core.writer();
|
|
1690
1661
|
if (isTopLevel) {
|
|
1691
|
-
|
|
1692
|
-
const fileSize =
|
|
1662
|
+
db.core.flush();
|
|
1663
|
+
const fileSize = db.core.length();
|
|
1693
1664
|
const header = new TopLevelArrayListHeader(fileSize, appendResult.header);
|
|
1694
|
-
|
|
1695
|
-
|
|
1665
|
+
db.core.seek(nextArrayListStart);
|
|
1666
|
+
writer.write(header.toBytes());
|
|
1696
1667
|
} else {
|
|
1697
|
-
|
|
1698
|
-
|
|
1668
|
+
db.core.seek(nextArrayListStart);
|
|
1669
|
+
writer.write(appendResult.header.toBytes());
|
|
1699
1670
|
}
|
|
1700
1671
|
return finalSlotPtr;
|
|
1701
1672
|
}
|
|
@@ -1707,29 +1678,29 @@ class ArrayListSlice {
|
|
|
1707
1678
|
constructor(size) {
|
|
1708
1679
|
this.size = size;
|
|
1709
1680
|
}
|
|
1710
|
-
|
|
1681
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1711
1682
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1712
1683
|
throw new WriteNotAllowedException;
|
|
1713
1684
|
if (slotPtr.slot.tag !== 2 /* ARRAY_LIST */)
|
|
1714
1685
|
throw new UnexpectedTagException;
|
|
1715
1686
|
const reader = db.core.reader();
|
|
1716
1687
|
const nextArrayListStart = Number(slotPtr.slot.value);
|
|
1717
|
-
|
|
1688
|
+
db.core.seek(nextArrayListStart);
|
|
1718
1689
|
const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
|
|
1719
|
-
|
|
1690
|
+
reader.readFully(headerBytes);
|
|
1720
1691
|
const origHeader = ArrayListHeader.fromBytes(headerBytes);
|
|
1721
|
-
const sliceHeader =
|
|
1722
|
-
const finalSlotPtr =
|
|
1692
|
+
const sliceHeader = db.readArrayListSlice(origHeader, this.size);
|
|
1693
|
+
const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, slotPtr);
|
|
1723
1694
|
const writer = db.core.writer();
|
|
1724
|
-
|
|
1725
|
-
|
|
1695
|
+
db.core.seek(nextArrayListStart);
|
|
1696
|
+
writer.write(sliceHeader.toBytes());
|
|
1726
1697
|
return finalSlotPtr;
|
|
1727
1698
|
}
|
|
1728
1699
|
}
|
|
1729
1700
|
|
|
1730
1701
|
class LinkedArrayListInit {
|
|
1731
1702
|
kind = "LinkedArrayListInit";
|
|
1732
|
-
|
|
1703
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1733
1704
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1734
1705
|
throw new WriteNotAllowedException;
|
|
1735
1706
|
if (isTopLevel)
|
|
@@ -1740,14 +1711,14 @@ class LinkedArrayListInit {
|
|
|
1740
1711
|
switch (slotPtr.slot.tag) {
|
|
1741
1712
|
case 0 /* NONE */: {
|
|
1742
1713
|
const writer = db.core.writer();
|
|
1743
|
-
const arrayListStart =
|
|
1744
|
-
|
|
1714
|
+
const arrayListStart = db.core.length();
|
|
1715
|
+
db.core.seek(arrayListStart);
|
|
1745
1716
|
const arrayListPtr = arrayListStart + LinkedArrayListHeader.LENGTH;
|
|
1746
|
-
|
|
1747
|
-
|
|
1717
|
+
writer.write(new LinkedArrayListHeader(0, arrayListPtr, 0).toBytes());
|
|
1718
|
+
writer.write(new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE));
|
|
1748
1719
|
const nextSlotPtr = new SlotPointer(position, new Slot(arrayListStart, 3 /* LINKED_ARRAY_LIST */));
|
|
1749
|
-
|
|
1750
|
-
|
|
1720
|
+
db.core.seek(position);
|
|
1721
|
+
writer.write(nextSlotPtr.slot.toBytes());
|
|
1751
1722
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
1752
1723
|
}
|
|
1753
1724
|
case 3 /* LINKED_ARRAY_LIST */: {
|
|
@@ -1756,26 +1727,26 @@ class LinkedArrayListInit {
|
|
|
1756
1727
|
let arrayListStart = Number(slotPtr.slot.value);
|
|
1757
1728
|
if (db.txStart !== null) {
|
|
1758
1729
|
if (arrayListStart < db.txStart) {
|
|
1759
|
-
|
|
1730
|
+
db.core.seek(arrayListStart);
|
|
1760
1731
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1761
|
-
|
|
1732
|
+
reader.readFully(headerBytes);
|
|
1762
1733
|
const header = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
1763
|
-
|
|
1734
|
+
db.core.seek(header.ptr);
|
|
1764
1735
|
const arrayListIndexBlock = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
|
|
1765
|
-
|
|
1766
|
-
arrayListStart =
|
|
1767
|
-
|
|
1736
|
+
reader.readFully(arrayListIndexBlock);
|
|
1737
|
+
arrayListStart = db.core.length();
|
|
1738
|
+
db.core.seek(arrayListStart);
|
|
1768
1739
|
const nextArrayListPtr = arrayListStart + LinkedArrayListHeader.LENGTH;
|
|
1769
1740
|
const newHeader = header.withPtr(nextArrayListPtr);
|
|
1770
|
-
|
|
1771
|
-
|
|
1741
|
+
writer.write(newHeader.toBytes());
|
|
1742
|
+
writer.write(arrayListIndexBlock);
|
|
1772
1743
|
}
|
|
1773
1744
|
} else if (db.header.tag === 2 /* ARRAY_LIST */) {
|
|
1774
1745
|
throw new ExpectedTxStartException;
|
|
1775
1746
|
}
|
|
1776
1747
|
const nextSlotPtr = new SlotPointer(position, new Slot(arrayListStart, 3 /* LINKED_ARRAY_LIST */));
|
|
1777
|
-
|
|
1778
|
-
|
|
1748
|
+
db.core.seek(position);
|
|
1749
|
+
writer.write(nextSlotPtr.slot.toBytes());
|
|
1779
1750
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
1780
1751
|
}
|
|
1781
1752
|
default:
|
|
@@ -1790,7 +1761,7 @@ class LinkedArrayListGet {
|
|
|
1790
1761
|
constructor(index) {
|
|
1791
1762
|
this.index = index;
|
|
1792
1763
|
}
|
|
1793
|
-
|
|
1764
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1794
1765
|
switch (slotPtr.slot.tag) {
|
|
1795
1766
|
case 0 /* NONE */:
|
|
1796
1767
|
throw new KeyNotFoundException;
|
|
@@ -1800,38 +1771,38 @@ class LinkedArrayListGet {
|
|
|
1800
1771
|
throw new UnexpectedTagException;
|
|
1801
1772
|
}
|
|
1802
1773
|
let index = this.index;
|
|
1803
|
-
|
|
1774
|
+
db.core.seek(Number(slotPtr.slot.value));
|
|
1804
1775
|
const reader = db.core.reader();
|
|
1805
1776
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1806
|
-
|
|
1777
|
+
reader.readFully(headerBytes);
|
|
1807
1778
|
const header = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
1808
1779
|
if (index >= header.size || index < -header.size) {
|
|
1809
1780
|
throw new KeyNotFoundException;
|
|
1810
1781
|
}
|
|
1811
1782
|
const key = index < 0 ? header.size - Math.abs(index) : index;
|
|
1812
|
-
const finalSlotPtr =
|
|
1783
|
+
const finalSlotPtr = db.readLinkedArrayListSlot(header.ptr, key, header.shift, writeMode, isTopLevel);
|
|
1813
1784
|
return db.readSlotPointer(writeMode, path, pathI + 1, finalSlotPtr.slotPtr);
|
|
1814
1785
|
}
|
|
1815
1786
|
}
|
|
1816
1787
|
|
|
1817
1788
|
class LinkedArrayListAppend {
|
|
1818
1789
|
kind = "LinkedArrayListAppend";
|
|
1819
|
-
|
|
1790
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1820
1791
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1821
1792
|
throw new WriteNotAllowedException;
|
|
1822
1793
|
if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
|
|
1823
1794
|
throw new UnexpectedTagException;
|
|
1824
1795
|
const reader = db.core.reader();
|
|
1825
1796
|
const nextArrayListStart = Number(slotPtr.slot.value);
|
|
1826
|
-
|
|
1797
|
+
db.core.seek(nextArrayListStart);
|
|
1827
1798
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1828
|
-
|
|
1799
|
+
reader.readFully(headerBytes);
|
|
1829
1800
|
const origHeader = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
1830
|
-
const appendResult =
|
|
1831
|
-
const finalSlotPtr =
|
|
1801
|
+
const appendResult = db.readLinkedArrayListSlotAppend(origHeader, writeMode, isTopLevel);
|
|
1802
|
+
const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, appendResult.slotPtr.slotPtr);
|
|
1832
1803
|
const writer = db.core.writer();
|
|
1833
|
-
|
|
1834
|
-
|
|
1804
|
+
db.core.seek(nextArrayListStart);
|
|
1805
|
+
writer.write(appendResult.header.toBytes());
|
|
1835
1806
|
return finalSlotPtr;
|
|
1836
1807
|
}
|
|
1837
1808
|
}
|
|
@@ -1844,22 +1815,22 @@ class LinkedArrayListSlice {
|
|
|
1844
1815
|
this.offset = offset;
|
|
1845
1816
|
this.size = size;
|
|
1846
1817
|
}
|
|
1847
|
-
|
|
1818
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1848
1819
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1849
1820
|
throw new WriteNotAllowedException;
|
|
1850
1821
|
if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
|
|
1851
1822
|
throw new UnexpectedTagException;
|
|
1852
1823
|
const reader = db.core.reader();
|
|
1853
1824
|
const nextArrayListStart = Number(slotPtr.slot.value);
|
|
1854
|
-
|
|
1825
|
+
db.core.seek(nextArrayListStart);
|
|
1855
1826
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1856
|
-
|
|
1827
|
+
reader.readFully(headerBytes);
|
|
1857
1828
|
const origHeader = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
1858
|
-
const sliceHeader =
|
|
1859
|
-
const finalSlotPtr =
|
|
1829
|
+
const sliceHeader = db.readLinkedArrayListSlice(origHeader, this.offset, this.size);
|
|
1830
|
+
const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, slotPtr);
|
|
1860
1831
|
const writer = db.core.writer();
|
|
1861
|
-
|
|
1862
|
-
|
|
1832
|
+
db.core.seek(nextArrayListStart);
|
|
1833
|
+
writer.write(sliceHeader.toBytes());
|
|
1863
1834
|
return finalSlotPtr;
|
|
1864
1835
|
}
|
|
1865
1836
|
}
|
|
@@ -1870,7 +1841,7 @@ class LinkedArrayListConcat {
|
|
|
1870
1841
|
constructor(list) {
|
|
1871
1842
|
this.list = list;
|
|
1872
1843
|
}
|
|
1873
|
-
|
|
1844
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1874
1845
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1875
1846
|
throw new WriteNotAllowedException;
|
|
1876
1847
|
if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
|
|
@@ -1879,19 +1850,19 @@ class LinkedArrayListConcat {
|
|
|
1879
1850
|
throw new UnexpectedTagException;
|
|
1880
1851
|
const reader = db.core.reader();
|
|
1881
1852
|
const nextArrayListStart = Number(slotPtr.slot.value);
|
|
1882
|
-
|
|
1853
|
+
db.core.seek(nextArrayListStart);
|
|
1883
1854
|
const headerBytesA = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1884
|
-
|
|
1855
|
+
reader.readFully(headerBytesA);
|
|
1885
1856
|
const headerA = LinkedArrayListHeader.fromBytes(headerBytesA);
|
|
1886
|
-
|
|
1857
|
+
db.core.seek(Number(this.list.value));
|
|
1887
1858
|
const headerBytesB = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1888
|
-
|
|
1859
|
+
reader.readFully(headerBytesB);
|
|
1889
1860
|
const headerB = LinkedArrayListHeader.fromBytes(headerBytesB);
|
|
1890
|
-
const concatHeader =
|
|
1891
|
-
const finalSlotPtr =
|
|
1861
|
+
const concatHeader = db.readLinkedArrayListConcat(headerA, headerB);
|
|
1862
|
+
const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, slotPtr);
|
|
1892
1863
|
const writer = db.core.writer();
|
|
1893
|
-
|
|
1894
|
-
|
|
1864
|
+
db.core.seek(nextArrayListStart);
|
|
1865
|
+
writer.write(concatHeader.toBytes());
|
|
1895
1866
|
return finalSlotPtr;
|
|
1896
1867
|
}
|
|
1897
1868
|
}
|
|
@@ -1902,31 +1873,31 @@ class LinkedArrayListInsert {
|
|
|
1902
1873
|
constructor(index) {
|
|
1903
1874
|
this.index = index;
|
|
1904
1875
|
}
|
|
1905
|
-
|
|
1876
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1906
1877
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1907
1878
|
throw new WriteNotAllowedException;
|
|
1908
1879
|
if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
|
|
1909
1880
|
throw new UnexpectedTagException;
|
|
1910
1881
|
const reader = db.core.reader();
|
|
1911
1882
|
const nextArrayListStart = Number(slotPtr.slot.value);
|
|
1912
|
-
|
|
1883
|
+
db.core.seek(nextArrayListStart);
|
|
1913
1884
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1914
|
-
|
|
1885
|
+
reader.readFully(headerBytes);
|
|
1915
1886
|
const origHeader = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
1916
1887
|
let index = this.index;
|
|
1917
1888
|
if (index >= origHeader.size || index < -origHeader.size) {
|
|
1918
1889
|
throw new KeyNotFoundException;
|
|
1919
1890
|
}
|
|
1920
1891
|
const key = index < 0 ? origHeader.size - Math.abs(index) : index;
|
|
1921
|
-
const headerA =
|
|
1922
|
-
const headerB =
|
|
1923
|
-
const appendResult =
|
|
1924
|
-
const concatHeader =
|
|
1925
|
-
const nextSlotPtr =
|
|
1926
|
-
const finalSlotPtr =
|
|
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);
|
|
1927
1898
|
const writer = db.core.writer();
|
|
1928
|
-
|
|
1929
|
-
|
|
1899
|
+
db.core.seek(nextArrayListStart);
|
|
1900
|
+
writer.write(concatHeader.toBytes());
|
|
1930
1901
|
return finalSlotPtr;
|
|
1931
1902
|
}
|
|
1932
1903
|
}
|
|
@@ -1937,30 +1908,30 @@ class LinkedArrayListRemove {
|
|
|
1937
1908
|
constructor(index) {
|
|
1938
1909
|
this.index = index;
|
|
1939
1910
|
}
|
|
1940
|
-
|
|
1911
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1941
1912
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1942
1913
|
throw new WriteNotAllowedException;
|
|
1943
1914
|
if (slotPtr.slot.tag !== 3 /* LINKED_ARRAY_LIST */)
|
|
1944
1915
|
throw new UnexpectedTagException;
|
|
1945
1916
|
const reader = db.core.reader();
|
|
1946
1917
|
const nextArrayListStart = Number(slotPtr.slot.value);
|
|
1947
|
-
|
|
1918
|
+
db.core.seek(nextArrayListStart);
|
|
1948
1919
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
1949
|
-
|
|
1920
|
+
reader.readFully(headerBytes);
|
|
1950
1921
|
const origHeader = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
1951
1922
|
let index = this.index;
|
|
1952
1923
|
if (index >= origHeader.size || index < -origHeader.size) {
|
|
1953
1924
|
throw new KeyNotFoundException;
|
|
1954
1925
|
}
|
|
1955
1926
|
const key = index < 0 ? origHeader.size - Math.abs(index) : index;
|
|
1956
|
-
const headerA =
|
|
1957
|
-
const headerB =
|
|
1958
|
-
const concatHeader =
|
|
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);
|
|
1959
1930
|
const nextSlotPtr = new SlotPointer(concatHeader.ptr, new Slot(nextArrayListStart, 3 /* LINKED_ARRAY_LIST */));
|
|
1960
|
-
const finalSlotPtr =
|
|
1931
|
+
const finalSlotPtr = db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
1961
1932
|
const writer = db.core.writer();
|
|
1962
|
-
|
|
1963
|
-
|
|
1933
|
+
db.core.seek(nextArrayListStart);
|
|
1934
|
+
writer.write(concatHeader.toBytes());
|
|
1964
1935
|
return finalSlotPtr;
|
|
1965
1936
|
}
|
|
1966
1937
|
}
|
|
@@ -1973,21 +1944,21 @@ class HashMapInit {
|
|
|
1973
1944
|
this.counted = counted;
|
|
1974
1945
|
this.set = set;
|
|
1975
1946
|
}
|
|
1976
|
-
|
|
1947
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
1977
1948
|
if (writeMode === 0 /* READ_ONLY */)
|
|
1978
1949
|
throw new WriteNotAllowedException;
|
|
1979
1950
|
const tag = this.counted ? this.set ? 13 /* COUNTED_HASH_SET */ : 12 /* COUNTED_HASH_MAP */ : this.set ? 11 /* HASH_SET */ : 4 /* HASH_MAP */;
|
|
1980
1951
|
if (isTopLevel) {
|
|
1981
1952
|
const writer = db.core.writer();
|
|
1982
1953
|
if (db.header.tag === 0 /* NONE */) {
|
|
1983
|
-
|
|
1954
|
+
db.core.seek(Header.LENGTH);
|
|
1984
1955
|
if (this.counted) {
|
|
1985
|
-
|
|
1956
|
+
writer.writeLong(0);
|
|
1986
1957
|
}
|
|
1987
|
-
|
|
1988
|
-
|
|
1958
|
+
writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
|
|
1959
|
+
db.core.seek(0);
|
|
1989
1960
|
db.header = db.header.withTag(tag);
|
|
1990
|
-
|
|
1961
|
+
writer.write(db.header.toBytes());
|
|
1991
1962
|
}
|
|
1992
1963
|
const nextSlotPtr = slotPtr.withSlot(slotPtr.slot.withTag(tag));
|
|
1993
1964
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
@@ -1998,15 +1969,15 @@ class HashMapInit {
|
|
|
1998
1969
|
switch (slotPtr.slot.tag) {
|
|
1999
1970
|
case 0 /* NONE */: {
|
|
2000
1971
|
const writer = db.core.writer();
|
|
2001
|
-
const mapStart =
|
|
2002
|
-
|
|
1972
|
+
const mapStart = db.core.length();
|
|
1973
|
+
db.core.seek(mapStart);
|
|
2003
1974
|
if (this.counted) {
|
|
2004
|
-
|
|
1975
|
+
writer.writeLong(0);
|
|
2005
1976
|
}
|
|
2006
|
-
|
|
1977
|
+
writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
|
|
2007
1978
|
const nextSlotPtr = new SlotPointer(position, new Slot(mapStart, tag));
|
|
2008
|
-
|
|
2009
|
-
|
|
1979
|
+
db.core.seek(position);
|
|
1980
|
+
writer.write(nextSlotPtr.slot.toBytes());
|
|
2010
1981
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
2011
1982
|
}
|
|
2012
1983
|
case 4 /* HASH_MAP */:
|
|
@@ -2035,26 +2006,26 @@ class HashMapInit {
|
|
|
2035
2006
|
let mapStart = Number(slotPtr.slot.value);
|
|
2036
2007
|
if (db.txStart !== null) {
|
|
2037
2008
|
if (mapStart < db.txStart) {
|
|
2038
|
-
|
|
2009
|
+
db.core.seek(mapStart);
|
|
2039
2010
|
let mapCountMaybe = null;
|
|
2040
2011
|
if (this.counted) {
|
|
2041
|
-
mapCountMaybe =
|
|
2012
|
+
mapCountMaybe = reader.readLong();
|
|
2042
2013
|
}
|
|
2043
2014
|
const mapIndexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
|
|
2044
|
-
|
|
2045
|
-
mapStart =
|
|
2046
|
-
|
|
2015
|
+
reader.readFully(mapIndexBlock);
|
|
2016
|
+
mapStart = db.core.length();
|
|
2017
|
+
db.core.seek(mapStart);
|
|
2047
2018
|
if (mapCountMaybe !== null) {
|
|
2048
|
-
|
|
2019
|
+
writer.writeLong(mapCountMaybe);
|
|
2049
2020
|
}
|
|
2050
|
-
|
|
2021
|
+
writer.write(mapIndexBlock);
|
|
2051
2022
|
}
|
|
2052
2023
|
} else if (db.header.tag === 2 /* ARRAY_LIST */) {
|
|
2053
2024
|
throw new ExpectedTxStartException;
|
|
2054
2025
|
}
|
|
2055
2026
|
const nextSlotPtr = new SlotPointer(position, new Slot(mapStart, tag));
|
|
2056
|
-
|
|
2057
|
-
|
|
2027
|
+
db.core.seek(position);
|
|
2028
|
+
writer.write(nextSlotPtr.slot.toBytes());
|
|
2058
2029
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
2059
2030
|
}
|
|
2060
2031
|
default:
|
|
@@ -2069,7 +2040,7 @@ class HashMapGet {
|
|
|
2069
2040
|
constructor(target) {
|
|
2070
2041
|
this.target = target;
|
|
2071
2042
|
}
|
|
2072
|
-
|
|
2043
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
2073
2044
|
let counted = false;
|
|
2074
2045
|
switch (slotPtr.slot.tag) {
|
|
2075
2046
|
case 0 /* NONE */:
|
|
@@ -2086,14 +2057,14 @@ class HashMapGet {
|
|
|
2086
2057
|
}
|
|
2087
2058
|
const indexPos = counted ? Number(slotPtr.slot.value) + 8 : Number(slotPtr.slot.value);
|
|
2088
2059
|
const hash = db.checkHash(this.target);
|
|
2089
|
-
const res =
|
|
2060
|
+
const res = db.readMapSlot(indexPos, hash, 0, writeMode, isTopLevel, this.target);
|
|
2090
2061
|
if (writeMode === 1 /* READ_WRITE */ && counted && res.isEmpty) {
|
|
2091
2062
|
const reader = db.core.reader();
|
|
2092
2063
|
const writer = db.core.writer();
|
|
2093
|
-
|
|
2094
|
-
const mapCount =
|
|
2095
|
-
|
|
2096
|
-
|
|
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);
|
|
2097
2068
|
}
|
|
2098
2069
|
return db.readSlotPointer(writeMode, path, pathI + 1, res.slotPtr);
|
|
2099
2070
|
}
|
|
@@ -2105,7 +2076,7 @@ class HashMapRemove {
|
|
|
2105
2076
|
constructor(hash) {
|
|
2106
2077
|
this.hash = hash;
|
|
2107
2078
|
}
|
|
2108
|
-
|
|
2079
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
2109
2080
|
if (writeMode === 0 /* READ_ONLY */)
|
|
2110
2081
|
throw new WriteNotAllowedException;
|
|
2111
2082
|
let counted = false;
|
|
@@ -2126,7 +2097,7 @@ class HashMapRemove {
|
|
|
2126
2097
|
const hash = db.checkHashBytes(this.hash);
|
|
2127
2098
|
let keyFound = true;
|
|
2128
2099
|
try {
|
|
2129
|
-
|
|
2100
|
+
db.removeMapSlot(indexPos, hash, 0, isTopLevel);
|
|
2130
2101
|
} catch (e) {
|
|
2131
2102
|
if (e instanceof KeyNotFoundException) {
|
|
2132
2103
|
keyFound = false;
|
|
@@ -2137,10 +2108,10 @@ class HashMapRemove {
|
|
|
2137
2108
|
if (writeMode === 1 /* READ_WRITE */ && counted && keyFound) {
|
|
2138
2109
|
const reader = db.core.reader();
|
|
2139
2110
|
const writer = db.core.writer();
|
|
2140
|
-
|
|
2141
|
-
const mapCount =
|
|
2142
|
-
|
|
2143
|
-
|
|
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);
|
|
2144
2115
|
}
|
|
2145
2116
|
if (!keyFound)
|
|
2146
2117
|
throw new KeyNotFoundException;
|
|
@@ -2154,7 +2125,7 @@ class WriteData {
|
|
|
2154
2125
|
constructor(data) {
|
|
2155
2126
|
this.data = data;
|
|
2156
2127
|
}
|
|
2157
|
-
|
|
2128
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
2158
2129
|
if (writeMode === 0 /* READ_ONLY */)
|
|
2159
2130
|
throw new WriteNotAllowedException;
|
|
2160
2131
|
if (slotPtr.position === null)
|
|
@@ -2189,10 +2160,10 @@ class WriteData {
|
|
|
2189
2160
|
slot = new Slot(longValue, 7 /* SHORT_BYTES */, data.formatTag !== null);
|
|
2190
2161
|
} else {
|
|
2191
2162
|
const nextCursor = new WriteCursor(slotPtr, db);
|
|
2192
|
-
const cursorWriter =
|
|
2163
|
+
const cursorWriter = nextCursor.writer();
|
|
2193
2164
|
cursorWriter.formatTag = data.formatTag;
|
|
2194
|
-
|
|
2195
|
-
|
|
2165
|
+
cursorWriter.write(data.value);
|
|
2166
|
+
cursorWriter.finish();
|
|
2196
2167
|
slot = cursorWriter.slot;
|
|
2197
2168
|
}
|
|
2198
2169
|
} else {
|
|
@@ -2201,8 +2172,8 @@ class WriteData {
|
|
|
2201
2172
|
if (slot.tag === 0 /* NONE */) {
|
|
2202
2173
|
slot = slot.withFull(true);
|
|
2203
2174
|
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2175
|
+
db.core.seek(position);
|
|
2176
|
+
writer.write(slot.toBytes());
|
|
2206
2177
|
const nextSlotPtr = new SlotPointer(slotPtr.position, slot);
|
|
2207
2178
|
return db.readSlotPointer(writeMode, path, pathI + 1, nextSlotPtr);
|
|
2208
2179
|
}
|
|
@@ -2214,17 +2185,17 @@ class Context {
|
|
|
2214
2185
|
constructor(fn) {
|
|
2215
2186
|
this.fn = fn;
|
|
2216
2187
|
}
|
|
2217
|
-
|
|
2188
|
+
readSlotPointer(db, isTopLevel, writeMode, path, pathI, slotPtr) {
|
|
2218
2189
|
if (writeMode === 0 /* READ_ONLY */)
|
|
2219
2190
|
throw new WriteNotAllowedException;
|
|
2220
2191
|
if (pathI !== path.length - 1)
|
|
2221
2192
|
throw new PathPartMustBeAtEndException;
|
|
2222
2193
|
const nextCursor = new WriteCursor(slotPtr, db);
|
|
2223
2194
|
try {
|
|
2224
|
-
|
|
2195
|
+
this.fn(nextCursor);
|
|
2225
2196
|
} catch (e) {
|
|
2226
2197
|
try {
|
|
2227
|
-
|
|
2198
|
+
db.truncate();
|
|
2228
2199
|
} catch (_) {}
|
|
2229
2200
|
throw e;
|
|
2230
2201
|
}
|
|
@@ -2289,88 +2260,88 @@ class Database3 {
|
|
|
2289
2260
|
constructor(core, hasher) {
|
|
2290
2261
|
this.core = core;
|
|
2291
2262
|
this.hasher = hasher;
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
db.header = new Header(hasher.id, hasher.digestLength, VERSION, 0 /* NONE */, MAGIC_NUMBER);
|
|
2298
|
-
await db.header.write(core);
|
|
2299
|
-
await core.flush();
|
|
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();
|
|
2300
2268
|
} else {
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
if (
|
|
2269
|
+
this.header = Header.read(core);
|
|
2270
|
+
this.header.validate();
|
|
2271
|
+
if (this.header.hashSize !== hasher.digestLength) {
|
|
2304
2272
|
throw new InvalidHashSizeException;
|
|
2305
2273
|
}
|
|
2306
|
-
|
|
2274
|
+
this.truncate();
|
|
2307
2275
|
}
|
|
2308
|
-
return db;
|
|
2309
2276
|
}
|
|
2310
2277
|
rootCursor() {
|
|
2278
|
+
if (this.header.tag === 0 /* NONE */) {
|
|
2279
|
+
this.core.seek(0);
|
|
2280
|
+
this.header = Header.read(this.core);
|
|
2281
|
+
}
|
|
2311
2282
|
return new WriteCursor(new SlotPointer(null, new Slot(Header.LENGTH, this.header.tag)), this);
|
|
2312
2283
|
}
|
|
2313
|
-
|
|
2284
|
+
freeze() {
|
|
2314
2285
|
if (this.txStart !== null) {
|
|
2315
|
-
this.txStart =
|
|
2286
|
+
this.txStart = this.core.length();
|
|
2316
2287
|
} else {
|
|
2317
2288
|
throw new ExpectedTxStartException;
|
|
2318
2289
|
}
|
|
2319
2290
|
}
|
|
2320
|
-
|
|
2291
|
+
compact(targetCore) {
|
|
2321
2292
|
const offsetMap = new Map;
|
|
2322
2293
|
const hasher = new Hasher(this.hasher.algorithm, this.header.hashId);
|
|
2323
|
-
const target =
|
|
2294
|
+
const target = new Database3(targetCore, hasher);
|
|
2324
2295
|
if (this.header.tag === 0 /* NONE */)
|
|
2325
2296
|
return target;
|
|
2326
2297
|
if (this.header.tag !== 2 /* ARRAY_LIST */)
|
|
2327
2298
|
throw new UnexpectedTagException;
|
|
2328
|
-
|
|
2299
|
+
this.core.seek(Header.LENGTH);
|
|
2329
2300
|
const sourceReader = this.core.reader();
|
|
2330
2301
|
const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
|
|
2331
|
-
|
|
2302
|
+
sourceReader.readFully(headerBytes);
|
|
2332
2303
|
const sourceHeader = ArrayListHeader.fromBytes(headerBytes);
|
|
2333
2304
|
if (sourceHeader.size === 0)
|
|
2334
2305
|
return target;
|
|
2335
2306
|
const lastKey = sourceHeader.size - 1;
|
|
2336
2307
|
const shift = lastKey < SLOT_COUNT ? 0 : Math.floor(Math.log(lastKey) / Math.log(SLOT_COUNT));
|
|
2337
|
-
const lastSlotPtr =
|
|
2308
|
+
const lastSlotPtr = this.readArrayListSlot(sourceHeader.ptr, lastKey, shift, 0 /* READ_ONLY */, true);
|
|
2338
2309
|
const momentSlot = lastSlotPtr.slot;
|
|
2339
2310
|
const targetWriter = targetCore.writer();
|
|
2340
|
-
|
|
2311
|
+
targetCore.seek(Header.LENGTH);
|
|
2341
2312
|
const targetArrayListPtr = Header.LENGTH + TopLevelArrayListHeader.LENGTH;
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
const remappedMoment =
|
|
2345
|
-
|
|
2346
|
-
|
|
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());
|
|
2347
2318
|
target.header = target.header.withTag(2 /* ARRAY_LIST */);
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
const fileSize =
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
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();
|
|
2355
2326
|
return target;
|
|
2356
2327
|
}
|
|
2357
|
-
|
|
2328
|
+
truncate() {
|
|
2358
2329
|
if (this.header.tag !== 2 /* ARRAY_LIST */)
|
|
2359
2330
|
return;
|
|
2360
2331
|
const rootCursor = this.rootCursor();
|
|
2361
|
-
const listSize =
|
|
2332
|
+
const listSize = rootCursor.count();
|
|
2362
2333
|
if (listSize === 0)
|
|
2363
2334
|
return;
|
|
2364
|
-
|
|
2335
|
+
this.core.seek(Header.LENGTH + ArrayListHeader.LENGTH);
|
|
2365
2336
|
const reader = this.core.reader();
|
|
2366
|
-
const headerFileSize =
|
|
2337
|
+
const headerFileSize = reader.readLong();
|
|
2367
2338
|
if (headerFileSize === 0)
|
|
2368
2339
|
return;
|
|
2369
|
-
const fileSize =
|
|
2340
|
+
const fileSize = this.core.length();
|
|
2370
2341
|
if (fileSize === headerFileSize)
|
|
2371
2342
|
return;
|
|
2372
2343
|
try {
|
|
2373
|
-
|
|
2344
|
+
this.core.setLength(headerFileSize);
|
|
2374
2345
|
} catch (_) {}
|
|
2375
2346
|
}
|
|
2376
2347
|
checkHashBytes(hash) {
|
|
@@ -2382,7 +2353,7 @@ class Database3 {
|
|
|
2382
2353
|
checkHash(target) {
|
|
2383
2354
|
return this.checkHashBytes(target.hash);
|
|
2384
2355
|
}
|
|
2385
|
-
|
|
2356
|
+
readSlotPointer(writeMode, path, pathI, slotPtr) {
|
|
2386
2357
|
if (pathI === path.length) {
|
|
2387
2358
|
if (writeMode === 0 /* READ_ONLY */ && slotPtr.slot.tag === 0 /* NONE */) {
|
|
2388
2359
|
throw new KeyNotFoundException;
|
|
@@ -2393,17 +2364,17 @@ class Database3 {
|
|
|
2393
2364
|
const isTopLevel = slotPtr.slot.value === BigInt(Header.LENGTH);
|
|
2394
2365
|
const isTxStart = isTopLevel && this.header.tag === 2 /* ARRAY_LIST */ && this.txStart === null;
|
|
2395
2366
|
if (isTxStart) {
|
|
2396
|
-
this.txStart =
|
|
2367
|
+
this.txStart = this.core.length();
|
|
2397
2368
|
}
|
|
2398
2369
|
try {
|
|
2399
|
-
return
|
|
2370
|
+
return part.readSlotPointer(this, isTopLevel, writeMode, path, pathI, slotPtr);
|
|
2400
2371
|
} finally {
|
|
2401
2372
|
if (isTxStart) {
|
|
2402
2373
|
this.txStart = null;
|
|
2403
2374
|
}
|
|
2404
2375
|
}
|
|
2405
2376
|
}
|
|
2406
|
-
|
|
2377
|
+
readMapSlot(indexPos, keyHash, keyOffset, writeMode, isTopLevel, target) {
|
|
2407
2378
|
if (keyOffset > this.header.hashSize * 8 / BIT_COUNT) {
|
|
2408
2379
|
throw new KeyOffsetExceededException;
|
|
2409
2380
|
}
|
|
@@ -2411,9 +2382,9 @@ class Database3 {
|
|
|
2411
2382
|
const writer = this.core.writer();
|
|
2412
2383
|
const i = Number(bigIntShiftRight(keyHash, keyOffset * BIT_COUNT) & MASK);
|
|
2413
2384
|
const slotPos = indexPos + Slot.LENGTH * i;
|
|
2414
|
-
|
|
2385
|
+
this.core.seek(slotPos);
|
|
2415
2386
|
const slotBytes = new Uint8Array(Slot.LENGTH);
|
|
2416
|
-
|
|
2387
|
+
reader.readFully(slotBytes);
|
|
2417
2388
|
const slot = Slot.fromBytes(slotBytes);
|
|
2418
2389
|
const ptr = Number(slot.value);
|
|
2419
2390
|
switch (slot.tag) {
|
|
@@ -2422,15 +2393,15 @@ class Database3 {
|
|
|
2422
2393
|
case 0 /* READ_ONLY */:
|
|
2423
2394
|
throw new KeyNotFoundException;
|
|
2424
2395
|
case 1 /* READ_WRITE */: {
|
|
2425
|
-
const hashPos =
|
|
2426
|
-
|
|
2396
|
+
const hashPos = this.core.length();
|
|
2397
|
+
this.core.seek(hashPos);
|
|
2427
2398
|
const keySlotPos = hashPos + this.header.hashSize;
|
|
2428
2399
|
const valueSlotPos = keySlotPos + Slot.LENGTH;
|
|
2429
2400
|
const kvPair = new KeyValuePair(new Slot, new Slot, keyHash);
|
|
2430
|
-
|
|
2401
|
+
writer.write(kvPair.toBytes());
|
|
2431
2402
|
const nextSlot = new Slot(hashPos, 5 /* KV_PAIR */);
|
|
2432
|
-
|
|
2433
|
-
|
|
2403
|
+
this.core.seek(slotPos);
|
|
2404
|
+
writer.write(nextSlot.toBytes());
|
|
2434
2405
|
let nextSlotPtr;
|
|
2435
2406
|
if (target.kind === "kv_pair") {
|
|
2436
2407
|
nextSlotPtr = new SlotPointer(slotPos, nextSlot);
|
|
@@ -2450,14 +2421,14 @@ class Database3 {
|
|
|
2450
2421
|
if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
|
|
2451
2422
|
if (this.txStart !== null) {
|
|
2452
2423
|
if (nextPtr < this.txStart) {
|
|
2453
|
-
|
|
2424
|
+
this.core.seek(ptr);
|
|
2454
2425
|
const indexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
|
|
2455
|
-
|
|
2456
|
-
nextPtr =
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
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());
|
|
2461
2432
|
}
|
|
2462
2433
|
} else if (this.header.tag === 2 /* ARRAY_LIST */) {
|
|
2463
2434
|
throw new ExpectedTxStartException;
|
|
@@ -2466,22 +2437,22 @@ class Database3 {
|
|
|
2466
2437
|
return this.readMapSlot(nextPtr, keyHash, keyOffset + 1, writeMode, isTopLevel, target);
|
|
2467
2438
|
}
|
|
2468
2439
|
case 5 /* KV_PAIR */: {
|
|
2469
|
-
|
|
2440
|
+
this.core.seek(ptr);
|
|
2470
2441
|
const kvPairBytes = new Uint8Array(KeyValuePair.length(this.header.hashSize));
|
|
2471
|
-
|
|
2442
|
+
reader.readFully(kvPairBytes);
|
|
2472
2443
|
const kvPair = KeyValuePair.fromBytes(kvPairBytes, this.header.hashSize);
|
|
2473
2444
|
if (arraysEqual(kvPair.hash, keyHash)) {
|
|
2474
2445
|
if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
|
|
2475
2446
|
if (this.txStart !== null) {
|
|
2476
2447
|
if (ptr < this.txStart) {
|
|
2477
|
-
const hashPos =
|
|
2478
|
-
|
|
2448
|
+
const hashPos = this.core.length();
|
|
2449
|
+
this.core.seek(hashPos);
|
|
2479
2450
|
const keySlotPos2 = hashPos + this.header.hashSize;
|
|
2480
2451
|
const valueSlotPos2 = keySlotPos2 + Slot.LENGTH;
|
|
2481
|
-
|
|
2452
|
+
writer.write(kvPair.toBytes());
|
|
2482
2453
|
const nextSlot = new Slot(hashPos, 5 /* KV_PAIR */);
|
|
2483
|
-
|
|
2484
|
-
|
|
2454
|
+
this.core.seek(slotPos);
|
|
2455
|
+
writer.write(nextSlot.toBytes());
|
|
2485
2456
|
let nextSlotPtr2;
|
|
2486
2457
|
if (target.kind === "kv_pair") {
|
|
2487
2458
|
nextSlotPtr2 = new SlotPointer(slotPos, nextSlot);
|
|
@@ -2516,14 +2487,14 @@ class Database3 {
|
|
|
2516
2487
|
throw new KeyOffsetExceededException;
|
|
2517
2488
|
}
|
|
2518
2489
|
const nextI = Number(bigIntShiftRight(kvPair.hash, (keyOffset + 1) * BIT_COUNT) & MASK);
|
|
2519
|
-
const nextIndexPos =
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
const res =
|
|
2525
|
-
|
|
2526
|
-
|
|
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());
|
|
2527
2498
|
return res;
|
|
2528
2499
|
}
|
|
2529
2500
|
default:
|
|
@@ -2535,16 +2506,16 @@ class Database3 {
|
|
|
2535
2506
|
throw new UnexpectedTagException;
|
|
2536
2507
|
}
|
|
2537
2508
|
}
|
|
2538
|
-
|
|
2509
|
+
removeMapSlot(indexPos, keyHash, keyOffset, isTopLevel) {
|
|
2539
2510
|
if (keyOffset > this.header.hashSize * 8 / BIT_COUNT) {
|
|
2540
2511
|
throw new KeyOffsetExceededException;
|
|
2541
2512
|
}
|
|
2542
2513
|
const reader = this.core.reader();
|
|
2543
2514
|
const writer = this.core.writer();
|
|
2544
2515
|
const slotBlock = new Array(SLOT_COUNT);
|
|
2545
|
-
|
|
2516
|
+
this.core.seek(indexPos);
|
|
2546
2517
|
const indexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
|
|
2547
|
-
|
|
2518
|
+
reader.readFully(indexBlock);
|
|
2548
2519
|
for (let i2 = 0;i2 < SLOT_COUNT; i2++) {
|
|
2549
2520
|
const slotBytes = indexBlock.slice(i2 * Slot.LENGTH, (i2 + 1) * Slot.LENGTH);
|
|
2550
2521
|
slotBlock[i2] = Slot.fromBytes(slotBytes);
|
|
@@ -2557,12 +2528,12 @@ class Database3 {
|
|
|
2557
2528
|
case 0 /* NONE */:
|
|
2558
2529
|
throw new KeyNotFoundException;
|
|
2559
2530
|
case 1 /* INDEX */:
|
|
2560
|
-
nextSlot =
|
|
2531
|
+
nextSlot = this.removeMapSlot(Number(slot.value), keyHash, keyOffset + 1, isTopLevel);
|
|
2561
2532
|
break;
|
|
2562
2533
|
case 5 /* KV_PAIR */: {
|
|
2563
|
-
|
|
2534
|
+
this.core.seek(Number(slot.value));
|
|
2564
2535
|
const kvPairBytes = new Uint8Array(KeyValuePair.length(this.header.hashSize));
|
|
2565
|
-
|
|
2536
|
+
reader.readFully(kvPairBytes);
|
|
2566
2537
|
const kvPair = KeyValuePair.fromBytes(kvPairBytes, this.header.hashSize);
|
|
2567
2538
|
if (arraysEqual(kvPair.hash, keyHash)) {
|
|
2568
2539
|
nextSlot = new Slot;
|
|
@@ -2575,8 +2546,8 @@ class Database3 {
|
|
|
2575
2546
|
throw new UnexpectedTagException;
|
|
2576
2547
|
}
|
|
2577
2548
|
if (keyOffset === 0) {
|
|
2578
|
-
|
|
2579
|
-
|
|
2549
|
+
this.core.seek(slotPos);
|
|
2550
|
+
writer.write(nextSlot.toBytes());
|
|
2580
2551
|
return new Slot(indexPos, 1 /* INDEX */);
|
|
2581
2552
|
}
|
|
2582
2553
|
let slotToReturnMaybe = new Slot;
|
|
@@ -2604,48 +2575,48 @@ class Database3 {
|
|
|
2604
2575
|
if (!isTopLevel) {
|
|
2605
2576
|
if (this.txStart !== null) {
|
|
2606
2577
|
if (indexPos < this.txStart) {
|
|
2607
|
-
const nextIndexPos =
|
|
2608
|
-
|
|
2609
|
-
|
|
2578
|
+
const nextIndexPos = this.core.length();
|
|
2579
|
+
this.core.seek(nextIndexPos);
|
|
2580
|
+
writer.write(indexBlock);
|
|
2610
2581
|
const nextSlotPos = nextIndexPos + Slot.LENGTH * i;
|
|
2611
|
-
|
|
2612
|
-
|
|
2582
|
+
this.core.seek(nextSlotPos);
|
|
2583
|
+
writer.write(nextSlot.toBytes());
|
|
2613
2584
|
return new Slot(nextIndexPos, 1 /* INDEX */);
|
|
2614
2585
|
}
|
|
2615
2586
|
} else if (this.header.tag === 2 /* ARRAY_LIST */) {
|
|
2616
2587
|
throw new ExpectedTxStartException;
|
|
2617
2588
|
}
|
|
2618
2589
|
}
|
|
2619
|
-
|
|
2620
|
-
|
|
2590
|
+
this.core.seek(slotPos);
|
|
2591
|
+
writer.write(nextSlot.toBytes());
|
|
2621
2592
|
return new Slot(indexPos, 1 /* INDEX */);
|
|
2622
2593
|
}
|
|
2623
|
-
|
|
2594
|
+
readArrayListSlotAppend(header, writeMode, isTopLevel) {
|
|
2624
2595
|
const writer = this.core.writer();
|
|
2625
2596
|
let indexPos = header.ptr;
|
|
2626
2597
|
const key = header.size;
|
|
2627
2598
|
const prevShift = key < SLOT_COUNT ? 0 : Math.floor(Math.log(key - 1) / Math.log(SLOT_COUNT));
|
|
2628
2599
|
const nextShift = key < SLOT_COUNT ? 0 : Math.floor(Math.log(key) / Math.log(SLOT_COUNT));
|
|
2629
2600
|
if (prevShift !== nextShift) {
|
|
2630
|
-
const nextIndexPos =
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
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());
|
|
2635
2606
|
indexPos = nextIndexPos;
|
|
2636
2607
|
}
|
|
2637
|
-
const slotPtr =
|
|
2608
|
+
const slotPtr = this.readArrayListSlot(indexPos, key, nextShift, writeMode, isTopLevel);
|
|
2638
2609
|
return new ArrayListAppendResult(new ArrayListHeader(indexPos, header.size + 1), slotPtr);
|
|
2639
2610
|
}
|
|
2640
|
-
|
|
2611
|
+
readArrayListSlot(indexPos, key, shift, writeMode, isTopLevel) {
|
|
2641
2612
|
if (shift >= MAX_BRANCH_LENGTH)
|
|
2642
2613
|
throw new MaxShiftExceededException;
|
|
2643
2614
|
const reader = this.core.reader();
|
|
2644
2615
|
const i = key >>> shift * BIT_COUNT & SLOT_COUNT - 1;
|
|
2645
2616
|
const slotPos = indexPos + Slot.LENGTH * i;
|
|
2646
|
-
|
|
2617
|
+
this.core.seek(slotPos);
|
|
2647
2618
|
const slotBytes = new Uint8Array(Slot.LENGTH);
|
|
2648
|
-
|
|
2619
|
+
reader.readFully(slotBytes);
|
|
2649
2620
|
const slot = Slot.fromBytes(slotBytes);
|
|
2650
2621
|
if (shift === 0) {
|
|
2651
2622
|
return new SlotPointer(slotPos, slot);
|
|
@@ -2658,16 +2629,16 @@ class Database3 {
|
|
|
2658
2629
|
throw new KeyNotFoundException;
|
|
2659
2630
|
case 1 /* READ_WRITE */: {
|
|
2660
2631
|
const writer = this.core.writer();
|
|
2661
|
-
const nextIndexPos =
|
|
2662
|
-
|
|
2663
|
-
|
|
2632
|
+
const nextIndexPos = this.core.length();
|
|
2633
|
+
this.core.seek(nextIndexPos);
|
|
2634
|
+
writer.write(new Uint8Array(INDEX_BLOCK_SIZE));
|
|
2664
2635
|
if (isTopLevel) {
|
|
2665
|
-
const fileSize =
|
|
2666
|
-
|
|
2667
|
-
|
|
2636
|
+
const fileSize = this.core.length();
|
|
2637
|
+
this.core.seek(Header.LENGTH + ArrayListHeader.LENGTH);
|
|
2638
|
+
writer.writeLong(fileSize);
|
|
2668
2639
|
}
|
|
2669
|
-
|
|
2670
|
-
|
|
2640
|
+
this.core.seek(slotPos);
|
|
2641
|
+
writer.write(new Slot(nextIndexPos, 1 /* INDEX */).toBytes());
|
|
2671
2642
|
return this.readArrayListSlot(nextIndexPos, key, shift - 1, writeMode, isTopLevel);
|
|
2672
2643
|
}
|
|
2673
2644
|
default:
|
|
@@ -2679,15 +2650,15 @@ class Database3 {
|
|
|
2679
2650
|
if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
|
|
2680
2651
|
if (this.txStart !== null) {
|
|
2681
2652
|
if (nextPtr < this.txStart) {
|
|
2682
|
-
|
|
2653
|
+
this.core.seek(ptr);
|
|
2683
2654
|
const indexBlock = new Uint8Array(INDEX_BLOCK_SIZE);
|
|
2684
|
-
|
|
2655
|
+
reader.readFully(indexBlock);
|
|
2685
2656
|
const writer = this.core.writer();
|
|
2686
|
-
nextPtr =
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
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());
|
|
2691
2662
|
}
|
|
2692
2663
|
} else if (this.header.tag === 2 /* ARRAY_LIST */) {
|
|
2693
2664
|
throw new ExpectedTxStartException;
|
|
@@ -2699,7 +2670,7 @@ class Database3 {
|
|
|
2699
2670
|
throw new UnexpectedTagException;
|
|
2700
2671
|
}
|
|
2701
2672
|
}
|
|
2702
|
-
|
|
2673
|
+
readArrayListSlice(header, size) {
|
|
2703
2674
|
const reader = this.core.reader();
|
|
2704
2675
|
if (size > header.size || size < 0) {
|
|
2705
2676
|
throw new KeyNotFoundException;
|
|
@@ -2712,9 +2683,9 @@ class Database3 {
|
|
|
2712
2683
|
let shift = prevShift;
|
|
2713
2684
|
let indexPos = header.ptr;
|
|
2714
2685
|
while (shift > nextShift) {
|
|
2715
|
-
|
|
2686
|
+
this.core.seek(indexPos);
|
|
2716
2687
|
const slotBytes = new Uint8Array(Slot.LENGTH);
|
|
2717
|
-
|
|
2688
|
+
reader.readFully(slotBytes);
|
|
2718
2689
|
const slot = Slot.fromBytes(slotBytes);
|
|
2719
2690
|
shift -= 1;
|
|
2720
2691
|
indexPos = Number(slot.value);
|
|
@@ -2722,24 +2693,24 @@ class Database3 {
|
|
|
2722
2693
|
return new ArrayListHeader(indexPos, size);
|
|
2723
2694
|
}
|
|
2724
2695
|
}
|
|
2725
|
-
|
|
2696
|
+
readLinkedArrayListSlotAppend(header, writeMode, isTopLevel) {
|
|
2726
2697
|
const writer = this.core.writer();
|
|
2727
2698
|
let ptr = header.ptr;
|
|
2728
2699
|
const key = header.size;
|
|
2729
2700
|
let shift = header.shift;
|
|
2730
2701
|
let slotPtr;
|
|
2731
2702
|
try {
|
|
2732
|
-
slotPtr =
|
|
2703
|
+
slotPtr = this.readLinkedArrayListSlot(ptr, key, shift, writeMode, isTopLevel);
|
|
2733
2704
|
} catch (e) {
|
|
2734
2705
|
if (e instanceof NoAvailableSlotsException) {
|
|
2735
|
-
const nextPtr =
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
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());
|
|
2740
2711
|
ptr = nextPtr;
|
|
2741
2712
|
shift += 1;
|
|
2742
|
-
slotPtr =
|
|
2713
|
+
slotPtr = this.readLinkedArrayListSlot(ptr, key, shift, writeMode, isTopLevel);
|
|
2743
2714
|
} else {
|
|
2744
2715
|
throw e;
|
|
2745
2716
|
}
|
|
@@ -2749,8 +2720,8 @@ class Database3 {
|
|
|
2749
2720
|
if (slotPtr.slotPtr.position === null)
|
|
2750
2721
|
throw new CursorNotWriteableException;
|
|
2751
2722
|
const position = slotPtr.slotPtr.position;
|
|
2752
|
-
|
|
2753
|
-
|
|
2723
|
+
this.core.seek(position);
|
|
2724
|
+
writer.write(new LinkedArrayListSlot2(0, newSlot).toBytes());
|
|
2754
2725
|
if (header.size < SLOT_COUNT && shift > 0) {
|
|
2755
2726
|
throw new MustSetNewSlotsToFullException;
|
|
2756
2727
|
}
|
|
@@ -2810,15 +2781,15 @@ class Database3 {
|
|
|
2810
2781
|
}
|
|
2811
2782
|
return { key: nextKey, index: i };
|
|
2812
2783
|
}
|
|
2813
|
-
|
|
2784
|
+
readLinkedArrayListSlot(indexPos, key, shift, writeMode, isTopLevel) {
|
|
2814
2785
|
if (shift >= MAX_BRANCH_LENGTH)
|
|
2815
2786
|
throw new MaxShiftExceededException;
|
|
2816
2787
|
const reader = this.core.reader();
|
|
2817
2788
|
const writer = this.core.writer();
|
|
2818
2789
|
const slotBlock = new Array(SLOT_COUNT);
|
|
2819
|
-
|
|
2790
|
+
this.core.seek(indexPos);
|
|
2820
2791
|
const indexBlock = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
|
|
2821
|
-
|
|
2792
|
+
reader.readFully(indexBlock);
|
|
2822
2793
|
for (let i2 = 0;i2 < SLOT_COUNT; i2++) {
|
|
2823
2794
|
const slotBytes = indexBlock.slice(i2 * LinkedArrayListSlot2.LENGTH, (i2 + 1) * LinkedArrayListSlot2.LENGTH);
|
|
2824
2795
|
slotBlock[i2] = LinkedArrayListSlot2.fromBytes(slotBytes);
|
|
@@ -2841,14 +2812,14 @@ class Database3 {
|
|
|
2841
2812
|
case 0 /* READ_ONLY */:
|
|
2842
2813
|
throw new KeyNotFoundException;
|
|
2843
2814
|
case 1 /* READ_WRITE */: {
|
|
2844
|
-
const nextIndexPos =
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
const nextSlotPtr =
|
|
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);
|
|
2848
2819
|
slotBlock[i] = slotBlock[i].withSize(nextSlotPtr.leafCount);
|
|
2849
2820
|
const leafCount = Database3.blockLeafCount(slotBlock, shift, i);
|
|
2850
|
-
|
|
2851
|
-
|
|
2821
|
+
this.core.seek(slotPos);
|
|
2822
|
+
writer.write(new LinkedArrayListSlot2(nextSlotPtr.leafCount, new Slot(nextIndexPos, 1 /* INDEX */)).toBytes());
|
|
2852
2823
|
return new LinkedArrayListSlotPointer(nextSlotPtr.slotPtr, leafCount);
|
|
2853
2824
|
}
|
|
2854
2825
|
default:
|
|
@@ -2860,23 +2831,23 @@ class Database3 {
|
|
|
2860
2831
|
if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
|
|
2861
2832
|
if (this.txStart !== null) {
|
|
2862
2833
|
if (nextPtr < this.txStart) {
|
|
2863
|
-
|
|
2834
|
+
this.core.seek(ptr);
|
|
2864
2835
|
const indexBlockCopy = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
|
|
2865
|
-
|
|
2866
|
-
nextPtr =
|
|
2867
|
-
|
|
2868
|
-
|
|
2836
|
+
reader.readFully(indexBlockCopy);
|
|
2837
|
+
nextPtr = this.core.length();
|
|
2838
|
+
this.core.seek(nextPtr);
|
|
2839
|
+
writer.write(indexBlockCopy);
|
|
2869
2840
|
}
|
|
2870
2841
|
} else if (this.header.tag === 2 /* ARRAY_LIST */) {
|
|
2871
2842
|
throw new ExpectedTxStartException;
|
|
2872
2843
|
}
|
|
2873
2844
|
}
|
|
2874
|
-
const nextSlotPtr =
|
|
2845
|
+
const nextSlotPtr = this.readLinkedArrayListSlot(nextPtr, nextKey, shift - 1, writeMode, isTopLevel);
|
|
2875
2846
|
slotBlock[i] = slotBlock[i].withSize(nextSlotPtr.leafCount);
|
|
2876
2847
|
const leafCount = Database3.blockLeafCount(slotBlock, shift, i);
|
|
2877
2848
|
if (writeMode === 1 /* READ_WRITE */ && !isTopLevel) {
|
|
2878
|
-
|
|
2879
|
-
|
|
2849
|
+
this.core.seek(slotPos);
|
|
2850
|
+
writer.write(new LinkedArrayListSlot2(nextSlotPtr.leafCount, new Slot(nextPtr, 1 /* INDEX */)).toBytes());
|
|
2880
2851
|
}
|
|
2881
2852
|
return new LinkedArrayListSlotPointer(nextSlotPtr.slotPtr, leafCount);
|
|
2882
2853
|
}
|
|
@@ -2884,12 +2855,12 @@ class Database3 {
|
|
|
2884
2855
|
throw new UnexpectedTagException;
|
|
2885
2856
|
}
|
|
2886
2857
|
}
|
|
2887
|
-
|
|
2858
|
+
readLinkedArrayListBlocks(indexPos, key, shift, blocks) {
|
|
2888
2859
|
const reader = this.core.reader();
|
|
2889
2860
|
const slotBlock = new Array(SLOT_COUNT);
|
|
2890
|
-
|
|
2861
|
+
this.core.seek(indexPos);
|
|
2891
2862
|
const indexBlock = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
|
|
2892
|
-
|
|
2863
|
+
reader.readFully(indexBlock);
|
|
2893
2864
|
for (let i2 = 0;i2 < SLOT_COUNT; i2++) {
|
|
2894
2865
|
const slotBytes = indexBlock.slice(i2 * LinkedArrayListSlot2.LENGTH, (i2 + 1) * LinkedArrayListSlot2.LENGTH);
|
|
2895
2866
|
slotBlock[i2] = LinkedArrayListSlot2.fromBytes(slotBytes);
|
|
@@ -2909,7 +2880,7 @@ class Database3 {
|
|
|
2909
2880
|
case 0 /* NONE */:
|
|
2910
2881
|
throw new EmptySlotException;
|
|
2911
2882
|
case 1 /* INDEX */:
|
|
2912
|
-
|
|
2883
|
+
this.readLinkedArrayListBlocks(Number(slot.slot.value), nextKey, shift - 1, blocks);
|
|
2913
2884
|
break;
|
|
2914
2885
|
default:
|
|
2915
2886
|
throw new UnexpectedTagException;
|
|
@@ -2920,16 +2891,16 @@ class Database3 {
|
|
|
2920
2891
|
arr[i] = new LinkedArrayListSlot2(0, new Slot);
|
|
2921
2892
|
}
|
|
2922
2893
|
}
|
|
2923
|
-
|
|
2894
|
+
readLinkedArrayListSlice(header, offset, size) {
|
|
2924
2895
|
const writer = this.core.writer();
|
|
2925
2896
|
if (offset + size > header.size) {
|
|
2926
2897
|
throw new KeyNotFoundException;
|
|
2927
2898
|
}
|
|
2928
2899
|
const leftBlocks = [];
|
|
2929
|
-
|
|
2900
|
+
this.readLinkedArrayListBlocks(header.ptr, offset, header.shift, leftBlocks);
|
|
2930
2901
|
const rightBlocks = [];
|
|
2931
2902
|
const rightKey = offset + size === 0 ? 0 : offset + size - 1;
|
|
2932
|
-
|
|
2903
|
+
this.readLinkedArrayListBlocks(header.ptr, rightKey, header.shift, rightBlocks);
|
|
2933
2904
|
const blockCount = leftBlocks.length;
|
|
2934
2905
|
let nextSlots = [null, null];
|
|
2935
2906
|
let nextShift = 0;
|
|
@@ -2997,7 +2968,7 @@ class Database3 {
|
|
|
2997
2968
|
nextShift += 1;
|
|
2998
2969
|
}
|
|
2999
2970
|
nextSlots = [null, null];
|
|
3000
|
-
|
|
2971
|
+
this.core.seek(this.core.length());
|
|
3001
2972
|
for (let j = 0;j < 2; j++) {
|
|
3002
2973
|
const blockMaybe = nextBlocks[j];
|
|
3003
2974
|
const origBlockInfo = origBlockInfos[j];
|
|
@@ -3014,11 +2985,11 @@ class Database3 {
|
|
|
3014
2985
|
if (eql) {
|
|
3015
2986
|
nextSlots[j] = origBlockInfo.parentSlot;
|
|
3016
2987
|
} else {
|
|
3017
|
-
const nextPtr =
|
|
2988
|
+
const nextPtr = this.core.position();
|
|
3018
2989
|
let leafCount = 0;
|
|
3019
2990
|
for (let k = 0;k < blockMaybe.length; k++) {
|
|
3020
2991
|
const blockSlot = blockMaybe[k];
|
|
3021
|
-
|
|
2992
|
+
writer.write(blockSlot.toBytes());
|
|
3022
2993
|
if (isLeafNode) {
|
|
3023
2994
|
if (!blockSlot.slot.empty()) {
|
|
3024
2995
|
leafCount += 1;
|
|
@@ -3040,13 +3011,13 @@ class Database3 {
|
|
|
3040
3011
|
throw new ExpectedRootNodeException;
|
|
3041
3012
|
return new LinkedArrayListHeader(nextShift, Number(rootSlot.slot.value), size);
|
|
3042
3013
|
}
|
|
3043
|
-
|
|
3014
|
+
readLinkedArrayListConcat(headerA, headerB) {
|
|
3044
3015
|
const writer = this.core.writer();
|
|
3045
3016
|
const blocksA = [];
|
|
3046
3017
|
const keyA = headerA.size === 0 ? 0 : headerA.size - 1;
|
|
3047
|
-
|
|
3018
|
+
this.readLinkedArrayListBlocks(headerA.ptr, keyA, headerA.shift, blocksA);
|
|
3048
3019
|
const blocksB = [];
|
|
3049
|
-
|
|
3020
|
+
this.readLinkedArrayListBlocks(headerB.ptr, 0, headerB.shift, blocksB);
|
|
3050
3021
|
let nextSlots = [null, null];
|
|
3051
3022
|
let nextShift = 0;
|
|
3052
3023
|
for (let i = 0;i < Math.max(blocksA.length, blocksB.length); i++) {
|
|
@@ -3133,16 +3104,16 @@ class Database3 {
|
|
|
3133
3104
|
blocks[0][j] = slotsToWrite[j];
|
|
3134
3105
|
}
|
|
3135
3106
|
}
|
|
3136
|
-
|
|
3107
|
+
this.core.seek(this.core.length());
|
|
3137
3108
|
for (let blockI = 0;blockI < blocks.length; blockI++) {
|
|
3138
3109
|
const block = blocks[blockI];
|
|
3139
3110
|
if (block[0].slot.empty()) {
|
|
3140
3111
|
break;
|
|
3141
3112
|
}
|
|
3142
|
-
const nextPtr =
|
|
3113
|
+
const nextPtr = this.core.position();
|
|
3143
3114
|
let leafCount = 0;
|
|
3144
3115
|
for (const blockSlot of block) {
|
|
3145
|
-
|
|
3116
|
+
writer.write(blockSlot.toBytes());
|
|
3146
3117
|
if (isLeafNode) {
|
|
3147
3118
|
if (!blockSlot.slot.empty()) {
|
|
3148
3119
|
leafCount += 1;
|
|
@@ -3161,9 +3132,9 @@ class Database3 {
|
|
|
3161
3132
|
this.populateArray(block);
|
|
3162
3133
|
block[0] = nextSlots[0];
|
|
3163
3134
|
block[1] = nextSlots[1];
|
|
3164
|
-
const newPtr =
|
|
3135
|
+
const newPtr = this.core.length();
|
|
3165
3136
|
for (const blockSlot of block) {
|
|
3166
|
-
|
|
3137
|
+
writer.write(blockSlot.toBytes());
|
|
3167
3138
|
}
|
|
3168
3139
|
if (nextShift === MAX_BRANCH_LENGTH)
|
|
3169
3140
|
throw new MaxShiftExceededException;
|
|
@@ -3178,7 +3149,7 @@ class Database3 {
|
|
|
3178
3149
|
return new LinkedArrayListHeader(nextShift, rootPtr, headerA.size + headerB.size);
|
|
3179
3150
|
}
|
|
3180
3151
|
}
|
|
3181
|
-
|
|
3152
|
+
function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
3182
3153
|
switch (slot.tag) {
|
|
3183
3154
|
case 0 /* NONE */:
|
|
3184
3155
|
case 8 /* UINT */:
|
|
@@ -3190,7 +3161,7 @@ async function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
|
3190
3161
|
const mapped = offsetMap.get(Number(slot.value));
|
|
3191
3162
|
if (mapped !== undefined)
|
|
3192
3163
|
return new Slot(mapped, slot.tag, slot.full);
|
|
3193
|
-
const newOffset =
|
|
3164
|
+
const newOffset = remapBytes(sourceCore, targetCore, slot);
|
|
3194
3165
|
offsetMap.set(Number(slot.value), newOffset);
|
|
3195
3166
|
return new Slot(newOffset, slot.tag, slot.full);
|
|
3196
3167
|
}
|
|
@@ -3198,7 +3169,7 @@ async function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
|
3198
3169
|
const mapped = offsetMap.get(Number(slot.value));
|
|
3199
3170
|
if (mapped !== undefined)
|
|
3200
3171
|
return new Slot(mapped, slot.tag, slot.full);
|
|
3201
|
-
const newOffset =
|
|
3172
|
+
const newOffset = remapIndex(sourceCore, targetCore, hashSize, offsetMap, slot);
|
|
3202
3173
|
offsetMap.set(Number(slot.value), newOffset);
|
|
3203
3174
|
return new Slot(newOffset, slot.tag, slot.full);
|
|
3204
3175
|
}
|
|
@@ -3206,7 +3177,7 @@ async function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
|
3206
3177
|
const mapped = offsetMap.get(Number(slot.value));
|
|
3207
3178
|
if (mapped !== undefined)
|
|
3208
3179
|
return new Slot(mapped, slot.tag, slot.full);
|
|
3209
|
-
const newOffset =
|
|
3180
|
+
const newOffset = remapArrayList(sourceCore, targetCore, hashSize, offsetMap, slot);
|
|
3210
3181
|
offsetMap.set(Number(slot.value), newOffset);
|
|
3211
3182
|
return new Slot(newOffset, slot.tag, slot.full);
|
|
3212
3183
|
}
|
|
@@ -3214,7 +3185,7 @@ async function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
|
3214
3185
|
const mapped = offsetMap.get(Number(slot.value));
|
|
3215
3186
|
if (mapped !== undefined)
|
|
3216
3187
|
return new Slot(mapped, slot.tag, slot.full);
|
|
3217
|
-
const newOffset =
|
|
3188
|
+
const newOffset = remapLinkedArrayList(sourceCore, targetCore, hashSize, offsetMap, slot);
|
|
3218
3189
|
offsetMap.set(Number(slot.value), newOffset);
|
|
3219
3190
|
return new Slot(newOffset, slot.tag, slot.full);
|
|
3220
3191
|
}
|
|
@@ -3223,7 +3194,7 @@ async function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
|
3223
3194
|
const mapped = offsetMap.get(Number(slot.value));
|
|
3224
3195
|
if (mapped !== undefined)
|
|
3225
3196
|
return new Slot(mapped, slot.tag, slot.full);
|
|
3226
|
-
const newOffset =
|
|
3197
|
+
const newOffset = remapHashMapOrSet(sourceCore, targetCore, hashSize, offsetMap, slot, false);
|
|
3227
3198
|
offsetMap.set(Number(slot.value), newOffset);
|
|
3228
3199
|
return new Slot(newOffset, slot.tag, slot.full);
|
|
3229
3200
|
}
|
|
@@ -3232,7 +3203,7 @@ async function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
|
3232
3203
|
const mapped = offsetMap.get(Number(slot.value));
|
|
3233
3204
|
if (mapped !== undefined)
|
|
3234
3205
|
return new Slot(mapped, slot.tag, slot.full);
|
|
3235
|
-
const newOffset =
|
|
3206
|
+
const newOffset = remapHashMapOrSet(sourceCore, targetCore, hashSize, offsetMap, slot, true);
|
|
3236
3207
|
offsetMap.set(Number(slot.value), newOffset);
|
|
3237
3208
|
return new Slot(newOffset, slot.tag, slot.full);
|
|
3238
3209
|
}
|
|
@@ -3240,7 +3211,7 @@ async function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
|
3240
3211
|
const mapped = offsetMap.get(Number(slot.value));
|
|
3241
3212
|
if (mapped !== undefined)
|
|
3242
3213
|
return new Slot(mapped, slot.tag, slot.full);
|
|
3243
|
-
const newOffset =
|
|
3214
|
+
const newOffset = remapKvPair(sourceCore, targetCore, hashSize, offsetMap, slot);
|
|
3244
3215
|
offsetMap.set(Number(slot.value), newOffset);
|
|
3245
3216
|
return new Slot(newOffset, slot.tag, slot.full);
|
|
3246
3217
|
}
|
|
@@ -3248,80 +3219,80 @@ async function remapSlot(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
|
3248
3219
|
throw new UnexpectedTagException;
|
|
3249
3220
|
}
|
|
3250
3221
|
}
|
|
3251
|
-
|
|
3252
|
-
|
|
3222
|
+
function remapBytes(sourceCore, targetCore, slot) {
|
|
3223
|
+
sourceCore.seek(Number(slot.value));
|
|
3253
3224
|
const sourceReader = sourceCore.reader();
|
|
3254
|
-
const length =
|
|
3225
|
+
const length = sourceReader.readLong();
|
|
3255
3226
|
const formatTagSize = slot.full ? 2 : 0;
|
|
3256
3227
|
const totalPayload = length + formatTagSize;
|
|
3257
|
-
const newOffset =
|
|
3258
|
-
|
|
3228
|
+
const newOffset = targetCore.length();
|
|
3229
|
+
targetCore.seek(newOffset);
|
|
3259
3230
|
const targetWriter = targetCore.writer();
|
|
3260
|
-
|
|
3231
|
+
targetWriter.writeLong(length);
|
|
3261
3232
|
let remaining = totalPayload;
|
|
3262
3233
|
while (remaining > 0) {
|
|
3263
3234
|
const chunk = Math.min(remaining, 4096);
|
|
3264
3235
|
const buf = new Uint8Array(chunk);
|
|
3265
|
-
|
|
3266
|
-
|
|
3236
|
+
sourceReader.readFully(buf);
|
|
3237
|
+
targetWriter.write(buf);
|
|
3267
3238
|
remaining -= chunk;
|
|
3268
3239
|
}
|
|
3269
3240
|
return newOffset;
|
|
3270
3241
|
}
|
|
3271
|
-
|
|
3272
|
-
|
|
3242
|
+
function remapIndex(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
3243
|
+
sourceCore.seek(Number(slot.value));
|
|
3273
3244
|
const sourceReader = sourceCore.reader();
|
|
3274
3245
|
const blockBytes = new Uint8Array(INDEX_BLOCK_SIZE);
|
|
3275
|
-
|
|
3246
|
+
sourceReader.readFully(blockBytes);
|
|
3276
3247
|
const remappedSlots = [];
|
|
3277
3248
|
for (let i = 0;i < SLOT_COUNT; i++) {
|
|
3278
3249
|
const slotBytes = blockBytes.slice(i * Slot.LENGTH, (i + 1) * Slot.LENGTH);
|
|
3279
3250
|
const childSlot = Slot.fromBytes(slotBytes);
|
|
3280
|
-
remappedSlots.push(
|
|
3251
|
+
remappedSlots.push(remapSlot(sourceCore, targetCore, hashSize, offsetMap, childSlot));
|
|
3281
3252
|
}
|
|
3282
|
-
const newOffset =
|
|
3283
|
-
|
|
3253
|
+
const newOffset = targetCore.length();
|
|
3254
|
+
targetCore.seek(newOffset);
|
|
3284
3255
|
const targetWriter = targetCore.writer();
|
|
3285
3256
|
for (const s of remappedSlots) {
|
|
3286
|
-
|
|
3257
|
+
targetWriter.write(s.toBytes());
|
|
3287
3258
|
}
|
|
3288
3259
|
return newOffset;
|
|
3289
3260
|
}
|
|
3290
|
-
|
|
3291
|
-
|
|
3261
|
+
function remapArrayList(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
3262
|
+
sourceCore.seek(Number(slot.value));
|
|
3292
3263
|
const sourceReader = sourceCore.reader();
|
|
3293
3264
|
const headerBytes = new Uint8Array(ArrayListHeader.LENGTH);
|
|
3294
|
-
|
|
3265
|
+
sourceReader.readFully(headerBytes);
|
|
3295
3266
|
const header = ArrayListHeader.fromBytes(headerBytes);
|
|
3296
3267
|
const indexSlot = new Slot(header.ptr, 1 /* INDEX */);
|
|
3297
|
-
const remappedIndex =
|
|
3298
|
-
const newOffset =
|
|
3299
|
-
|
|
3268
|
+
const remappedIndex = remapSlot(sourceCore, targetCore, hashSize, offsetMap, indexSlot);
|
|
3269
|
+
const newOffset = targetCore.length();
|
|
3270
|
+
targetCore.seek(newOffset);
|
|
3300
3271
|
const targetWriter = targetCore.writer();
|
|
3301
|
-
|
|
3272
|
+
targetWriter.write(new ArrayListHeader(Number(remappedIndex.value), header.size).toBytes());
|
|
3302
3273
|
return newOffset;
|
|
3303
3274
|
}
|
|
3304
|
-
|
|
3305
|
-
|
|
3275
|
+
function remapLinkedArrayList(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
3276
|
+
sourceCore.seek(Number(slot.value));
|
|
3306
3277
|
const sourceReader = sourceCore.reader();
|
|
3307
3278
|
const headerBytes = new Uint8Array(LinkedArrayListHeader.LENGTH);
|
|
3308
|
-
|
|
3279
|
+
sourceReader.readFully(headerBytes);
|
|
3309
3280
|
const header = LinkedArrayListHeader.fromBytes(headerBytes);
|
|
3310
|
-
const remappedPtr =
|
|
3311
|
-
const newOffset =
|
|
3312
|
-
|
|
3281
|
+
const remappedPtr = remapLinkedArrayListBlock(sourceCore, targetCore, hashSize, offsetMap, header.ptr);
|
|
3282
|
+
const newOffset = targetCore.length();
|
|
3283
|
+
targetCore.seek(newOffset);
|
|
3313
3284
|
const targetWriter = targetCore.writer();
|
|
3314
|
-
|
|
3285
|
+
targetWriter.write(new LinkedArrayListHeader(header.shift, remappedPtr, header.size).toBytes());
|
|
3315
3286
|
return newOffset;
|
|
3316
3287
|
}
|
|
3317
|
-
|
|
3288
|
+
function remapLinkedArrayListBlock(sourceCore, targetCore, hashSize, offsetMap, blockOffset) {
|
|
3318
3289
|
const mapped = offsetMap.get(blockOffset);
|
|
3319
3290
|
if (mapped !== undefined)
|
|
3320
3291
|
return mapped;
|
|
3321
|
-
|
|
3292
|
+
sourceCore.seek(blockOffset);
|
|
3322
3293
|
const sourceReader = sourceCore.reader();
|
|
3323
3294
|
const blockBytes = new Uint8Array(LINKED_ARRAY_LIST_INDEX_BLOCK_SIZE);
|
|
3324
|
-
|
|
3295
|
+
sourceReader.readFully(blockBytes);
|
|
3325
3296
|
const slots = [];
|
|
3326
3297
|
for (let i = 0;i < SLOT_COUNT; i++) {
|
|
3327
3298
|
const slotBytes = blockBytes.slice(i * LinkedArrayListSlot2.LENGTH, (i + 1) * LinkedArrayListSlot2.LENGTH);
|
|
@@ -3330,62 +3301,62 @@ async function remapLinkedArrayListBlock(sourceCore, targetCore, hashSize, offse
|
|
|
3330
3301
|
const remappedSlots = [];
|
|
3331
3302
|
for (const s of slots) {
|
|
3332
3303
|
if (s.slot.tag === 1 /* INDEX */) {
|
|
3333
|
-
const remappedPtr =
|
|
3304
|
+
const remappedPtr = remapLinkedArrayListBlock(sourceCore, targetCore, hashSize, offsetMap, Number(s.slot.value));
|
|
3334
3305
|
remappedSlots.push(new LinkedArrayListSlot2(s.size, new Slot(remappedPtr, 1 /* INDEX */, s.slot.full)));
|
|
3335
3306
|
} else if (s.slot.empty()) {
|
|
3336
3307
|
remappedSlots.push(s);
|
|
3337
3308
|
} else {
|
|
3338
|
-
const remapped =
|
|
3309
|
+
const remapped = remapSlot(sourceCore, targetCore, hashSize, offsetMap, s.slot);
|
|
3339
3310
|
remappedSlots.push(new LinkedArrayListSlot2(s.size, remapped));
|
|
3340
3311
|
}
|
|
3341
3312
|
}
|
|
3342
|
-
const newOffset =
|
|
3343
|
-
|
|
3313
|
+
const newOffset = targetCore.length();
|
|
3314
|
+
targetCore.seek(newOffset);
|
|
3344
3315
|
const targetWriter = targetCore.writer();
|
|
3345
3316
|
for (const s of remappedSlots) {
|
|
3346
|
-
|
|
3317
|
+
targetWriter.write(s.toBytes());
|
|
3347
3318
|
}
|
|
3348
3319
|
offsetMap.set(blockOffset, newOffset);
|
|
3349
3320
|
return newOffset;
|
|
3350
3321
|
}
|
|
3351
|
-
|
|
3352
|
-
|
|
3322
|
+
function remapHashMapOrSet(sourceCore, targetCore, hashSize, offsetMap, slot, counted) {
|
|
3323
|
+
sourceCore.seek(Number(slot.value));
|
|
3353
3324
|
const sourceReader = sourceCore.reader();
|
|
3354
3325
|
let countValue = -1;
|
|
3355
3326
|
if (counted) {
|
|
3356
|
-
countValue =
|
|
3327
|
+
countValue = sourceReader.readLong();
|
|
3357
3328
|
}
|
|
3358
3329
|
const blockBytes = new Uint8Array(INDEX_BLOCK_SIZE);
|
|
3359
|
-
|
|
3330
|
+
sourceReader.readFully(blockBytes);
|
|
3360
3331
|
const remappedSlots = [];
|
|
3361
3332
|
for (let i = 0;i < SLOT_COUNT; i++) {
|
|
3362
3333
|
const slotBytes = blockBytes.slice(i * Slot.LENGTH, (i + 1) * Slot.LENGTH);
|
|
3363
3334
|
const childSlot = Slot.fromBytes(slotBytes);
|
|
3364
|
-
remappedSlots.push(
|
|
3335
|
+
remappedSlots.push(remapSlot(sourceCore, targetCore, hashSize, offsetMap, childSlot));
|
|
3365
3336
|
}
|
|
3366
|
-
const newOffset =
|
|
3367
|
-
|
|
3337
|
+
const newOffset = targetCore.length();
|
|
3338
|
+
targetCore.seek(newOffset);
|
|
3368
3339
|
const targetWriter = targetCore.writer();
|
|
3369
3340
|
if (counted) {
|
|
3370
|
-
|
|
3341
|
+
targetWriter.writeLong(countValue);
|
|
3371
3342
|
}
|
|
3372
3343
|
for (const s of remappedSlots) {
|
|
3373
|
-
|
|
3344
|
+
targetWriter.write(s.toBytes());
|
|
3374
3345
|
}
|
|
3375
3346
|
return newOffset;
|
|
3376
3347
|
}
|
|
3377
|
-
|
|
3378
|
-
|
|
3348
|
+
function remapKvPair(sourceCore, targetCore, hashSize, offsetMap, slot) {
|
|
3349
|
+
sourceCore.seek(Number(slot.value));
|
|
3379
3350
|
const sourceReader = sourceCore.reader();
|
|
3380
3351
|
const kvPairBytes = new Uint8Array(KeyValuePair.length(hashSize));
|
|
3381
|
-
|
|
3352
|
+
sourceReader.readFully(kvPairBytes);
|
|
3382
3353
|
const kvPair = KeyValuePair.fromBytes(kvPairBytes, hashSize);
|
|
3383
|
-
const remappedKey =
|
|
3384
|
-
const remappedValue =
|
|
3385
|
-
const newOffset =
|
|
3386
|
-
|
|
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);
|
|
3387
3358
|
const targetWriter = targetCore.writer();
|
|
3388
|
-
|
|
3359
|
+
targetWriter.write(new KeyValuePair(remappedValue, remappedKey, kvPair.hash).toBytes());
|
|
3389
3360
|
return newOffset;
|
|
3390
3361
|
}
|
|
3391
3362
|
// src/read-array-list.ts
|
|
@@ -3406,66 +3377,61 @@ class ReadArrayList {
|
|
|
3406
3377
|
slot() {
|
|
3407
3378
|
return this.cursor.slot();
|
|
3408
3379
|
}
|
|
3409
|
-
|
|
3380
|
+
count() {
|
|
3410
3381
|
return this.cursor.count();
|
|
3411
3382
|
}
|
|
3412
|
-
|
|
3383
|
+
iterator() {
|
|
3413
3384
|
return this.cursor.iterator();
|
|
3414
3385
|
}
|
|
3415
|
-
|
|
3386
|
+
*[Symbol.iterator]() {
|
|
3416
3387
|
yield* this.cursor;
|
|
3417
3388
|
}
|
|
3418
|
-
|
|
3389
|
+
getCursor(index) {
|
|
3419
3390
|
return this.cursor.readPath([new ArrayListGet2(index)]);
|
|
3420
3391
|
}
|
|
3421
|
-
|
|
3392
|
+
getSlot(index) {
|
|
3422
3393
|
return this.cursor.readPathSlot([new ArrayListGet2(index)]);
|
|
3423
3394
|
}
|
|
3424
3395
|
}
|
|
3425
3396
|
// src/write-array-list.ts
|
|
3426
3397
|
class WriteArrayList extends ReadArrayList {
|
|
3427
|
-
constructor() {
|
|
3398
|
+
constructor(cursor) {
|
|
3428
3399
|
super();
|
|
3400
|
+
this.cursor = cursor.writePath([new ArrayListInit]);
|
|
3429
3401
|
}
|
|
3430
|
-
|
|
3431
|
-
const list = new WriteArrayList;
|
|
3432
|
-
const newCursor = await cursor.writePath([new ArrayListInit]);
|
|
3433
|
-
list.cursor = newCursor;
|
|
3434
|
-
return list;
|
|
3435
|
-
}
|
|
3436
|
-
async iterator() {
|
|
3402
|
+
iterator() {
|
|
3437
3403
|
return this.cursor.iterator();
|
|
3438
3404
|
}
|
|
3439
|
-
|
|
3405
|
+
*[Symbol.iterator]() {
|
|
3440
3406
|
yield* this.cursor;
|
|
3441
3407
|
}
|
|
3442
|
-
|
|
3443
|
-
|
|
3408
|
+
put(index, data) {
|
|
3409
|
+
this.cursor.writePath([
|
|
3444
3410
|
new ArrayListGet2(index),
|
|
3445
3411
|
new WriteData(data)
|
|
3446
3412
|
]);
|
|
3447
3413
|
}
|
|
3448
|
-
|
|
3414
|
+
putCursor(index) {
|
|
3449
3415
|
return this.cursor.writePath([new ArrayListGet2(index)]);
|
|
3450
3416
|
}
|
|
3451
|
-
|
|
3452
|
-
|
|
3417
|
+
append(data) {
|
|
3418
|
+
this.cursor.writePath([
|
|
3453
3419
|
new ArrayListAppend,
|
|
3454
3420
|
new WriteData(data)
|
|
3455
3421
|
]);
|
|
3456
3422
|
}
|
|
3457
|
-
|
|
3423
|
+
appendCursor() {
|
|
3458
3424
|
return this.cursor.writePath([new ArrayListAppend]);
|
|
3459
3425
|
}
|
|
3460
|
-
|
|
3461
|
-
|
|
3426
|
+
appendContext(data, fn) {
|
|
3427
|
+
this.cursor.writePath([
|
|
3462
3428
|
new ArrayListAppend,
|
|
3463
3429
|
new WriteData(data),
|
|
3464
3430
|
new Context(fn)
|
|
3465
3431
|
]);
|
|
3466
3432
|
}
|
|
3467
|
-
|
|
3468
|
-
|
|
3433
|
+
slice(size) {
|
|
3434
|
+
this.cursor.writePath([new ArrayListSlice(size)]);
|
|
3469
3435
|
}
|
|
3470
3436
|
}
|
|
3471
3437
|
// src/read-hash-map.ts
|
|
@@ -3487,38 +3453,38 @@ class ReadHashMap {
|
|
|
3487
3453
|
slot() {
|
|
3488
3454
|
return this.cursor.slot();
|
|
3489
3455
|
}
|
|
3490
|
-
|
|
3456
|
+
iterator() {
|
|
3491
3457
|
return this.cursor.iterator();
|
|
3492
3458
|
}
|
|
3493
|
-
|
|
3459
|
+
*[Symbol.iterator]() {
|
|
3494
3460
|
yield* this.cursor;
|
|
3495
3461
|
}
|
|
3496
|
-
|
|
3497
|
-
const hash =
|
|
3462
|
+
getCursor(key) {
|
|
3463
|
+
const hash = this.resolveHash(key);
|
|
3498
3464
|
return this.cursor.readPath([new HashMapGet(new HashMapGetValue(hash))]);
|
|
3499
3465
|
}
|
|
3500
|
-
|
|
3501
|
-
const hash =
|
|
3466
|
+
getSlot(key) {
|
|
3467
|
+
const hash = this.resolveHash(key);
|
|
3502
3468
|
return this.cursor.readPathSlot([new HashMapGet(new HashMapGetValue(hash))]);
|
|
3503
3469
|
}
|
|
3504
|
-
|
|
3505
|
-
const hash =
|
|
3470
|
+
getKeyCursor(key) {
|
|
3471
|
+
const hash = this.resolveHash(key);
|
|
3506
3472
|
return this.cursor.readPath([new HashMapGet(new HashMapGetKey(hash))]);
|
|
3507
3473
|
}
|
|
3508
|
-
|
|
3509
|
-
const hash =
|
|
3474
|
+
getKeySlot(key) {
|
|
3475
|
+
const hash = this.resolveHash(key);
|
|
3510
3476
|
return this.cursor.readPathSlot([new HashMapGet(new HashMapGetKey(hash))]);
|
|
3511
3477
|
}
|
|
3512
|
-
|
|
3513
|
-
const hash =
|
|
3514
|
-
const cursor =
|
|
3478
|
+
getKeyValuePair(key) {
|
|
3479
|
+
const hash = this.resolveHash(key);
|
|
3480
|
+
const cursor = this.cursor.readPath([new HashMapGet(new HashMapGetKVPair(hash))]);
|
|
3515
3481
|
if (cursor === null) {
|
|
3516
3482
|
return null;
|
|
3517
3483
|
} else {
|
|
3518
3484
|
return cursor.readKeyValuePair();
|
|
3519
3485
|
}
|
|
3520
3486
|
}
|
|
3521
|
-
|
|
3487
|
+
resolveHash(key) {
|
|
3522
3488
|
if (key instanceof Uint8Array) {
|
|
3523
3489
|
return key;
|
|
3524
3490
|
} else if (typeof key === "string") {
|
|
@@ -3530,59 +3496,54 @@ class ReadHashMap {
|
|
|
3530
3496
|
}
|
|
3531
3497
|
// src/write-hash-map.ts
|
|
3532
3498
|
class WriteHashMap extends ReadHashMap {
|
|
3533
|
-
constructor() {
|
|
3499
|
+
constructor(cursor, counted = false) {
|
|
3534
3500
|
super();
|
|
3501
|
+
this.cursor = cursor.writePath([new HashMapInit(counted, false)]);
|
|
3535
3502
|
}
|
|
3536
|
-
|
|
3537
|
-
const map = new WriteHashMap;
|
|
3538
|
-
const newCursor = await cursor.writePath([new HashMapInit(false, false)]);
|
|
3539
|
-
map.cursor = newCursor;
|
|
3540
|
-
return map;
|
|
3541
|
-
}
|
|
3542
|
-
async iterator() {
|
|
3503
|
+
iterator() {
|
|
3543
3504
|
return this.cursor.iterator();
|
|
3544
3505
|
}
|
|
3545
|
-
|
|
3506
|
+
*[Symbol.iterator]() {
|
|
3546
3507
|
yield* this.cursor;
|
|
3547
3508
|
}
|
|
3548
|
-
|
|
3509
|
+
put(key, data) {
|
|
3549
3510
|
if (typeof key === "string") {
|
|
3550
|
-
const hash =
|
|
3551
|
-
|
|
3552
|
-
|
|
3511
|
+
const hash = this.cursor.db.hasher.digest(new TextEncoder().encode(key));
|
|
3512
|
+
this.putKeyInternal(hash, new Bytes(key));
|
|
3513
|
+
this.putInternal(hash, data);
|
|
3553
3514
|
} else if (key instanceof Bytes) {
|
|
3554
|
-
const hash =
|
|
3555
|
-
|
|
3556
|
-
|
|
3515
|
+
const hash = this.cursor.db.hasher.digest(key.value);
|
|
3516
|
+
this.putKeyInternal(hash, key);
|
|
3517
|
+
this.putInternal(hash, data);
|
|
3557
3518
|
} else {
|
|
3558
|
-
|
|
3519
|
+
this.putInternal(key, data);
|
|
3559
3520
|
}
|
|
3560
3521
|
}
|
|
3561
|
-
|
|
3522
|
+
putCursor(key) {
|
|
3562
3523
|
if (typeof key === "string") {
|
|
3563
|
-
const hash =
|
|
3564
|
-
|
|
3524
|
+
const hash = this.cursor.db.hasher.digest(new TextEncoder().encode(key));
|
|
3525
|
+
this.putKeyInternal(hash, new Bytes(key));
|
|
3565
3526
|
return this.putCursorInternal(hash);
|
|
3566
3527
|
} else if (key instanceof Bytes) {
|
|
3567
|
-
const hash =
|
|
3568
|
-
|
|
3528
|
+
const hash = this.cursor.db.hasher.digest(key.value);
|
|
3529
|
+
this.putKeyInternal(hash, key);
|
|
3569
3530
|
return this.putCursorInternal(hash);
|
|
3570
3531
|
} else {
|
|
3571
3532
|
return this.putCursorInternal(key);
|
|
3572
3533
|
}
|
|
3573
3534
|
}
|
|
3574
|
-
|
|
3575
|
-
const hash =
|
|
3576
|
-
|
|
3535
|
+
putKey(key, data) {
|
|
3536
|
+
const hash = this.resolveHash(key);
|
|
3537
|
+
this.putKeyInternal(hash, data);
|
|
3577
3538
|
}
|
|
3578
|
-
|
|
3579
|
-
const hash =
|
|
3539
|
+
putKeyCursor(key) {
|
|
3540
|
+
const hash = this.resolveHash(key);
|
|
3580
3541
|
return this.putKeyCursorInternal(hash);
|
|
3581
3542
|
}
|
|
3582
|
-
|
|
3583
|
-
const hash =
|
|
3543
|
+
remove(key) {
|
|
3544
|
+
const hash = this.resolveHash(key);
|
|
3584
3545
|
try {
|
|
3585
|
-
|
|
3546
|
+
this.cursor.writePath([new HashMapRemove(hash)]);
|
|
3586
3547
|
} catch (e) {
|
|
3587
3548
|
if (e instanceof KeyNotFoundException) {
|
|
3588
3549
|
return false;
|
|
@@ -3591,24 +3552,24 @@ class WriteHashMap extends ReadHashMap {
|
|
|
3591
3552
|
}
|
|
3592
3553
|
return true;
|
|
3593
3554
|
}
|
|
3594
|
-
|
|
3595
|
-
|
|
3555
|
+
putInternal(hash, data) {
|
|
3556
|
+
this.cursor.writePath([
|
|
3596
3557
|
new HashMapGet(new HashMapGetValue(hash)),
|
|
3597
3558
|
new WriteData(data)
|
|
3598
3559
|
]);
|
|
3599
3560
|
}
|
|
3600
|
-
|
|
3561
|
+
putCursorInternal(hash) {
|
|
3601
3562
|
return this.cursor.writePath([
|
|
3602
3563
|
new HashMapGet(new HashMapGetValue(hash))
|
|
3603
3564
|
]);
|
|
3604
3565
|
}
|
|
3605
|
-
|
|
3606
|
-
const cursor =
|
|
3566
|
+
putKeyInternal(hash, data) {
|
|
3567
|
+
const cursor = this.cursor.writePath([
|
|
3607
3568
|
new HashMapGet(new HashMapGetKey(hash))
|
|
3608
3569
|
]);
|
|
3609
|
-
|
|
3570
|
+
cursor.writeIfEmpty(data);
|
|
3610
3571
|
}
|
|
3611
|
-
|
|
3572
|
+
putKeyCursorInternal(hash) {
|
|
3612
3573
|
return this.cursor.writePath([
|
|
3613
3574
|
new HashMapGet(new HashMapGetKey(hash))
|
|
3614
3575
|
]);
|
|
@@ -3633,21 +3594,21 @@ class ReadHashSet {
|
|
|
3633
3594
|
slot() {
|
|
3634
3595
|
return this.cursor.slot();
|
|
3635
3596
|
}
|
|
3636
|
-
|
|
3597
|
+
iterator() {
|
|
3637
3598
|
return this.cursor.iterator();
|
|
3638
3599
|
}
|
|
3639
|
-
|
|
3600
|
+
*[Symbol.iterator]() {
|
|
3640
3601
|
yield* this.cursor;
|
|
3641
3602
|
}
|
|
3642
|
-
|
|
3643
|
-
const hash =
|
|
3603
|
+
getCursor(key) {
|
|
3604
|
+
const hash = this.resolveHash(key);
|
|
3644
3605
|
return this.cursor.readPath([new HashMapGet(new HashMapGetKey(hash))]);
|
|
3645
3606
|
}
|
|
3646
|
-
|
|
3647
|
-
const hash =
|
|
3607
|
+
getSlot(key) {
|
|
3608
|
+
const hash = this.resolveHash(key);
|
|
3648
3609
|
return this.cursor.readPathSlot([new HashMapGet(new HashMapGetKey(hash))]);
|
|
3649
3610
|
}
|
|
3650
|
-
|
|
3611
|
+
resolveHash(key) {
|
|
3651
3612
|
if (key instanceof Uint8Array) {
|
|
3652
3613
|
return key;
|
|
3653
3614
|
} else if (typeof key === "string") {
|
|
@@ -3659,41 +3620,36 @@ class ReadHashSet {
|
|
|
3659
3620
|
}
|
|
3660
3621
|
// src/write-hash-set.ts
|
|
3661
3622
|
class WriteHashSet extends ReadHashSet {
|
|
3662
|
-
constructor() {
|
|
3623
|
+
constructor(cursor, counted = false) {
|
|
3663
3624
|
super();
|
|
3625
|
+
this.cursor = cursor.writePath([new HashMapInit(counted, true)]);
|
|
3664
3626
|
}
|
|
3665
|
-
|
|
3666
|
-
const set = new WriteHashSet;
|
|
3667
|
-
const newCursor = await cursor.writePath([new HashMapInit(false, true)]);
|
|
3668
|
-
set.cursor = newCursor;
|
|
3669
|
-
return set;
|
|
3670
|
-
}
|
|
3671
|
-
async iterator() {
|
|
3627
|
+
iterator() {
|
|
3672
3628
|
return this.cursor.iterator();
|
|
3673
3629
|
}
|
|
3674
|
-
|
|
3630
|
+
*[Symbol.iterator]() {
|
|
3675
3631
|
yield* this.cursor;
|
|
3676
3632
|
}
|
|
3677
|
-
|
|
3633
|
+
put(key, data) {
|
|
3678
3634
|
if (typeof key === "string") {
|
|
3679
3635
|
const bytes = new TextEncoder().encode(key);
|
|
3680
|
-
const hash =
|
|
3681
|
-
|
|
3636
|
+
const hash = this.cursor.db.hasher.digest(bytes);
|
|
3637
|
+
this.putInternal(hash, new Bytes(bytes));
|
|
3682
3638
|
} else if (key instanceof Bytes) {
|
|
3683
|
-
const hash =
|
|
3684
|
-
|
|
3639
|
+
const hash = this.cursor.db.hasher.digest(key.value);
|
|
3640
|
+
this.putInternal(hash, key);
|
|
3685
3641
|
} else {
|
|
3686
|
-
|
|
3642
|
+
this.putInternal(key, data);
|
|
3687
3643
|
}
|
|
3688
3644
|
}
|
|
3689
|
-
|
|
3690
|
-
const hash =
|
|
3645
|
+
putCursor(key) {
|
|
3646
|
+
const hash = this.resolveHash(key);
|
|
3691
3647
|
return this.putCursorInternal(hash);
|
|
3692
3648
|
}
|
|
3693
|
-
|
|
3694
|
-
const hash =
|
|
3649
|
+
remove(key) {
|
|
3650
|
+
const hash = this.resolveHash(key);
|
|
3695
3651
|
try {
|
|
3696
|
-
|
|
3652
|
+
this.cursor.writePath([new HashMapRemove(hash)]);
|
|
3697
3653
|
} catch (e) {
|
|
3698
3654
|
if (e instanceof KeyNotFoundException) {
|
|
3699
3655
|
return false;
|
|
@@ -3702,13 +3658,13 @@ class WriteHashSet extends ReadHashSet {
|
|
|
3702
3658
|
}
|
|
3703
3659
|
return true;
|
|
3704
3660
|
}
|
|
3705
|
-
|
|
3706
|
-
const cursor =
|
|
3661
|
+
putInternal(hash, data) {
|
|
3662
|
+
const cursor = this.cursor.writePath([
|
|
3707
3663
|
new HashMapGet(new HashMapGetKey(hash))
|
|
3708
3664
|
]);
|
|
3709
|
-
|
|
3665
|
+
cursor.writeIfEmpty(data);
|
|
3710
3666
|
}
|
|
3711
|
-
|
|
3667
|
+
putCursorInternal(hash) {
|
|
3712
3668
|
return this.cursor.writePath([
|
|
3713
3669
|
new HashMapGet(new HashMapGetKey(hash))
|
|
3714
3670
|
]);
|
|
@@ -3732,76 +3688,71 @@ class ReadLinkedArrayList {
|
|
|
3732
3688
|
slot() {
|
|
3733
3689
|
return this.cursor.slot();
|
|
3734
3690
|
}
|
|
3735
|
-
|
|
3691
|
+
count() {
|
|
3736
3692
|
return this.cursor.count();
|
|
3737
3693
|
}
|
|
3738
|
-
|
|
3694
|
+
iterator() {
|
|
3739
3695
|
return this.cursor.iterator();
|
|
3740
3696
|
}
|
|
3741
|
-
|
|
3697
|
+
*[Symbol.iterator]() {
|
|
3742
3698
|
yield* this.cursor;
|
|
3743
3699
|
}
|
|
3744
|
-
|
|
3700
|
+
getCursor(index) {
|
|
3745
3701
|
return this.cursor.readPath([new LinkedArrayListGet(index)]);
|
|
3746
3702
|
}
|
|
3747
|
-
|
|
3703
|
+
getSlot(index) {
|
|
3748
3704
|
return this.cursor.readPathSlot([new LinkedArrayListGet(index)]);
|
|
3749
3705
|
}
|
|
3750
3706
|
}
|
|
3751
3707
|
// src/write-linked-array-list.ts
|
|
3752
3708
|
class WriteLinkedArrayList extends ReadLinkedArrayList {
|
|
3753
|
-
constructor() {
|
|
3709
|
+
constructor(cursor) {
|
|
3754
3710
|
super();
|
|
3711
|
+
this.cursor = cursor.writePath([new LinkedArrayListInit]);
|
|
3755
3712
|
}
|
|
3756
|
-
|
|
3757
|
-
const list = new WriteLinkedArrayList;
|
|
3758
|
-
const newCursor = await cursor.writePath([new LinkedArrayListInit]);
|
|
3759
|
-
list.cursor = newCursor;
|
|
3760
|
-
return list;
|
|
3761
|
-
}
|
|
3762
|
-
async iterator() {
|
|
3713
|
+
iterator() {
|
|
3763
3714
|
return this.cursor.iterator();
|
|
3764
3715
|
}
|
|
3765
|
-
|
|
3716
|
+
*[Symbol.iterator]() {
|
|
3766
3717
|
yield* this.cursor;
|
|
3767
3718
|
}
|
|
3768
|
-
|
|
3769
|
-
|
|
3719
|
+
put(index, data) {
|
|
3720
|
+
this.cursor.writePath([
|
|
3770
3721
|
new LinkedArrayListGet(index),
|
|
3771
3722
|
new WriteData(data)
|
|
3772
3723
|
]);
|
|
3773
3724
|
}
|
|
3774
|
-
|
|
3725
|
+
putCursor(index) {
|
|
3775
3726
|
return this.cursor.writePath([new LinkedArrayListGet(index)]);
|
|
3776
3727
|
}
|
|
3777
|
-
|
|
3778
|
-
|
|
3728
|
+
append(data) {
|
|
3729
|
+
this.cursor.writePath([
|
|
3779
3730
|
new LinkedArrayListAppend,
|
|
3780
3731
|
new WriteData(data)
|
|
3781
3732
|
]);
|
|
3782
3733
|
}
|
|
3783
|
-
|
|
3734
|
+
appendCursor() {
|
|
3784
3735
|
return this.cursor.writePath([new LinkedArrayListAppend]);
|
|
3785
3736
|
}
|
|
3786
|
-
|
|
3787
|
-
|
|
3737
|
+
slice(offset, size) {
|
|
3738
|
+
this.cursor.writePath([
|
|
3788
3739
|
new LinkedArrayListSlice(offset, size)
|
|
3789
3740
|
]);
|
|
3790
3741
|
}
|
|
3791
|
-
|
|
3792
|
-
|
|
3742
|
+
concat(list) {
|
|
3743
|
+
this.cursor.writePath([new LinkedArrayListConcat(list)]);
|
|
3793
3744
|
}
|
|
3794
|
-
|
|
3795
|
-
|
|
3745
|
+
insert(index, data) {
|
|
3746
|
+
this.cursor.writePath([
|
|
3796
3747
|
new LinkedArrayListInsert(index),
|
|
3797
3748
|
new WriteData(data)
|
|
3798
3749
|
]);
|
|
3799
3750
|
}
|
|
3800
|
-
|
|
3751
|
+
insertCursor(index) {
|
|
3801
3752
|
return this.cursor.writePath([new LinkedArrayListInsert(index)]);
|
|
3802
3753
|
}
|
|
3803
|
-
|
|
3804
|
-
|
|
3754
|
+
remove(index) {
|
|
3755
|
+
this.cursor.writePath([new LinkedArrayListRemove(index)]);
|
|
3805
3756
|
}
|
|
3806
3757
|
}
|
|
3807
3758
|
// src/read-counted-hash-map.ts
|
|
@@ -3818,31 +3769,24 @@ class ReadCountedHashMap extends ReadHashMap {
|
|
|
3818
3769
|
throw new UnexpectedTagException;
|
|
3819
3770
|
}
|
|
3820
3771
|
}
|
|
3821
|
-
|
|
3772
|
+
count() {
|
|
3822
3773
|
return this.cursor.count();
|
|
3823
3774
|
}
|
|
3824
3775
|
}
|
|
3825
3776
|
// src/write-counted-hash-map.ts
|
|
3826
3777
|
class WriteCountedHashMap extends WriteHashMap {
|
|
3827
|
-
constructor() {
|
|
3828
|
-
super();
|
|
3829
|
-
}
|
|
3830
|
-
static async create(cursor) {
|
|
3831
|
-
const map = new WriteCountedHashMap;
|
|
3778
|
+
constructor(cursor) {
|
|
3832
3779
|
switch (cursor.slotPtr.slot.tag) {
|
|
3833
3780
|
case 0 /* NONE */:
|
|
3834
3781
|
case 12 /* COUNTED_HASH_MAP */:
|
|
3835
|
-
case 13 /* COUNTED_HASH_SET */:
|
|
3836
|
-
|
|
3837
|
-
map.cursor = newCursor;
|
|
3782
|
+
case 13 /* COUNTED_HASH_SET */:
|
|
3783
|
+
super(cursor, true);
|
|
3838
3784
|
break;
|
|
3839
|
-
}
|
|
3840
3785
|
default:
|
|
3841
3786
|
throw new UnexpectedTagException;
|
|
3842
3787
|
}
|
|
3843
|
-
return map;
|
|
3844
3788
|
}
|
|
3845
|
-
|
|
3789
|
+
count() {
|
|
3846
3790
|
return this.cursor.count();
|
|
3847
3791
|
}
|
|
3848
3792
|
}
|
|
@@ -3860,31 +3804,24 @@ class ReadCountedHashSet extends ReadHashSet {
|
|
|
3860
3804
|
throw new UnexpectedTagException;
|
|
3861
3805
|
}
|
|
3862
3806
|
}
|
|
3863
|
-
|
|
3807
|
+
count() {
|
|
3864
3808
|
return this.cursor.count();
|
|
3865
3809
|
}
|
|
3866
3810
|
}
|
|
3867
3811
|
// src/write-counted-hash-set.ts
|
|
3868
3812
|
class WriteCountedHashSet extends WriteHashSet {
|
|
3869
|
-
constructor() {
|
|
3870
|
-
super();
|
|
3871
|
-
}
|
|
3872
|
-
static async create(cursor) {
|
|
3873
|
-
const set = new WriteCountedHashSet;
|
|
3813
|
+
constructor(cursor) {
|
|
3874
3814
|
switch (cursor.slotPtr.slot.tag) {
|
|
3875
3815
|
case 0 /* NONE */:
|
|
3876
3816
|
case 12 /* COUNTED_HASH_MAP */:
|
|
3877
|
-
case 13 /* COUNTED_HASH_SET */:
|
|
3878
|
-
|
|
3879
|
-
set.cursor = newCursor;
|
|
3817
|
+
case 13 /* COUNTED_HASH_SET */:
|
|
3818
|
+
super(cursor, true);
|
|
3880
3819
|
break;
|
|
3881
|
-
}
|
|
3882
3820
|
default:
|
|
3883
3821
|
throw new UnexpectedTagException;
|
|
3884
3822
|
}
|
|
3885
|
-
return set;
|
|
3886
3823
|
}
|
|
3887
|
-
|
|
3824
|
+
count() {
|
|
3888
3825
|
return this.cursor.count();
|
|
3889
3826
|
}
|
|
3890
3827
|
}
|