@nxtedition/rocksdb 7.1.34 → 8.0.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/BUILDING.md +2 -2
- package/binding.cc +0 -147
- package/index.js +0 -192
- package/package.json +2 -4
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/common.js +0 -7
package/BUILDING.md
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
- Copy `libfolly.a` to `/usr/lib/x86_64-linux-gnu`.
|
|
11
11
|
- Copy headers to `/usr/lib/x86_64-linux-gnu/include`.
|
|
12
12
|
- Copy boost headers from folly scratchpad to `/usr/lib/x86_64-linux-gnu/include`.
|
|
13
|
-
- `npx prebuildify -t
|
|
13
|
+
- `npx prebuildify -t 18.11.0 --napi --strip --arch x64`
|
|
14
14
|
|
|
15
15
|
# OSX
|
|
16
16
|
|
|
17
17
|
- `brew install zstd`
|
|
18
|
-
- `npx prebuildify -t
|
|
18
|
+
- `npx prebuildify -t 18.11.0 --napi --strip --arch arm64`
|
package/binding.cc
CHANGED
|
@@ -38,7 +38,6 @@ class NullLogger : public rocksdb::Logger {
|
|
|
38
38
|
|
|
39
39
|
struct Database;
|
|
40
40
|
struct Iterator;
|
|
41
|
-
struct Updates;
|
|
42
41
|
|
|
43
42
|
struct ColumnFamily {
|
|
44
43
|
napi_ref ref;
|
|
@@ -254,48 +253,6 @@ struct BatchIterator : public rocksdb::WriteBatch::Handler {
|
|
|
254
253
|
std::vector<BatchEntry> cache_;
|
|
255
254
|
};
|
|
256
255
|
|
|
257
|
-
struct Updates : public BatchIterator, public Closable {
|
|
258
|
-
Updates(Database* database,
|
|
259
|
-
const int64_t seqNumber,
|
|
260
|
-
const bool keys,
|
|
261
|
-
const bool values,
|
|
262
|
-
const bool data,
|
|
263
|
-
const rocksdb::ColumnFamilyHandle* column,
|
|
264
|
-
const Encoding keyEncoding,
|
|
265
|
-
const Encoding valueEncoding)
|
|
266
|
-
: BatchIterator(database, keys, values, data, column, keyEncoding, valueEncoding),
|
|
267
|
-
database_(database),
|
|
268
|
-
start_(seqNumber) {}
|
|
269
|
-
|
|
270
|
-
virtual ~Updates() { assert(!iterator_); }
|
|
271
|
-
|
|
272
|
-
rocksdb::Status Close() override {
|
|
273
|
-
iterator_.reset();
|
|
274
|
-
return rocksdb::Status::OK();
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
napi_status Attach(napi_env env, napi_value context) {
|
|
278
|
-
NAPI_STATUS_RETURN(napi_create_reference(env, context, 1, &ref_));
|
|
279
|
-
database_->closables.insert(this);
|
|
280
|
-
return napi_ok;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
napi_status Detach(napi_env env) {
|
|
284
|
-
database_->closables.erase(this);
|
|
285
|
-
if (ref_) {
|
|
286
|
-
NAPI_STATUS_RETURN(napi_delete_reference(env, ref_));
|
|
287
|
-
}
|
|
288
|
-
return napi_ok;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
Database* database_;
|
|
292
|
-
int64_t start_;
|
|
293
|
-
std::unique_ptr<rocksdb::TransactionLogIterator> iterator_;
|
|
294
|
-
|
|
295
|
-
private:
|
|
296
|
-
napi_ref ref_ = nullptr;
|
|
297
|
-
};
|
|
298
|
-
|
|
299
256
|
struct BaseIterator : public Closable {
|
|
300
257
|
BaseIterator(Database* database,
|
|
301
258
|
rocksdb::ColumnFamilyHandle* column,
|
|
@@ -850,106 +807,6 @@ NAPI_METHOD(db_close) {
|
|
|
850
807
|
return 0;
|
|
851
808
|
}
|
|
852
809
|
|
|
853
|
-
NAPI_METHOD(updates_init) {
|
|
854
|
-
NAPI_ARGV(2);
|
|
855
|
-
|
|
856
|
-
Database* database;
|
|
857
|
-
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&database)));
|
|
858
|
-
|
|
859
|
-
const auto options = argv[1];
|
|
860
|
-
|
|
861
|
-
int64_t since = 0;
|
|
862
|
-
NAPI_STATUS_THROWS(GetProperty(env, options, "since", since));
|
|
863
|
-
|
|
864
|
-
bool keys = true;
|
|
865
|
-
NAPI_STATUS_THROWS(GetProperty(env, options, "keys", keys));
|
|
866
|
-
|
|
867
|
-
bool values = true;
|
|
868
|
-
NAPI_STATUS_THROWS(GetProperty(env, options, "values", values));
|
|
869
|
-
|
|
870
|
-
bool data = true;
|
|
871
|
-
NAPI_STATUS_THROWS(GetProperty(env, options, "data", data));
|
|
872
|
-
|
|
873
|
-
Encoding keyEncoding = Encoding::String;
|
|
874
|
-
NAPI_STATUS_THROWS(GetProperty(env, options, "keyEncoding", keyEncoding));
|
|
875
|
-
|
|
876
|
-
Encoding valueEncoding = Encoding::String;
|
|
877
|
-
NAPI_STATUS_THROWS(GetProperty(env, options, "valueEncoding", valueEncoding));
|
|
878
|
-
|
|
879
|
-
rocksdb::ColumnFamilyHandle* column = nullptr;
|
|
880
|
-
NAPI_STATUS_THROWS(GetProperty(env, options, "column", column));
|
|
881
|
-
|
|
882
|
-
auto updates =
|
|
883
|
-
std::unique_ptr<Updates>(new Updates(database, since, keys, values, data, column, keyEncoding, valueEncoding));
|
|
884
|
-
|
|
885
|
-
napi_value result;
|
|
886
|
-
NAPI_STATUS_THROWS(napi_create_external(env, updates.get(), Finalize<Updates>, updates.get(), &result));
|
|
887
|
-
|
|
888
|
-
// Prevent GC of JS object before the iterator is closed (explicitly or on
|
|
889
|
-
// db close) and keep track of non-closed iterators to end them on db close.
|
|
890
|
-
NAPI_STATUS_THROWS(updates.release()->Attach(env, result));
|
|
891
|
-
|
|
892
|
-
return result;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
NAPI_METHOD(updates_next) {
|
|
896
|
-
NAPI_ARGV(2);
|
|
897
|
-
|
|
898
|
-
Updates* updates;
|
|
899
|
-
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&updates)));
|
|
900
|
-
|
|
901
|
-
auto callback = argv[1];
|
|
902
|
-
|
|
903
|
-
runAsync<rocksdb::BatchResult>(
|
|
904
|
-
"leveldown.updates.next", env, callback,
|
|
905
|
-
[=](auto& batchResult) {
|
|
906
|
-
if (!updates->iterator_) {
|
|
907
|
-
rocksdb::TransactionLogIterator::ReadOptions options;
|
|
908
|
-
const auto status = updates->database_->db->GetUpdatesSince(updates->start_, &updates->iterator_, options);
|
|
909
|
-
if (!status.ok()) {
|
|
910
|
-
return status;
|
|
911
|
-
}
|
|
912
|
-
} else if (updates->iterator_->Valid()) {
|
|
913
|
-
updates->iterator_->Next();
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
if (!updates->iterator_->Valid() || !updates->iterator_->status().ok()) {
|
|
917
|
-
return updates->iterator_->status();
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
batchResult = updates->iterator_->GetBatch();
|
|
921
|
-
|
|
922
|
-
return rocksdb::Status::OK();
|
|
923
|
-
},
|
|
924
|
-
[=](auto& batchResult, auto env, auto& argv) {
|
|
925
|
-
if (!batchResult.writeBatchPtr) {
|
|
926
|
-
return napi_ok;
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
argv.resize(5);
|
|
930
|
-
NAPI_STATUS_RETURN(updates->Iterate(env, *batchResult.writeBatchPtr, &argv[1]));
|
|
931
|
-
NAPI_STATUS_RETURN(napi_create_int64(env, batchResult.sequence, &argv[2]));
|
|
932
|
-
NAPI_STATUS_RETURN(napi_create_int64(env, batchResult.writeBatchPtr->Count(), &argv[3]));
|
|
933
|
-
NAPI_STATUS_RETURN(napi_create_int64(env, updates->start_, &argv[4]));
|
|
934
|
-
|
|
935
|
-
return napi_ok;
|
|
936
|
-
});
|
|
937
|
-
|
|
938
|
-
return 0;
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
NAPI_METHOD(updates_close) {
|
|
942
|
-
NAPI_ARGV(1);
|
|
943
|
-
|
|
944
|
-
Updates* updates;
|
|
945
|
-
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&updates)));
|
|
946
|
-
|
|
947
|
-
ROCKS_STATUS_THROWS_NAPI(updates->Close());
|
|
948
|
-
NAPI_STATUS_THROWS(updates->Detach(env));
|
|
949
|
-
|
|
950
|
-
return 0;
|
|
951
|
-
}
|
|
952
|
-
|
|
953
810
|
NAPI_METHOD(db_get_many) {
|
|
954
811
|
NAPI_ARGV(4);
|
|
955
812
|
|
|
@@ -1731,10 +1588,6 @@ NAPI_INIT() {
|
|
|
1731
1588
|
NAPI_EXPORT_FUNCTION(iterator_nextv);
|
|
1732
1589
|
NAPI_EXPORT_FUNCTION(iterator_get_sequence);
|
|
1733
1590
|
|
|
1734
|
-
NAPI_EXPORT_FUNCTION(updates_init);
|
|
1735
|
-
NAPI_EXPORT_FUNCTION(updates_close);
|
|
1736
|
-
NAPI_EXPORT_FUNCTION(updates_next);
|
|
1737
|
-
|
|
1738
1591
|
NAPI_EXPORT_FUNCTION(batch_do);
|
|
1739
1592
|
NAPI_EXPORT_FUNCTION(batch_init);
|
|
1740
1593
|
NAPI_EXPORT_FUNCTION(batch_put);
|
package/index.js
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { fromCallback } = require('catering')
|
|
4
|
-
const { AbortError } = require('./common')
|
|
5
4
|
const { AbstractLevel } = require('abstract-level')
|
|
6
5
|
const ModuleError = require('module-error')
|
|
7
6
|
const fs = require('fs')
|
|
8
7
|
const binding = require('./binding')
|
|
9
8
|
const { ChainedBatch } = require('./chained-batch')
|
|
10
9
|
const { Iterator } = require('./iterator')
|
|
11
|
-
const { Readable } = require('readable-stream')
|
|
12
10
|
const os = require('os')
|
|
13
|
-
const AbortController = require('abort-controller')
|
|
14
11
|
|
|
15
12
|
const kContext = Symbol('context')
|
|
16
13
|
const kColumns = Symbol('columns')
|
|
17
14
|
const kLocation = Symbol('location')
|
|
18
15
|
const kPromise = Symbol('promise')
|
|
19
|
-
const kUpdates = Symbol('updates')
|
|
20
16
|
const kRef = Symbol('ref')
|
|
21
17
|
const kUnref = Symbol('unref')
|
|
22
18
|
const kRefs = Symbol('refs')
|
|
@@ -206,11 +202,6 @@ class RocksLevel extends AbstractLevel {
|
|
|
206
202
|
this[kRef]()
|
|
207
203
|
binding.batch_write(this[kContext], context, options, (err, sequence) => {
|
|
208
204
|
this[kUnref]()
|
|
209
|
-
|
|
210
|
-
if (!err) {
|
|
211
|
-
this.emit('update', { batch, sequence })
|
|
212
|
-
}
|
|
213
|
-
|
|
214
205
|
callback(err)
|
|
215
206
|
})
|
|
216
207
|
} catch (err) {
|
|
@@ -226,12 +217,6 @@ class RocksLevel extends AbstractLevel {
|
|
|
226
217
|
this[kRef]()
|
|
227
218
|
binding.batch_do(this[kContext], operations, options ?? EMPTY, (err, sequence) => {
|
|
228
219
|
this[kUnref]()
|
|
229
|
-
|
|
230
|
-
// TODO (fix)
|
|
231
|
-
// if (!err) {
|
|
232
|
-
// this.emit('update', { batch, sequence })
|
|
233
|
-
// }
|
|
234
|
-
|
|
235
220
|
callback(err)
|
|
236
221
|
})
|
|
237
222
|
} catch (err) {
|
|
@@ -292,183 +277,6 @@ class RocksLevel extends AbstractLevel {
|
|
|
292
277
|
}
|
|
293
278
|
}
|
|
294
279
|
|
|
295
|
-
async * updates (options) {
|
|
296
|
-
// TODO (fix): Ensure open status etc...?
|
|
297
|
-
if (this.status !== 'open') {
|
|
298
|
-
throw new Error('Database is not open')
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (this.status !== 'open') {
|
|
302
|
-
throw new ModuleError('Database is not open', {
|
|
303
|
-
code: 'LEVEL_DATABASE_NOT_OPEN'
|
|
304
|
-
})
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
options = {
|
|
308
|
-
since: options?.since ?? 0,
|
|
309
|
-
keys: options?.keys ?? true,
|
|
310
|
-
keyEncoding: options?.keyEncoding,
|
|
311
|
-
values: options?.values ?? true,
|
|
312
|
-
valueEncoding: options?.valueEncoding,
|
|
313
|
-
data: options?.data ?? true,
|
|
314
|
-
live: options?.live ?? false,
|
|
315
|
-
column: options?.column ?? null,
|
|
316
|
-
signal: options?.signal ?? null
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (typeof options.since !== 'number') {
|
|
320
|
-
throw new TypeError("'since' must be nully or a number")
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (typeof options.keys !== 'boolean') {
|
|
324
|
-
throw new TypeError("'keys' must be nully or a boolean")
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (typeof options.values !== 'boolean') {
|
|
328
|
-
throw new TypeError("'values' must be nully or a boolean")
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (typeof options.data !== 'boolean') {
|
|
332
|
-
throw new TypeError("'data' must be nully or a boolean")
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
if (options.column !== undefined && typeof options.column !== 'object') {
|
|
336
|
-
throw new TypeError("'column' must be nully or a object")
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (typeof options.live !== 'boolean') {
|
|
340
|
-
throw new TypeError("'live' must be nully or a boolean")
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
const ac = new AbortController()
|
|
344
|
-
const onAbort = () => {
|
|
345
|
-
ac.abort()
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
options.signal?.addEventListener('abort', onAbort)
|
|
349
|
-
this.on('closing', onAbort)
|
|
350
|
-
|
|
351
|
-
const db = this
|
|
352
|
-
|
|
353
|
-
try {
|
|
354
|
-
let since = (options.since ?? 0) + 1
|
|
355
|
-
while (true) {
|
|
356
|
-
const buffer = new Readable({
|
|
357
|
-
signal: ac.signal,
|
|
358
|
-
objectMode: true,
|
|
359
|
-
readableHighWaterMark: 8192,
|
|
360
|
-
construct (callback) {
|
|
361
|
-
this._next = ({ batch, sequence }) => {
|
|
362
|
-
const update = {
|
|
363
|
-
rows: batch.toArray(options),
|
|
364
|
-
count: batch.length,
|
|
365
|
-
sequence
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (!this.push(update)) {
|
|
369
|
-
this.push(null)
|
|
370
|
-
db.off('update', this._next)
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
db.on('update', this._next)
|
|
374
|
-
callback()
|
|
375
|
-
},
|
|
376
|
-
read () {},
|
|
377
|
-
destroy (err, callback) {
|
|
378
|
-
db.off('update', this._next)
|
|
379
|
-
callback(err)
|
|
380
|
-
}
|
|
381
|
-
})
|
|
382
|
-
|
|
383
|
-
if (ac.signal.aborted) {
|
|
384
|
-
throw new AbortError()
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
try {
|
|
388
|
-
if (since <= db.sequence) {
|
|
389
|
-
let first = true
|
|
390
|
-
for await (const update of db[kUpdates]({
|
|
391
|
-
...options,
|
|
392
|
-
signal: ac.signal,
|
|
393
|
-
since: Math.max(0, options.since - 8192) // TODO (fix): https://github.com/facebook/rocksdb/issues/10476
|
|
394
|
-
})) {
|
|
395
|
-
if (first) {
|
|
396
|
-
if (update.sequence > since) {
|
|
397
|
-
db.emit('warning', `Invalid updates sequence ${update.sequence} > ${options.since}.`)
|
|
398
|
-
}
|
|
399
|
-
first = false
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// TODO (Fix): What if since > sequence && since < sequence + count
|
|
403
|
-
if (update.sequence + update.count > since) {
|
|
404
|
-
yield update
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
since = update.sequence + update.count
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
} catch (err) {
|
|
411
|
-
if (err.code !== 'LEVEL_TRYAGAIN') {
|
|
412
|
-
throw err
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (!options.live) {
|
|
417
|
-
return
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
let first = true
|
|
421
|
-
for await (const update of buffer) {
|
|
422
|
-
if (first) {
|
|
423
|
-
if (update.sequence > since) {
|
|
424
|
-
db.emit('warning', `Invalid batch sequence ${update.sequence} > ${options.since}.`)
|
|
425
|
-
}
|
|
426
|
-
first = false
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// TODO (Fix): What if since > sequence && since < sequence + count
|
|
430
|
-
if (update.sequence + update.count > since) {
|
|
431
|
-
yield update
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
since = update.sequence + update.count
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
} finally {
|
|
438
|
-
this.off('closing', onAbort)
|
|
439
|
-
options.signal?.removeEventListener('abort', onAbort)
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
async * [kUpdates] ({ signal, ...options }) {
|
|
444
|
-
const context = binding.updates_init(this[kContext], options)
|
|
445
|
-
this[kRef]()
|
|
446
|
-
try {
|
|
447
|
-
while (true) {
|
|
448
|
-
if (signal?.aborted) {
|
|
449
|
-
throw new AbortError()
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
const entry = await new Promise((resolve, reject) => binding.updates_next(context, (err, rows, sequence, count) => {
|
|
453
|
-
if (err) {
|
|
454
|
-
reject(err)
|
|
455
|
-
} else {
|
|
456
|
-
resolve({ rows, sequence, count })
|
|
457
|
-
}
|
|
458
|
-
}))
|
|
459
|
-
|
|
460
|
-
if (!entry.rows) {
|
|
461
|
-
return
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
yield entry
|
|
465
|
-
}
|
|
466
|
-
} finally {
|
|
467
|
-
binding.updates_close(context)
|
|
468
|
-
this[kUnref]()
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
280
|
async flushWal (options) {
|
|
473
281
|
return new Promise((resolve, reject) => {
|
|
474
282
|
binding.db_flush_wal(this[kContext], options ?? {}, (err, val) => err ? reject(err) : resolve(val))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/rocksdb",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "A low-level Node.js RocksDB binding",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
@@ -11,13 +11,11 @@
|
|
|
11
11
|
"rebuild": "npm run install --build-from-source"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"abort-controller": "^3.0.0",
|
|
15
14
|
"abstract-level": "^1.0.2",
|
|
16
15
|
"catering": "^2.1.1",
|
|
17
16
|
"module-error": "^1.0.2",
|
|
18
17
|
"napi-macros": "~2.0.0",
|
|
19
|
-
"node-gyp-build": "^4.5.0"
|
|
20
|
-
"readable-stream": "^4.2.0"
|
|
18
|
+
"node-gyp-build": "^4.5.0"
|
|
21
19
|
},
|
|
22
20
|
"devDependencies": {
|
|
23
21
|
"@types/node": "^18.11.3",
|
|
Binary file
|