@harperfast/rocksdb-js 1.1.1 → 1.2.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 +95 -20
- package/bin/rocksdb-js.mjs +568 -0
- package/dist/index.cjs +162 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +111 -5
- package/dist/index.d.mts +111 -5
- package/dist/index.mjs +162 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -15
package/dist/index.cjs
CHANGED
|
@@ -453,42 +453,62 @@ var DBI = class DBI {
|
|
|
453
453
|
|
|
454
454
|
//#endregion
|
|
455
455
|
//#region src/dbi-iterator.ts
|
|
456
|
+
const { ITERATOR_RESULT_DONE, ITERATOR_RESULT_FAST } = constants;
|
|
457
|
+
const DONE_RESULT = Object.freeze({
|
|
458
|
+
done: true,
|
|
459
|
+
value: void 0
|
|
460
|
+
});
|
|
456
461
|
/**
|
|
457
|
-
* Wraps
|
|
458
|
-
*
|
|
462
|
+
* Wraps the `NativeIterator` C++ binding, decoding keys and values from the
|
|
463
|
+
* shared key/value buffers (fast path) or from per-iteration buffers (slow
|
|
464
|
+
* fallback path used for oversized data or stable-buffer decoders).
|
|
465
|
+
*
|
|
466
|
+
* The native `next()` returns a primitive signal (and writes lengths to the
|
|
467
|
+
* shared `ITERATOR_STATE` buffer) instead of constructing a JS result object,
|
|
468
|
+
* so this class is responsible for building the `IteratorResult`.
|
|
459
469
|
*/
|
|
460
470
|
var DBIterator = class {
|
|
461
471
|
iterator;
|
|
462
472
|
store;
|
|
463
473
|
#includeValues;
|
|
464
|
-
constructor(iterator, store,
|
|
474
|
+
constructor(iterator, store, includeValues) {
|
|
465
475
|
this.iterator = iterator;
|
|
466
476
|
this.store = store;
|
|
467
|
-
this.#includeValues =
|
|
477
|
+
this.#includeValues = includeValues;
|
|
468
478
|
}
|
|
469
479
|
[Symbol.iterator]() {
|
|
470
480
|
return this;
|
|
471
481
|
}
|
|
472
|
-
next(
|
|
482
|
+
next() {
|
|
473
483
|
const result = this.iterator.next();
|
|
474
|
-
if (result
|
|
484
|
+
if (result === ITERATOR_RESULT_DONE) return DONE_RESULT;
|
|
485
|
+
const includeValues = this.#includeValues;
|
|
475
486
|
const value = {};
|
|
476
|
-
|
|
477
|
-
|
|
487
|
+
if (result === ITERATOR_RESULT_FAST) {
|
|
488
|
+
value.key = this.store.readKey(KEY_BUFFER, 0, ITERATOR_STATE[0]);
|
|
489
|
+
if (includeValues) {
|
|
490
|
+
VALUE_BUFFER.end = ITERATOR_STATE[1];
|
|
491
|
+
value.value = this.store.decodeValue(VALUE_BUFFER);
|
|
492
|
+
}
|
|
493
|
+
} else {
|
|
494
|
+
const slow = result;
|
|
495
|
+
value.key = this.store.decodeKey(slow.key);
|
|
496
|
+
if (includeValues && slow.value !== void 0) value.value = this.store.decodeValue(slow.value);
|
|
497
|
+
}
|
|
478
498
|
return {
|
|
479
499
|
done: false,
|
|
480
500
|
value
|
|
481
501
|
};
|
|
482
502
|
}
|
|
483
503
|
return(value) {
|
|
484
|
-
|
|
504
|
+
this.iterator.return?.();
|
|
485
505
|
return {
|
|
486
506
|
done: true,
|
|
487
507
|
value
|
|
488
508
|
};
|
|
489
509
|
}
|
|
490
510
|
throw(err) {
|
|
491
|
-
|
|
511
|
+
this.iterator.throw?.(err);
|
|
492
512
|
throw err;
|
|
493
513
|
}
|
|
494
514
|
};
|
|
@@ -563,10 +583,17 @@ function createFixedBuffer(size) {
|
|
|
563
583
|
|
|
564
584
|
//#endregion
|
|
565
585
|
//#region src/store.ts
|
|
566
|
-
const { ONLY_IF_IN_MEMORY_CACHE_FLAG, NOT_IN_MEMORY_CACHE_FLAG, ALWAYS_CREATE_NEW_BUFFER_FLAG } = constants;
|
|
586
|
+
const { ONLY_IF_IN_MEMORY_CACHE_FLAG, NOT_IN_MEMORY_CACHE_FLAG, ALWAYS_CREATE_NEW_BUFFER_FLAG, ITERATOR_REVERSE_FLAG, ITERATOR_INCLUSIVE_END_FLAG, ITERATOR_EXCLUSIVE_START_FLAG, ITERATOR_INCLUDE_VALUES_FLAG, ITERATOR_NEEDS_STABLE_VALUE_BUFFER_FLAG, ITERATOR_CONTEXT_IS_TRANSACTION_FLAG } = constants;
|
|
567
587
|
const KEY_BUFFER_SIZE = 4096;
|
|
568
588
|
const KEY_BUFFER = createFixedBuffer(KEY_BUFFER_SIZE);
|
|
569
589
|
const VALUE_BUFFER = createFixedBuffer(64 * 1024);
|
|
590
|
+
/**
|
|
591
|
+
* Backing buffer for the shared iterator state. Layout (Uint32Array view):
|
|
592
|
+
* [0] = key length written into KEY_BUFFER by the most recent iterator step
|
|
593
|
+
* [1] = value length written into VALUE_BUFFER by the most recent step
|
|
594
|
+
*/
|
|
595
|
+
const ITERATOR_STATE_BUFFER = Buffer.allocUnsafeSlow(8);
|
|
596
|
+
const ITERATOR_STATE = new Uint32Array(ITERATOR_STATE_BUFFER.buffer, ITERATOR_STATE_BUFFER.byteOffset, 2);
|
|
570
597
|
const MAX_KEY_SIZE = 1024 * 1024;
|
|
571
598
|
const RESET_BUFFER_MODE = 1024;
|
|
572
599
|
const REUSE_BUFFER_MODE = 512;
|
|
@@ -745,6 +772,52 @@ var Store = class {
|
|
|
745
772
|
this.db.close();
|
|
746
773
|
}
|
|
747
774
|
/**
|
|
775
|
+
* Compacts the entire key range of the database asynchronously.
|
|
776
|
+
* This triggers manual compaction which removes tombstones and reclaims space.
|
|
777
|
+
*
|
|
778
|
+
* @example
|
|
779
|
+
* ```typescript
|
|
780
|
+
* const db = RocksDatabase.open('/path/to/database');
|
|
781
|
+
* await db.compact();
|
|
782
|
+
* ```
|
|
783
|
+
*/
|
|
784
|
+
compact(options) {
|
|
785
|
+
let startBuffer;
|
|
786
|
+
let endBuffer;
|
|
787
|
+
if (options?.start !== void 0) {
|
|
788
|
+
const start = this.encodeKey(options.start);
|
|
789
|
+
startBuffer = Buffer.from(start.subarray(start.start, start.end));
|
|
790
|
+
}
|
|
791
|
+
if (options?.end !== void 0) {
|
|
792
|
+
const end = this.encodeKey(options.end);
|
|
793
|
+
endBuffer = Buffer.from(end.subarray(end.start, end.end));
|
|
794
|
+
}
|
|
795
|
+
return new Promise((resolve, reject) => this.db.compact(resolve, reject, startBuffer, endBuffer));
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Compacts the entire key range of the database synchronously.
|
|
799
|
+
* This triggers manual compaction which removes tombstones and reclaims space.
|
|
800
|
+
*
|
|
801
|
+
* @example
|
|
802
|
+
* ```typescript
|
|
803
|
+
* const db = RocksDatabase.open('/path/to/database');
|
|
804
|
+
* db.compactSync();
|
|
805
|
+
* ```
|
|
806
|
+
*/
|
|
807
|
+
compactSync(options) {
|
|
808
|
+
let startBuffer;
|
|
809
|
+
let endBuffer;
|
|
810
|
+
if (options?.start !== void 0) {
|
|
811
|
+
const start = this.encodeKey(options.start);
|
|
812
|
+
startBuffer = Buffer.from(start.subarray(start.start, start.end));
|
|
813
|
+
}
|
|
814
|
+
if (options?.end !== void 0) {
|
|
815
|
+
const end = this.encodeKey(options.end);
|
|
816
|
+
endBuffer = Buffer.from(end.subarray(end.start, end.end));
|
|
817
|
+
}
|
|
818
|
+
this.db.compactSync(startBuffer, endBuffer);
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
748
821
|
* Decodes a key from the database.
|
|
749
822
|
*
|
|
750
823
|
* @param key - The key to decode.
|
|
@@ -832,27 +905,45 @@ var Store = class {
|
|
|
832
905
|
}
|
|
833
906
|
getRange(context, options) {
|
|
834
907
|
if (!this.db.opened) throw new Error("Database not open");
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
908
|
+
let startUnencoded = options?.key ?? options?.start;
|
|
909
|
+
let endUnencoded = options?.key ?? options?.end;
|
|
910
|
+
const includeValues = options?.values ?? true;
|
|
911
|
+
const reverse = options?.reverse ?? false;
|
|
912
|
+
let exclusiveStart = options?.exclusiveStart ?? false;
|
|
913
|
+
let inclusiveEnd = options?.inclusiveEnd ?? false;
|
|
914
|
+
if (options?.key !== void 0) inclusiveEnd = true;
|
|
915
|
+
if (reverse) {
|
|
916
|
+
const tmp = startUnencoded;
|
|
917
|
+
startUnencoded = endUnencoded;
|
|
918
|
+
endUnencoded = tmp;
|
|
919
|
+
exclusiveStart = options?.exclusiveStart ?? true;
|
|
920
|
+
inclusiveEnd = options?.inclusiveEnd ?? true;
|
|
840
921
|
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
922
|
+
const keyBuffer = this.keyBuffer;
|
|
923
|
+
let startKeyEnd = 0;
|
|
924
|
+
let endKeyStart = 0;
|
|
925
|
+
let endKeyEnd = 0;
|
|
926
|
+
if (startUnencoded !== void 0) {
|
|
927
|
+
startKeyEnd = this.writeKey(startUnencoded, keyBuffer, 0);
|
|
928
|
+
if (startKeyEnd === 0) throw new Error("Zero length key is not allowed");
|
|
847
929
|
}
|
|
848
|
-
if (
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
930
|
+
if (endUnencoded !== void 0) if (endUnencoded === startUnencoded) {
|
|
931
|
+
endKeyStart = 0;
|
|
932
|
+
endKeyEnd = startKeyEnd;
|
|
933
|
+
} else {
|
|
934
|
+
endKeyStart = startKeyEnd;
|
|
935
|
+
endKeyEnd = this.writeKey(endUnencoded, keyBuffer, endKeyStart);
|
|
936
|
+
if (endKeyEnd === endKeyStart) throw new Error("Zero length key is not allowed");
|
|
854
937
|
}
|
|
855
|
-
|
|
938
|
+
let flags = 0;
|
|
939
|
+
if (reverse) flags |= ITERATOR_REVERSE_FLAG;
|
|
940
|
+
if (exclusiveStart) flags |= ITERATOR_EXCLUSIVE_START_FLAG;
|
|
941
|
+
if (inclusiveEnd) flags |= ITERATOR_INCLUSIVE_END_FLAG;
|
|
942
|
+
if (includeValues) flags |= ITERATOR_INCLUDE_VALUES_FLAG;
|
|
943
|
+
if (includeValues && !this.decoderCopies) flags |= ITERATOR_NEEDS_STABLE_VALUE_BUFFER_FLAG;
|
|
944
|
+
if (context !== this.db) flags |= ITERATOR_CONTEXT_IS_TRANSACTION_FLAG;
|
|
945
|
+
const advancedOptions = options !== void 0 && (options.adaptiveReadahead !== void 0 || options.asyncIO !== void 0 || options.autoReadaheadSize !== void 0 || options.backgroundPurgeOnIteratorCleanup !== void 0 || options.fillCache !== void 0 || options.readaheadSize !== void 0 || options.tailing !== void 0) ? options : void 0;
|
|
946
|
+
return new _harperfast_extended_iterable.ExtendedIterable(new DBIterator(new NativeIterator(context, flags, startKeyEnd, endKeyStart, endKeyEnd, advancedOptions), this, includeValues));
|
|
856
947
|
}
|
|
857
948
|
getSync(context, key, alwaysCreateNewBuffer = false, options) {
|
|
858
949
|
const keyParam = getKeyParam(this.encodeKey(key));
|
|
@@ -1219,6 +1310,32 @@ var RocksDatabase = class RocksDatabase extends DBI {
|
|
|
1219
1310
|
this.store.close();
|
|
1220
1311
|
}
|
|
1221
1312
|
/**
|
|
1313
|
+
* Compacts the entire key range of the database asynchronously.
|
|
1314
|
+
* This triggers manual compaction which removes tombstones and reclaims space.
|
|
1315
|
+
*
|
|
1316
|
+
* @example
|
|
1317
|
+
* ```typescript
|
|
1318
|
+
* const db = RocksDatabase.open('/path/to/database');
|
|
1319
|
+
* await db.compact();
|
|
1320
|
+
* ```
|
|
1321
|
+
*/
|
|
1322
|
+
compact(options) {
|
|
1323
|
+
return this.store.compact(options);
|
|
1324
|
+
}
|
|
1325
|
+
/**
|
|
1326
|
+
* Compacts the entire key range of the database synchronously.
|
|
1327
|
+
* This triggers manual compaction which removes tombstones and reclaims space.
|
|
1328
|
+
*
|
|
1329
|
+
* @example
|
|
1330
|
+
* ```typescript
|
|
1331
|
+
* const db = RocksDatabase.open('/path/to/database');
|
|
1332
|
+
* db.compactSync();
|
|
1333
|
+
* ```
|
|
1334
|
+
*/
|
|
1335
|
+
compactSync(options) {
|
|
1336
|
+
return this.store.compactSync(options);
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1222
1339
|
* Returns the list of column families in the RocksDB database.
|
|
1223
1340
|
*/
|
|
1224
1341
|
get columns() {
|
|
@@ -1300,6 +1417,19 @@ var RocksDatabase = class RocksDatabase extends DBI {
|
|
|
1300
1417
|
return this.store.db.getDBProperty(propertyName);
|
|
1301
1418
|
}
|
|
1302
1419
|
/**
|
|
1420
|
+
* Retrieves the estimated number of keys in the database.
|
|
1421
|
+
*
|
|
1422
|
+
* @example
|
|
1423
|
+
* ```typescript
|
|
1424
|
+
* const db = RocksDatabase.open('/path/to/database');
|
|
1425
|
+
* const estimated = db.getEstimatedKeyCount();
|
|
1426
|
+
* console.log(estimated);
|
|
1427
|
+
* ```
|
|
1428
|
+
*/
|
|
1429
|
+
getEstimatedKeyCount() {
|
|
1430
|
+
return this.getDBIntProperty("rocksdb.estimate-num-keys") ?? 0;
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1303
1433
|
* Returns the current timestamp as a monotonically increasing timestamp in
|
|
1304
1434
|
* milliseconds represented as a decimal number.
|
|
1305
1435
|
*
|
|
@@ -1438,6 +1568,7 @@ var RocksDatabase = class RocksDatabase extends DBI {
|
|
|
1438
1568
|
if (store.open()) return this;
|
|
1439
1569
|
store.db.setDefaultValueBuffer(VALUE_BUFFER);
|
|
1440
1570
|
store.db.setDefaultKeyBuffer(KEY_BUFFER);
|
|
1571
|
+
store.db.setIteratorState(ITERATOR_STATE_BUFFER);
|
|
1441
1572
|
/**
|
|
1442
1573
|
* The encoder initialization precedence is:
|
|
1443
1574
|
* 1. encoder.Encoder
|
|
@@ -1809,6 +1940,7 @@ Object.defineProperty(TransactionLog.prototype, "query", { value({ start, end, e
|
|
|
1809
1940
|
logBuffer.logId = 0;
|
|
1810
1941
|
logBuffer.size = 0;
|
|
1811
1942
|
logBuffer.dataView = new DataView(logBuffer.buffer);
|
|
1943
|
+
size = 0;
|
|
1812
1944
|
}
|
|
1813
1945
|
}
|
|
1814
1946
|
dataView = logBuffer.dataView;
|
|
@@ -1936,7 +2068,7 @@ function loadLastPosition(transactionLog, readUncommitted) {
|
|
|
1936
2068
|
//#region src/index.ts
|
|
1937
2069
|
const versions = {
|
|
1938
2070
|
rocksdb: version,
|
|
1939
|
-
"rocksdb-js": "1.
|
|
2071
|
+
"rocksdb-js": "1.2.0"
|
|
1940
2072
|
};
|
|
1941
2073
|
|
|
1942
2074
|
//#endregion
|