@nxtedition/rocksdb 5.2.26 → 5.2.27
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/binding.cc +214 -532
- package/binding.gyp +1 -1
- package/chained-batch.js +1 -2
- package/deps/rocksdb/rocksdb/cmake/modules/CxxFlags.cmake +7 -0
- package/deps/rocksdb/rocksdb/cmake/modules/FindJeMalloc.cmake +29 -0
- package/deps/rocksdb/rocksdb/cmake/modules/FindNUMA.cmake +29 -0
- package/deps/rocksdb/rocksdb/cmake/modules/FindSnappy.cmake +29 -0
- package/deps/rocksdb/rocksdb/cmake/modules/FindTBB.cmake +33 -0
- package/deps/rocksdb/rocksdb/cmake/modules/Findgflags.cmake +29 -0
- package/deps/rocksdb/rocksdb/cmake/modules/Findlz4.cmake +29 -0
- package/deps/rocksdb/rocksdb/cmake/modules/Finduring.cmake +26 -0
- package/deps/rocksdb/rocksdb/cmake/modules/Findzstd.cmake +29 -0
- package/deps/rocksdb/rocksdb/cmake/modules/ReadVersion.cmake +10 -0
- package/deps/rocksdb/rocksdb.gyp +26 -26
- package/index.js +5 -87
- package/package-lock.json +23687 -0
- package/package.json +1 -2
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/{darwin-x86 → darwin-x64}/node.napi.node +0 -0
- package/deps/rocksdb/rocksdb/README.md +0 -32
- package/deps/rocksdb/rocksdb/microbench/README.md +0 -60
- package/deps/rocksdb/rocksdb/plugin/README.md +0 -43
- package/deps/rocksdb/rocksdb/port/README +0 -10
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/README +0 -13
- package/deps/snappy/snappy-1.1.7/README.md +0 -149
package/binding.cc
CHANGED
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
|
|
17
17
|
namespace leveldb = rocksdb;
|
|
18
18
|
|
|
19
|
+
#include <array>
|
|
19
20
|
#include <set>
|
|
20
21
|
#include <memory>
|
|
21
22
|
#include <string>
|
|
22
23
|
#include <vector>
|
|
24
|
+
#include <optional>
|
|
23
25
|
|
|
24
26
|
class NullLogger : public rocksdb::Logger {
|
|
25
27
|
public:
|
|
@@ -61,7 +63,7 @@ static bool IsObject (napi_env env, napi_value value) {
|
|
|
61
63
|
return type == napi_object;
|
|
62
64
|
}
|
|
63
65
|
|
|
64
|
-
static napi_value CreateError (napi_env env, const std::
|
|
66
|
+
static napi_value CreateError (napi_env env, const std::string_view& str) {
|
|
65
67
|
napi_value msg;
|
|
66
68
|
napi_create_string_utf8(env, str.data(), str.size(), &msg);
|
|
67
69
|
napi_value error;
|
|
@@ -69,7 +71,7 @@ static napi_value CreateError (napi_env env, const std::string& str) {
|
|
|
69
71
|
return error;
|
|
70
72
|
}
|
|
71
73
|
|
|
72
|
-
static napi_value CreateCodeError (napi_env env, const std::
|
|
74
|
+
static napi_value CreateCodeError (napi_env env, const std::string_view& code, const std::string_view& msg) {
|
|
73
75
|
napi_value codeValue;
|
|
74
76
|
napi_create_string_utf8(env, code.data(), code.size(), &codeValue);
|
|
75
77
|
napi_value msgValue;
|
|
@@ -79,19 +81,19 @@ static napi_value CreateCodeError (napi_env env, const std::string& code, const
|
|
|
79
81
|
return error;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
static bool HasProperty (napi_env env, napi_value obj, const std::
|
|
84
|
+
static bool HasProperty (napi_env env, napi_value obj, const std::string_view& key) {
|
|
83
85
|
bool has = false;
|
|
84
86
|
napi_has_named_property(env, obj, key.data(), &has);
|
|
85
87
|
return has;
|
|
86
88
|
}
|
|
87
89
|
|
|
88
|
-
static napi_value GetProperty (napi_env env, napi_value obj, const std::
|
|
90
|
+
static napi_value GetProperty (napi_env env, napi_value obj, const std::string_view& key) {
|
|
89
91
|
napi_value value;
|
|
90
92
|
napi_get_named_property(env, obj, key.data(), &value);
|
|
91
93
|
return value;
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
static bool BooleanProperty (napi_env env, napi_value obj, const std::
|
|
96
|
+
static bool BooleanProperty (napi_env env, napi_value obj, const std::string_view& key, bool defaultValue) {
|
|
95
97
|
if (HasProperty(env, obj, key.data())) {
|
|
96
98
|
const auto value = GetProperty(env, obj, key.data());
|
|
97
99
|
bool result;
|
|
@@ -102,7 +104,7 @@ static bool BooleanProperty (napi_env env, napi_value obj, const std::string& ke
|
|
|
102
104
|
return defaultValue;
|
|
103
105
|
}
|
|
104
106
|
|
|
105
|
-
static bool EncodingIsBuffer (napi_env env, napi_value obj, const std::
|
|
107
|
+
static bool EncodingIsBuffer (napi_env env, napi_value obj, const std::string_view& option) {
|
|
106
108
|
napi_value value;
|
|
107
109
|
size_t size;
|
|
108
110
|
|
|
@@ -115,7 +117,7 @@ static bool EncodingIsBuffer (napi_env env, napi_value obj, const std::string& o
|
|
|
115
117
|
return false;
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
static uint32_t Uint32Property (napi_env env, napi_value obj, const std::
|
|
120
|
+
static uint32_t Uint32Property (napi_env env, napi_value obj, const std::string_view& key, uint32_t defaultValue) {
|
|
119
121
|
if (HasProperty(env, obj, key.data())) {
|
|
120
122
|
const auto value = GetProperty(env, obj, key.data());
|
|
121
123
|
uint32_t result;
|
|
@@ -126,7 +128,7 @@ static uint32_t Uint32Property (napi_env env, napi_value obj, const std::string&
|
|
|
126
128
|
return defaultValue;
|
|
127
129
|
}
|
|
128
130
|
|
|
129
|
-
static int Int32Property (napi_env env, napi_value obj, const std::
|
|
131
|
+
static int Int32Property (napi_env env, napi_value obj, const std::string_view& key, int defaultValue) {
|
|
130
132
|
if (HasProperty(env, obj, key.data())) {
|
|
131
133
|
const auto value = GetProperty(env, obj, key.data());
|
|
132
134
|
int result;
|
|
@@ -142,7 +144,7 @@ static std::string ToString (napi_env env, napi_value from, const std::string& d
|
|
|
142
144
|
size_t length = 0;
|
|
143
145
|
napi_get_value_string_utf8(env, from, nullptr, 0, &length);
|
|
144
146
|
std::string value(length, '\0');
|
|
145
|
-
napi_get_value_string_utf8(
|
|
147
|
+
napi_get_value_string_utf8(env, from, &value[0], value.length() + 1, &length);
|
|
146
148
|
return value;
|
|
147
149
|
} else if (IsBuffer(env, from)) {
|
|
148
150
|
char* buf = nullptr;
|
|
@@ -154,7 +156,7 @@ static std::string ToString (napi_env env, napi_value from, const std::string& d
|
|
|
154
156
|
return defaultValue;
|
|
155
157
|
}
|
|
156
158
|
|
|
157
|
-
static std::string StringProperty (napi_env env, napi_value obj, const std::
|
|
159
|
+
static std::string StringProperty (napi_env env, napi_value obj, const std::string_view& key, const std::string& defaultValue = "") {
|
|
158
160
|
if (HasProperty(env, obj, key)) {
|
|
159
161
|
napi_value value = GetProperty(env, obj, key);
|
|
160
162
|
if (IsString(env, value)) {
|
|
@@ -178,13 +180,13 @@ static size_t StringOrBufferLength (napi_env env, napi_value value) {
|
|
|
178
180
|
return size;
|
|
179
181
|
}
|
|
180
182
|
|
|
181
|
-
static std::string
|
|
183
|
+
static std::optional<std::string> RangeOption (napi_env env, napi_value opts, const std::string_view& name) {
|
|
182
184
|
if (HasProperty(env, opts, name)) {
|
|
183
185
|
const auto value = GetProperty(env, opts, name);
|
|
184
|
-
return
|
|
186
|
+
return std::string(ToString(env, value));
|
|
185
187
|
}
|
|
186
188
|
|
|
187
|
-
return
|
|
189
|
+
return {};
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
static std::vector<std::string> KeyArray (napi_env env, napi_value arr) {
|
|
@@ -213,6 +215,32 @@ static napi_status CallFunction (napi_env env, napi_value callback, const int ar
|
|
|
213
215
|
return napi_call_function(env, global, callback, argc, argv, nullptr);
|
|
214
216
|
}
|
|
215
217
|
|
|
218
|
+
static napi_value ToError(napi_env env, const rocksdb::Status& status) {
|
|
219
|
+
if (status.ok()) {
|
|
220
|
+
return 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const auto msg = status.ToString();
|
|
224
|
+
|
|
225
|
+
if (status.IsNotFound()) {
|
|
226
|
+
return CreateCodeError(env, "LEVEL_NOT_FOUND", msg);
|
|
227
|
+
} else if (status.IsCorruption()) {
|
|
228
|
+
return CreateCodeError(env, "LEVEL_CORRUPTION", msg);
|
|
229
|
+
} else if (status.IsIOError()) {
|
|
230
|
+
if (msg.find("IO error: lock ") != std::string::npos) { // env_posix.cc
|
|
231
|
+
return CreateCodeError(env, "LEVEL_LOCKED", msg);
|
|
232
|
+
} else if (msg.find("IO error: LockFile ") != std::string::npos) { // env_win.cc
|
|
233
|
+
return CreateCodeError(env, "LEVEL_LOCKED", msg);
|
|
234
|
+
} else if (msg.find("IO error: While lock file") != std::string::npos) { // env_mac.cc
|
|
235
|
+
return CreateCodeError(env, "LEVEL_LOCKED", msg);
|
|
236
|
+
} else {
|
|
237
|
+
return CreateCodeError(env, "LEVEL_IO_ERROR", msg);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return CreateError(env, msg);
|
|
242
|
+
}
|
|
243
|
+
|
|
216
244
|
template <typename T>
|
|
217
245
|
void Convert (napi_env env, const T& s, bool asBuffer, napi_value& result) {
|
|
218
246
|
if (asBuffer) {
|
|
@@ -222,14 +250,39 @@ void Convert (napi_env env, const T& s, bool asBuffer, napi_value& result) {
|
|
|
222
250
|
}
|
|
223
251
|
}
|
|
224
252
|
|
|
253
|
+
struct NapiSlice : public rocksdb::Slice {
|
|
254
|
+
NapiSlice (napi_env env, napi_value from) {
|
|
255
|
+
if (IsString(env, from)) {
|
|
256
|
+
napi_get_value_string_utf8(env, from, nullptr, 0, &size_);
|
|
257
|
+
char* data;
|
|
258
|
+
if (size_ + 1 < stack_.size()) {
|
|
259
|
+
data = stack_.data();
|
|
260
|
+
} else {
|
|
261
|
+
heap_.reset(new char[size_ + 1]);
|
|
262
|
+
data = heap_.get();
|
|
263
|
+
}
|
|
264
|
+
data[size_] = 0;
|
|
265
|
+
napi_get_value_string_utf8(env, from, data, size_ + 1, &size_);
|
|
266
|
+
data_ = data;
|
|
267
|
+
} else if (IsBuffer(env, from)) {
|
|
268
|
+
void* data;
|
|
269
|
+
napi_get_buffer_info(env, from, &data, &size_);
|
|
270
|
+
data_ = static_cast<char*>(data);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
std::unique_ptr<char[]> heap_;
|
|
275
|
+
std::array<char, 8192> stack_;
|
|
276
|
+
};
|
|
277
|
+
|
|
225
278
|
/**
|
|
226
279
|
* Base worker class. Handles the async work. Derived classes can override the
|
|
227
280
|
* following virtual methods (listed in the order in which they're called):
|
|
228
281
|
*
|
|
229
282
|
* - Execute (abstract, worker pool thread): main work
|
|
230
|
-
* -
|
|
231
|
-
* -
|
|
232
|
-
* -
|
|
283
|
+
* - OnOk (main thread): call JS callback on success
|
|
284
|
+
* - OnError (main thread): call JS callback on error
|
|
285
|
+
* - Destroy (main thread): do cleanup regardless of success
|
|
233
286
|
*/
|
|
234
287
|
struct BaseWorker {
|
|
235
288
|
BaseWorker (napi_env env,
|
|
@@ -253,7 +306,7 @@ struct BaseWorker {
|
|
|
253
306
|
|
|
254
307
|
static void Execute (napi_env env, void* data) {
|
|
255
308
|
auto self = reinterpret_cast<BaseWorker*>(data);
|
|
256
|
-
self->status_ = self->Execute();
|
|
309
|
+
self->status_ = self->Execute(*self->database_);
|
|
257
310
|
}
|
|
258
311
|
|
|
259
312
|
static void Complete (napi_env env, napi_status status, void* data) {
|
|
@@ -263,53 +316,32 @@ struct BaseWorker {
|
|
|
263
316
|
napi_get_reference_value(env, self->callbackRef_, &callback);
|
|
264
317
|
|
|
265
318
|
if (self->status_.ok()) {
|
|
266
|
-
self->
|
|
319
|
+
self->OnOk(env, callback);
|
|
267
320
|
} else {
|
|
268
|
-
self->
|
|
321
|
+
self->OnError(env, callback, ToError(env, self->status_));
|
|
269
322
|
}
|
|
270
323
|
|
|
271
|
-
self->
|
|
324
|
+
self->Destroy(env);
|
|
325
|
+
|
|
326
|
+
napi_delete_reference(env, self->callbackRef_);
|
|
327
|
+
napi_delete_async_work(env, self->asyncWork_);
|
|
328
|
+
|
|
329
|
+
delete self;
|
|
272
330
|
}
|
|
273
331
|
|
|
274
|
-
virtual rocksdb::Status Execute () = 0;
|
|
332
|
+
virtual rocksdb::Status Execute (Database& database) = 0;
|
|
275
333
|
|
|
276
|
-
virtual void
|
|
334
|
+
virtual void OnOk (napi_env env, napi_value callback) {
|
|
277
335
|
napi_value argv;
|
|
278
336
|
napi_get_null(env, &argv);
|
|
279
337
|
CallFunction(env, callback, 1, &argv);
|
|
280
338
|
}
|
|
281
339
|
|
|
282
|
-
virtual void
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const auto msg = status_.ToString();
|
|
286
|
-
|
|
287
|
-
if (status_.IsNotFound()) {
|
|
288
|
-
argv = CreateCodeError(env, "LEVEL_NOT_FOUND", msg);
|
|
289
|
-
} else if (status_.IsCorruption()) {
|
|
290
|
-
argv = CreateCodeError(env, "LEVEL_CORRUPTION", msg);
|
|
291
|
-
} else if (status_.IsIOError()) {
|
|
292
|
-
if (msg.find("IO error: lock ") != std::string::npos) { // env_posix.cc
|
|
293
|
-
argv = CreateCodeError(env, "LEVEL_LOCKED", msg);
|
|
294
|
-
} else if (msg.find("IO error: LockFile ") != std::string::npos) { // env_win.cc
|
|
295
|
-
argv = CreateCodeError(env, "LEVEL_LOCKED", msg);
|
|
296
|
-
} else if (msg.find("IO error: While lock file") != std::string::npos) { // env_mac.cc
|
|
297
|
-
argv = CreateCodeError(env, "LEVEL_LOCKED", msg);
|
|
298
|
-
} else {
|
|
299
|
-
argv = CreateCodeError(env, "LEVEL_IO_ERROR", msg);
|
|
300
|
-
}
|
|
301
|
-
} else {
|
|
302
|
-
argv = CreateError(env, msg);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
CallFunction(env, callback, 1, &argv);
|
|
340
|
+
virtual void OnError (napi_env env, napi_value callback, napi_value err) {
|
|
341
|
+
CallFunction(env, callback, 1, &err);
|
|
306
342
|
}
|
|
307
343
|
|
|
308
|
-
virtual void
|
|
309
|
-
napi_delete_reference(env, callbackRef_);
|
|
310
|
-
napi_delete_async_work(env, asyncWork_);
|
|
311
|
-
|
|
312
|
-
delete this;
|
|
344
|
+
virtual void Destroy (napi_env env) {
|
|
313
345
|
}
|
|
314
346
|
|
|
315
347
|
void Queue (napi_env env) {
|
|
@@ -317,7 +349,6 @@ struct BaseWorker {
|
|
|
317
349
|
}
|
|
318
350
|
|
|
319
351
|
Database* database_;
|
|
320
|
-
|
|
321
352
|
private:
|
|
322
353
|
napi_ref callbackRef_;
|
|
323
354
|
napi_async_work asyncWork_;
|
|
@@ -345,56 +376,6 @@ struct Database {
|
|
|
345
376
|
db_.reset();
|
|
346
377
|
}
|
|
347
378
|
|
|
348
|
-
rocksdb::Status Put (const rocksdb::WriteOptions& options,
|
|
349
|
-
const std::string& key,
|
|
350
|
-
const std::string& value) {
|
|
351
|
-
return db_->Put(options, db_->DefaultColumnFamily(), key, value);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
rocksdb::Status Get (const rocksdb::ReadOptions& options,
|
|
355
|
-
const std::string& key,
|
|
356
|
-
rocksdb::PinnableSlice& value) {
|
|
357
|
-
return db_->Get(options, db_->DefaultColumnFamily(), key, &value);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
rocksdb::Status Del (const rocksdb::WriteOptions& options,
|
|
361
|
-
const std::string& key) {
|
|
362
|
-
return db_->Delete(options, db_->DefaultColumnFamily(), key);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
rocksdb::Status WriteBatch (const rocksdb::WriteOptions& options,
|
|
366
|
-
rocksdb::WriteBatch* batch) {
|
|
367
|
-
return db_->Write(options, batch);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
uint64_t ApproximateSize (const rocksdb::Range* range) {
|
|
371
|
-
uint64_t size = 0;
|
|
372
|
-
db_->GetApproximateSizes(range, 1, &size);
|
|
373
|
-
return size;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
void CompactRange (const rocksdb::Slice* start,
|
|
377
|
-
const rocksdb::Slice* end) {
|
|
378
|
-
rocksdb::CompactRangeOptions options;
|
|
379
|
-
db_->CompactRange(options, start, end);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
void GetProperty (const std::string& property, std::string& value) {
|
|
383
|
-
db_->GetProperty(property, &value);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const rocksdb::Snapshot* NewSnapshot () {
|
|
387
|
-
return db_->GetSnapshot();
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
rocksdb::Iterator* NewIterator (const rocksdb::ReadOptions& options) {
|
|
391
|
-
return db_->NewIterator(options);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
void ReleaseSnapshot (const rocksdb::Snapshot* snapshot) {
|
|
395
|
-
return db_->ReleaseSnapshot(snapshot);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
379
|
void AttachIterator (napi_env env, Iterator* iterator) {
|
|
399
380
|
iterators_.insert(iterator);
|
|
400
381
|
IncrementPriorityWork(env);
|
|
@@ -442,19 +423,19 @@ struct PriorityWorker : public BaseWorker {
|
|
|
442
423
|
|
|
443
424
|
virtual ~PriorityWorker () {}
|
|
444
425
|
|
|
445
|
-
void
|
|
426
|
+
void Destroy (napi_env env) override {
|
|
446
427
|
database_->DecrementPriorityWork(env);
|
|
447
|
-
BaseWorker::
|
|
428
|
+
BaseWorker::Destroy(env);
|
|
448
429
|
}
|
|
449
430
|
};
|
|
450
431
|
|
|
451
432
|
struct BaseIterator {
|
|
452
433
|
BaseIterator(Database* database,
|
|
453
434
|
const bool reverse,
|
|
454
|
-
const std::string
|
|
455
|
-
const std::string
|
|
456
|
-
const std::string
|
|
457
|
-
const std::string
|
|
435
|
+
const std::optional<std::string>& lt,
|
|
436
|
+
const std::optional<std::string>& lte,
|
|
437
|
+
const std::optional<std::string>& gt,
|
|
438
|
+
const std::optional<std::string>& gte,
|
|
458
439
|
const int limit,
|
|
459
440
|
const bool fillCache)
|
|
460
441
|
: database_(database),
|
|
@@ -462,10 +443,10 @@ struct BaseIterator {
|
|
|
462
443
|
lte_(lte),
|
|
463
444
|
gt_(gt),
|
|
464
445
|
gte_(gte),
|
|
465
|
-
snapshot_(
|
|
466
|
-
database_->ReleaseSnapshot(ptr);
|
|
446
|
+
snapshot_(database_->db_->GetSnapshot(), [this](const rocksdb::Snapshot* ptr) {
|
|
447
|
+
database_->db_->ReleaseSnapshot(ptr);
|
|
467
448
|
}),
|
|
468
|
-
iterator_(database->NewIterator([&]{
|
|
449
|
+
iterator_(database->db_->NewIterator([&]{
|
|
469
450
|
rocksdb::ReadOptions options;
|
|
470
451
|
if (lt_ && !lte_) {
|
|
471
452
|
upper_bound_ = rocksdb::Slice(lt_->data(), lt_->size());
|
|
@@ -501,13 +482,7 @@ struct BaseIterator {
|
|
|
501
482
|
iterator_->Next();
|
|
502
483
|
}
|
|
503
484
|
} else if (reverse_ && lte_) {
|
|
504
|
-
iterator_->
|
|
505
|
-
|
|
506
|
-
if (!iterator_->Valid()) {
|
|
507
|
-
iterator_->SeekToLast();
|
|
508
|
-
} else if (iterator_->key().compare(*lte_) > 0) {
|
|
509
|
-
iterator_->Prev();
|
|
510
|
-
}
|
|
485
|
+
iterator_->SeekForPrev(*lte_);
|
|
511
486
|
} else if (reverse_) {
|
|
512
487
|
iterator_->SeekToLast();
|
|
513
488
|
} else {
|
|
@@ -518,25 +493,16 @@ struct BaseIterator {
|
|
|
518
493
|
void Seek (const std::string& target) {
|
|
519
494
|
didSeek_ = true;
|
|
520
495
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
iterator_->Seek(target);
|
|
496
|
+
// TODO (fix): Only check for (gt && !gte) and lte.
|
|
497
|
+
// See, https://github.com/facebook/rocksdb/issues/9904.
|
|
526
498
|
|
|
527
|
-
if (
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
499
|
+
if (OutOfRange(target)) {
|
|
500
|
+
SeekToLast();
|
|
501
|
+
Next();
|
|
502
|
+
} else if (reverse_) {
|
|
503
|
+
iterator_->SeekForPrev(target);
|
|
532
504
|
} else {
|
|
533
|
-
|
|
534
|
-
if (iterator_->Valid()) {
|
|
535
|
-
const auto cmp = iterator_->key().compare(target);
|
|
536
|
-
if (reverse_ ? cmp > 0 : cmp < 0) {
|
|
537
|
-
SeekToEnd();
|
|
538
|
-
}
|
|
539
|
-
}
|
|
505
|
+
iterator_->Seek(target);
|
|
540
506
|
}
|
|
541
507
|
}
|
|
542
508
|
|
|
@@ -580,11 +546,6 @@ struct BaseIterator {
|
|
|
580
546
|
else iterator_->SeekToLast();
|
|
581
547
|
}
|
|
582
548
|
|
|
583
|
-
void SeekToEnd () {
|
|
584
|
-
SeekToLast();
|
|
585
|
-
Next();
|
|
586
|
-
}
|
|
587
|
-
|
|
588
549
|
rocksdb::Slice CurrentKey () const {
|
|
589
550
|
return iterator_->key();
|
|
590
551
|
}
|
|
@@ -616,10 +577,10 @@ struct BaseIterator {
|
|
|
616
577
|
Database* database_;
|
|
617
578
|
|
|
618
579
|
private:
|
|
619
|
-
const std::
|
|
620
|
-
const std::
|
|
621
|
-
const std::
|
|
622
|
-
const std::
|
|
580
|
+
const std::optional<std::string> lt_;
|
|
581
|
+
const std::optional<std::string> lte_;
|
|
582
|
+
const std::optional<std::string> gt_;
|
|
583
|
+
const std::optional<std::string> gte_;
|
|
623
584
|
rocksdb::Slice lower_bound_;
|
|
624
585
|
rocksdb::Slice upper_bound_;
|
|
625
586
|
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
|
|
@@ -636,10 +597,10 @@ struct Iterator final : public BaseIterator {
|
|
|
636
597
|
const bool keys,
|
|
637
598
|
const bool values,
|
|
638
599
|
const int limit,
|
|
639
|
-
const std::string
|
|
640
|
-
const std::string
|
|
641
|
-
const std::string
|
|
642
|
-
const std::string
|
|
600
|
+
const std::optional<std::string>& lt,
|
|
601
|
+
const std::optional<std::string>& lte,
|
|
602
|
+
const std::optional<std::string>& gt,
|
|
603
|
+
const std::optional<std::string>& gte,
|
|
643
604
|
const bool fillCache,
|
|
644
605
|
const bool keyAsBuffer,
|
|
645
606
|
const bool valueAsBuffer,
|
|
@@ -790,8 +751,8 @@ struct OpenWorker final : public PriorityWorker {
|
|
|
790
751
|
);
|
|
791
752
|
}
|
|
792
753
|
|
|
793
|
-
rocksdb::Status Execute () override {
|
|
794
|
-
return
|
|
754
|
+
rocksdb::Status Execute (Database& database) override {
|
|
755
|
+
return database.Open(options_, readOnly_, location_.c_str());
|
|
795
756
|
}
|
|
796
757
|
|
|
797
758
|
rocksdb::Options options_;
|
|
@@ -839,9 +800,8 @@ struct CloseWorker final : public BaseWorker {
|
|
|
839
800
|
napi_value callback)
|
|
840
801
|
: BaseWorker(env, database, callback, "leveldown.db.close") {}
|
|
841
802
|
|
|
842
|
-
rocksdb::Status Execute () override {
|
|
843
|
-
|
|
844
|
-
return rocksdb::Status::OK();
|
|
803
|
+
rocksdb::Status Execute (Database& database) override {
|
|
804
|
+
return database.db_->Close();
|
|
845
805
|
}
|
|
846
806
|
};
|
|
847
807
|
|
|
@@ -866,41 +826,15 @@ NAPI_METHOD(db_close) {
|
|
|
866
826
|
return 0;
|
|
867
827
|
}
|
|
868
828
|
|
|
869
|
-
struct PutWorker final : public PriorityWorker {
|
|
870
|
-
PutWorker (napi_env env,
|
|
871
|
-
Database* database,
|
|
872
|
-
napi_value callback,
|
|
873
|
-
const std::string& key,
|
|
874
|
-
const std::string& value,
|
|
875
|
-
bool sync)
|
|
876
|
-
: PriorityWorker(env, database, callback, "rocks_level.db.put"),
|
|
877
|
-
key_(key), value_(value), sync_(sync) {
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
rocksdb::Status Execute () override {
|
|
881
|
-
rocksdb::WriteOptions options;
|
|
882
|
-
options.sync = sync_;
|
|
883
|
-
return database_->Put(options, key_, value_);
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
const std::string key_;
|
|
887
|
-
const std::string value_;
|
|
888
|
-
const bool sync_;
|
|
889
|
-
};
|
|
890
|
-
|
|
891
829
|
NAPI_METHOD(db_put) {
|
|
892
|
-
NAPI_ARGV(
|
|
830
|
+
NAPI_ARGV(4);
|
|
893
831
|
NAPI_DB_CONTEXT();
|
|
894
832
|
|
|
895
833
|
const auto key = ToString(env, argv[1]);
|
|
896
834
|
const auto value = ToString(env, argv[2]);
|
|
897
|
-
const auto sync = BooleanProperty(env, argv[3], "sync", false);
|
|
898
|
-
const auto callback = argv[4];
|
|
899
|
-
|
|
900
|
-
auto worker = new PutWorker(env, database, callback, key, value, sync);
|
|
901
|
-
worker->Queue(env);
|
|
902
835
|
|
|
903
|
-
|
|
836
|
+
rocksdb::WriteOptions options;
|
|
837
|
+
return ToError(env, database->db_->Put(options, key, value));
|
|
904
838
|
}
|
|
905
839
|
|
|
906
840
|
struct GetWorker final : public PriorityWorker {
|
|
@@ -911,16 +845,22 @@ struct GetWorker final : public PriorityWorker {
|
|
|
911
845
|
const bool asBuffer,
|
|
912
846
|
const bool fillCache)
|
|
913
847
|
: PriorityWorker(env, database, callback, "rocks_level.db.get"),
|
|
914
|
-
key_(key), asBuffer_(asBuffer), fillCache_(fillCache)
|
|
848
|
+
key_(key), asBuffer_(asBuffer), fillCache_(fillCache),
|
|
849
|
+
snapshot_(database_->db_->GetSnapshot(), [this](const rocksdb::Snapshot* ptr) {
|
|
850
|
+
database_->db_->ReleaseSnapshot(ptr);
|
|
851
|
+
}) {
|
|
915
852
|
}
|
|
916
853
|
|
|
917
|
-
rocksdb::Status Execute () override {
|
|
854
|
+
rocksdb::Status Execute (Database& database) override {
|
|
918
855
|
rocksdb::ReadOptions options;
|
|
919
856
|
options.fill_cache = fillCache_;
|
|
920
|
-
|
|
857
|
+
options.snapshot = snapshot_.get();
|
|
858
|
+
auto status = database.db_->Get(options, database.db_->DefaultColumnFamily(), key_, &value_);
|
|
859
|
+
snapshot_.reset();
|
|
860
|
+
return status;
|
|
921
861
|
}
|
|
922
862
|
|
|
923
|
-
void
|
|
863
|
+
void OnOk (napi_env env, napi_value callback) override {
|
|
924
864
|
napi_value argv[2];
|
|
925
865
|
napi_get_null(env, &argv[0]);
|
|
926
866
|
Convert(env, std::move(value_), asBuffer_, argv[1]);
|
|
@@ -932,6 +872,7 @@ private:
|
|
|
932
872
|
rocksdb::PinnableSlice value_;
|
|
933
873
|
const bool asBuffer_;
|
|
934
874
|
const bool fillCache_;
|
|
875
|
+
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
|
|
935
876
|
};
|
|
936
877
|
|
|
937
878
|
NAPI_METHOD(db_get) {
|
|
@@ -959,28 +900,21 @@ struct GetManyWorker final : public PriorityWorker {
|
|
|
959
900
|
const bool fillCache)
|
|
960
901
|
: PriorityWorker(env, database, callback, "leveldown.get.many"),
|
|
961
902
|
keys_(keys), valueAsBuffer_(valueAsBuffer), fillCache_(fillCache),
|
|
962
|
-
snapshot_(
|
|
903
|
+
snapshot_(database_->db_->GetSnapshot(), [this](const rocksdb::Snapshot* ptr) {
|
|
904
|
+
database_->db_->ReleaseSnapshot(ptr);
|
|
905
|
+
}) {
|
|
963
906
|
}
|
|
964
907
|
|
|
965
|
-
|
|
966
|
-
if (snapshot_) {
|
|
967
|
-
database_->ReleaseSnapshot(snapshot_);
|
|
968
|
-
snapshot_ = nullptr;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
rocksdb::Status Execute () override {
|
|
908
|
+
rocksdb::Status Execute (Database& database) override {
|
|
973
909
|
rocksdb::ReadOptions options;
|
|
974
|
-
options.snapshot = snapshot_;
|
|
975
910
|
options.fill_cache = fillCache_;
|
|
976
|
-
|
|
977
|
-
|
|
911
|
+
options.snapshot = snapshot_.get();
|
|
912
|
+
|
|
913
|
+
status_ = database.db_->MultiGet(
|
|
978
914
|
options,
|
|
979
915
|
std::vector<rocksdb::Slice>(keys_.begin(), keys_.end()),
|
|
980
916
|
&values_
|
|
981
917
|
);
|
|
982
|
-
|
|
983
|
-
database_->ReleaseSnapshot(snapshot_);
|
|
984
918
|
snapshot_ = nullptr;
|
|
985
919
|
|
|
986
920
|
for (auto status : status_) {
|
|
@@ -992,7 +926,7 @@ struct GetManyWorker final : public PriorityWorker {
|
|
|
992
926
|
return rocksdb::Status::OK();
|
|
993
927
|
}
|
|
994
928
|
|
|
995
|
-
void
|
|
929
|
+
void OnOk (napi_env env, napi_value callback) override {
|
|
996
930
|
const auto size = values_.size();
|
|
997
931
|
|
|
998
932
|
napi_value array;
|
|
@@ -1020,7 +954,7 @@ private:
|
|
|
1020
954
|
std::vector<rocksdb::Status> status_;
|
|
1021
955
|
const bool valueAsBuffer_;
|
|
1022
956
|
const bool fillCache_;
|
|
1023
|
-
const rocksdb::Snapshot
|
|
957
|
+
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
|
|
1024
958
|
};
|
|
1025
959
|
|
|
1026
960
|
NAPI_METHOD(db_get_many) {
|
|
@@ -1039,190 +973,65 @@ NAPI_METHOD(db_get_many) {
|
|
|
1039
973
|
return 0;
|
|
1040
974
|
}
|
|
1041
975
|
|
|
1042
|
-
struct DelWorker final : public PriorityWorker {
|
|
1043
|
-
DelWorker (napi_env env,
|
|
1044
|
-
Database* database,
|
|
1045
|
-
napi_value callback,
|
|
1046
|
-
const std::string& key,
|
|
1047
|
-
bool sync)
|
|
1048
|
-
: PriorityWorker(env, database, callback, "rocks_level.db.del"),
|
|
1049
|
-
key_(key), sync_(sync) {
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
rocksdb::Status Execute () override {
|
|
1053
|
-
rocksdb::WriteOptions options;
|
|
1054
|
-
options.sync = sync_;
|
|
1055
|
-
return database_->Del(options, key_);
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
const std::string key_;
|
|
1059
|
-
const bool sync_;
|
|
1060
|
-
};
|
|
1061
|
-
|
|
1062
976
|
NAPI_METHOD(db_del) {
|
|
1063
|
-
NAPI_ARGV(
|
|
977
|
+
NAPI_ARGV(3);
|
|
1064
978
|
NAPI_DB_CONTEXT();
|
|
1065
979
|
|
|
1066
980
|
const auto key = ToString(env, argv[1]);
|
|
1067
|
-
const auto sync = BooleanProperty(env, argv[2], "sync", false);
|
|
1068
|
-
const auto callback = argv[3];
|
|
1069
981
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
return 0;
|
|
982
|
+
rocksdb::WriteOptions options;
|
|
983
|
+
return ToError(env, database->db_->Delete(options, key));
|
|
1074
984
|
}
|
|
1075
985
|
|
|
1076
|
-
struct ClearWorker final : public PriorityWorker {
|
|
1077
|
-
ClearWorker (napi_env env,
|
|
1078
|
-
Database* database,
|
|
1079
|
-
napi_value callback,
|
|
1080
|
-
const bool reverse,
|
|
1081
|
-
const int limit,
|
|
1082
|
-
const std::string* lt,
|
|
1083
|
-
const std::string* lte,
|
|
1084
|
-
const std::string* gt,
|
|
1085
|
-
const std::string* gte)
|
|
1086
|
-
: PriorityWorker(env, database, callback, "rocks_level.db.clear"),
|
|
1087
|
-
iterator_(database, reverse, lt, lte, gt, gte, limit, false) {
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
rocksdb::Status Execute () override {
|
|
1091
|
-
iterator_.SeekToRange();
|
|
1092
|
-
|
|
1093
|
-
// TODO: add option
|
|
1094
|
-
const uint32_t hwm = 16 * 1024;
|
|
1095
|
-
|
|
1096
|
-
rocksdb::WriteBatch batch;
|
|
1097
|
-
rocksdb::WriteOptions options;
|
|
1098
|
-
rocksdb::Status status;
|
|
1099
|
-
|
|
1100
|
-
while (true) {
|
|
1101
|
-
size_t bytesRead = 0;
|
|
1102
|
-
|
|
1103
|
-
while (bytesRead <= hwm && iterator_.Valid() && iterator_.Increment()) {
|
|
1104
|
-
const auto key = iterator_.CurrentKey();
|
|
1105
|
-
batch.Delete(key);
|
|
1106
|
-
bytesRead += key.size();
|
|
1107
|
-
iterator_.Next();
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
status = iterator_.Status();
|
|
1111
|
-
if (!status.ok() || bytesRead == 0) {
|
|
1112
|
-
break;
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
status = database_->WriteBatch(options, &batch);
|
|
1116
|
-
if (!status.ok()) {
|
|
1117
|
-
break;
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
batch.Clear();
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
iterator_.Close();
|
|
1124
|
-
|
|
1125
|
-
return status;
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
private:
|
|
1129
|
-
BaseIterator iterator_;
|
|
1130
|
-
};
|
|
1131
|
-
|
|
1132
986
|
NAPI_METHOD(db_clear) {
|
|
1133
|
-
NAPI_ARGV(
|
|
987
|
+
NAPI_ARGV(2);
|
|
1134
988
|
NAPI_DB_CONTEXT();
|
|
1135
989
|
|
|
1136
|
-
|
|
1137
|
-
|
|
990
|
+
const auto reverse = BooleanProperty(env, argv[1], "reverse", false);
|
|
991
|
+
const auto limit = Int32Property(env, argv[1], "limit", -1);
|
|
1138
992
|
|
|
1139
|
-
const auto
|
|
1140
|
-
const auto
|
|
1141
|
-
|
|
1142
|
-
const auto
|
|
1143
|
-
const auto lte = RangeOption(env, options, "lte");
|
|
1144
|
-
const auto gt = RangeOption(env, options, "gt");
|
|
1145
|
-
const auto gte = RangeOption(env, options, "gte");
|
|
993
|
+
const auto lt = RangeOption(env, argv[1], "lt");
|
|
994
|
+
const auto lte = RangeOption(env, argv[1], "lte");
|
|
995
|
+
const auto gt = RangeOption(env, argv[1], "gt");
|
|
996
|
+
const auto gte = RangeOption(env, argv[1], "gte");
|
|
1146
997
|
|
|
1147
|
-
|
|
1148
|
-
worker->Queue(env);
|
|
998
|
+
BaseIterator it(database, reverse, lt, lte, gt, gte, limit, false);
|
|
1149
999
|
|
|
1150
|
-
|
|
1151
|
-
}
|
|
1000
|
+
it.SeekToRange();
|
|
1152
1001
|
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
Database* database,
|
|
1156
|
-
napi_value callback,
|
|
1157
|
-
const std::string& start,
|
|
1158
|
-
const std::string& end)
|
|
1159
|
-
: PriorityWorker(env, database, callback, "rocks_level.db.approximate_size"),
|
|
1160
|
-
start_(start), end_(end) {}
|
|
1161
|
-
|
|
1162
|
-
rocksdb::Status Execute () override {
|
|
1163
|
-
rocksdb::Range range(start_, end_);
|
|
1164
|
-
size_ = database_->ApproximateSize(&range);
|
|
1165
|
-
return rocksdb::Status::OK();
|
|
1166
|
-
}
|
|
1002
|
+
// TODO: add option
|
|
1003
|
+
const uint32_t hwm = 16 * 1024;
|
|
1167
1004
|
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
std::string start_;
|
|
1176
|
-
std::string end_;
|
|
1177
|
-
uint64_t size_;
|
|
1178
|
-
};
|
|
1179
|
-
|
|
1180
|
-
NAPI_METHOD(db_approximate_size) {
|
|
1181
|
-
NAPI_ARGV(4);
|
|
1182
|
-
NAPI_DB_CONTEXT();
|
|
1005
|
+
rocksdb::WriteBatch batch;
|
|
1006
|
+
rocksdb::WriteOptions options;
|
|
1007
|
+
rocksdb::Status status;
|
|
1008
|
+
|
|
1009
|
+
while (true) {
|
|
1010
|
+
size_t bytesRead = 0;
|
|
1183
1011
|
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1012
|
+
while (bytesRead <= hwm && it.Valid() && it.Increment()) {
|
|
1013
|
+
const auto key = it.CurrentKey();
|
|
1014
|
+
batch.Delete(key);
|
|
1015
|
+
bytesRead += key.size();
|
|
1016
|
+
it.Next();
|
|
1017
|
+
}
|
|
1187
1018
|
|
|
1188
|
-
|
|
1189
|
-
|
|
1019
|
+
status = it.Status();
|
|
1020
|
+
if (!status.ok() || bytesRead == 0) {
|
|
1021
|
+
break;
|
|
1022
|
+
}
|
|
1190
1023
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1024
|
+
status = database->db_->Write(options, &batch);
|
|
1025
|
+
if (!status.ok()) {
|
|
1026
|
+
break;
|
|
1027
|
+
}
|
|
1193
1028
|
|
|
1194
|
-
|
|
1195
|
-
CompactRangeWorker (napi_env env,
|
|
1196
|
-
Database* database,
|
|
1197
|
-
napi_value callback,
|
|
1198
|
-
const std::string& start,
|
|
1199
|
-
const std::string& end)
|
|
1200
|
-
: PriorityWorker(env, database, callback, "rocks_level.db.compact_range"),
|
|
1201
|
-
start_(start), end_(end) {}
|
|
1202
|
-
|
|
1203
|
-
rocksdb::Status Execute () override {
|
|
1204
|
-
rocksdb::Slice start = start_;
|
|
1205
|
-
rocksdb::Slice end = end_;
|
|
1206
|
-
database_->CompactRange(&start, &end);
|
|
1207
|
-
return rocksdb::Status::OK();
|
|
1029
|
+
batch.Clear();
|
|
1208
1030
|
}
|
|
1209
1031
|
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
NAPI_METHOD(db_compact_range) {
|
|
1215
|
-
NAPI_ARGV(4);
|
|
1216
|
-
NAPI_DB_CONTEXT();
|
|
1217
|
-
|
|
1218
|
-
const auto start = ToString(env, argv[1]);
|
|
1219
|
-
const auto end = ToString(env, argv[2]);
|
|
1220
|
-
const auto callback = argv[3];
|
|
1221
|
-
|
|
1222
|
-
auto worker = new CompactRangeWorker(env, database, callback, start, end);
|
|
1223
|
-
worker->Queue(env);
|
|
1224
|
-
|
|
1225
|
-
return 0;
|
|
1032
|
+
it.Close();
|
|
1033
|
+
|
|
1034
|
+
return ToError(env, status);
|
|
1226
1035
|
}
|
|
1227
1036
|
|
|
1228
1037
|
NAPI_METHOD(db_get_property) {
|
|
@@ -1232,7 +1041,7 @@ NAPI_METHOD(db_get_property) {
|
|
|
1232
1041
|
const auto property = ToString(env, argv[1]);
|
|
1233
1042
|
|
|
1234
1043
|
std::string value;
|
|
1235
|
-
database->GetProperty(property, value);
|
|
1044
|
+
database->db_->GetProperty(property, &value);
|
|
1236
1045
|
|
|
1237
1046
|
napi_value result;
|
|
1238
1047
|
napi_create_string_utf8(env, value.data(), value.size(), &result);
|
|
@@ -1240,62 +1049,6 @@ NAPI_METHOD(db_get_property) {
|
|
|
1240
1049
|
return result;
|
|
1241
1050
|
}
|
|
1242
1051
|
|
|
1243
|
-
struct DestroyWorker final : public BaseWorker {
|
|
1244
|
-
DestroyWorker (napi_env env,
|
|
1245
|
-
const std::string& location,
|
|
1246
|
-
napi_value callback)
|
|
1247
|
-
: BaseWorker(env, nullptr, callback, "rocks_level.destroy_db"),
|
|
1248
|
-
location_(location) {}
|
|
1249
|
-
|
|
1250
|
-
~DestroyWorker () {}
|
|
1251
|
-
|
|
1252
|
-
rocksdb::Status Execute () override {
|
|
1253
|
-
rocksdb::Options options;
|
|
1254
|
-
return rocksdb::DestroyDB(location_, options);
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
const std::string location_;
|
|
1258
|
-
};
|
|
1259
|
-
|
|
1260
|
-
NAPI_METHOD(destroy_db) {
|
|
1261
|
-
NAPI_ARGV(2);
|
|
1262
|
-
|
|
1263
|
-
const auto location = ToString(env, argv[0]);
|
|
1264
|
-
const auto callback = argv[1];
|
|
1265
|
-
|
|
1266
|
-
auto worker = new DestroyWorker(env, location, callback);
|
|
1267
|
-
worker->Queue(env);
|
|
1268
|
-
|
|
1269
|
-
return 0;
|
|
1270
|
-
}
|
|
1271
|
-
|
|
1272
|
-
struct RepairWorker final : public BaseWorker {
|
|
1273
|
-
RepairWorker (napi_env env,
|
|
1274
|
-
const std::string& location,
|
|
1275
|
-
napi_value callback)
|
|
1276
|
-
: BaseWorker(env, nullptr, callback, "rocks_level.repair_db"),
|
|
1277
|
-
location_(location) {}
|
|
1278
|
-
|
|
1279
|
-
rocksdb::Status Execute () override {
|
|
1280
|
-
rocksdb::Options options;
|
|
1281
|
-
return rocksdb::RepairDB(location_, options);
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
|
-
const std::string location_;
|
|
1285
|
-
};
|
|
1286
|
-
|
|
1287
|
-
NAPI_METHOD(repair_db) {
|
|
1288
|
-
NAPI_ARGV(2);
|
|
1289
|
-
|
|
1290
|
-
const auto location = ToString(env, argv[1]);
|
|
1291
|
-
const auto callback = argv[1];
|
|
1292
|
-
|
|
1293
|
-
auto worker = new RepairWorker(env, location, callback);
|
|
1294
|
-
worker->Queue(env);
|
|
1295
|
-
|
|
1296
|
-
return 0;
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
1052
|
static void FinalizeIterator (napi_env env, void* data, void* hint) {
|
|
1300
1053
|
if (data) {
|
|
1301
1054
|
delete reinterpret_cast<Iterator*>(data);
|
|
@@ -1326,9 +1079,7 @@ NAPI_METHOD(iterator_init) {
|
|
|
1326
1079
|
keyAsBuffer, valueAsBuffer, highWaterMarkBytes);
|
|
1327
1080
|
napi_value result;
|
|
1328
1081
|
|
|
1329
|
-
NAPI_STATUS_THROWS(napi_create_external(env, iterator,
|
|
1330
|
-
FinalizeIterator,
|
|
1331
|
-
nullptr, &result));
|
|
1082
|
+
NAPI_STATUS_THROWS(napi_create_external(env, iterator, FinalizeIterator, nullptr, &result));
|
|
1332
1083
|
|
|
1333
1084
|
// Prevent GC of JS object before the iterator is closed (explicitly or on
|
|
1334
1085
|
// db close) and keep track of non-closed iterators to end them on db close.
|
|
@@ -1355,14 +1106,14 @@ struct CloseIteratorWorker final : public BaseWorker {
|
|
|
1355
1106
|
: BaseWorker(env, iterator->database_, callback, "leveldown.iterator.end"),
|
|
1356
1107
|
iterator_(iterator) {}
|
|
1357
1108
|
|
|
1358
|
-
rocksdb::Status Execute () override {
|
|
1109
|
+
rocksdb::Status Execute (Database& database) override {
|
|
1359
1110
|
iterator_->Close();
|
|
1360
1111
|
return rocksdb::Status::OK();
|
|
1361
1112
|
}
|
|
1362
1113
|
|
|
1363
|
-
void
|
|
1114
|
+
void Destroy (napi_env env) override {
|
|
1364
1115
|
iterator_->Detach(env);
|
|
1365
|
-
BaseWorker::
|
|
1116
|
+
BaseWorker::Destroy(env);
|
|
1366
1117
|
}
|
|
1367
1118
|
|
|
1368
1119
|
private:
|
|
@@ -1390,7 +1141,7 @@ struct NextWorker final : public BaseWorker {
|
|
|
1390
1141
|
"leveldown.iterator.next"),
|
|
1391
1142
|
iterator_(iterator), size_(size) {}
|
|
1392
1143
|
|
|
1393
|
-
rocksdb::Status Execute () override {
|
|
1144
|
+
rocksdb::Status Execute (Database& database) override {
|
|
1394
1145
|
if (!iterator_->DidSeek()) {
|
|
1395
1146
|
iterator_->SeekToRange();
|
|
1396
1147
|
}
|
|
@@ -1398,7 +1149,6 @@ struct NextWorker final : public BaseWorker {
|
|
|
1398
1149
|
// Limit the size of the cache to prevent starving the event loop
|
|
1399
1150
|
// in JS-land while we're recursively calling process.nextTick().
|
|
1400
1151
|
|
|
1401
|
-
finished_ = false;
|
|
1402
1152
|
cache_.reserve(size_ * 2);
|
|
1403
1153
|
size_t bytesRead = 0;
|
|
1404
1154
|
|
|
@@ -1435,7 +1185,7 @@ struct NextWorker final : public BaseWorker {
|
|
|
1435
1185
|
return iterator_->Status();
|
|
1436
1186
|
}
|
|
1437
1187
|
|
|
1438
|
-
void
|
|
1188
|
+
void OnOk (napi_env env, napi_value callback) override {
|
|
1439
1189
|
const auto size = cache_.size();
|
|
1440
1190
|
napi_value result;
|
|
1441
1191
|
napi_create_array_with_length(env, size, &result);
|
|
@@ -1483,71 +1233,44 @@ NAPI_METHOD(iterator_nextv) {
|
|
|
1483
1233
|
return 0;
|
|
1484
1234
|
}
|
|
1485
1235
|
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
napi_value callback,
|
|
1490
|
-
napi_value array,
|
|
1491
|
-
const bool sync)
|
|
1492
|
-
: PriorityWorker(env, database, callback, "rocks_level.batch.do"), sync_(sync) {
|
|
1493
|
-
uint32_t length;
|
|
1494
|
-
NAPI_STATUS_THROWS_VOID(napi_get_array_length(env, array, &length));
|
|
1495
|
-
|
|
1496
|
-
for (uint32_t i = 0; i < length; i++) {
|
|
1497
|
-
napi_value element;
|
|
1498
|
-
NAPI_STATUS_THROWS_VOID(napi_get_element(env, array, i, &element));
|
|
1499
|
-
|
|
1500
|
-
if (!IsObject(env, element)) continue;
|
|
1236
|
+
NAPI_METHOD(batch_do) {
|
|
1237
|
+
NAPI_ARGV(3);
|
|
1238
|
+
NAPI_DB_CONTEXT();
|
|
1501
1239
|
|
|
1502
|
-
|
|
1240
|
+
const auto operations = argv[1];
|
|
1503
1241
|
|
|
1504
|
-
|
|
1505
|
-
if (!HasProperty(env, element, "key")) continue;
|
|
1506
|
-
const auto key = ToString(env, GetProperty(env, element, "key"));
|
|
1242
|
+
rocksdb::WriteBatch batch;
|
|
1507
1243
|
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
} else if (type == "put") {
|
|
1511
|
-
if (!HasProperty(env, element, "key")) continue;
|
|
1512
|
-
if (!HasProperty(env, element, "value")) continue;
|
|
1244
|
+
uint32_t length;
|
|
1245
|
+
NAPI_STATUS_THROWS(napi_get_array_length(env, operations, &length));
|
|
1513
1246
|
|
|
1514
|
-
|
|
1515
|
-
|
|
1247
|
+
for (uint32_t i = 0; i < length; i++) {
|
|
1248
|
+
napi_value element;
|
|
1249
|
+
NAPI_STATUS_THROWS(napi_get_element(env, operations, i, &element));
|
|
1516
1250
|
|
|
1517
|
-
|
|
1518
|
-
if (!hasData_) hasData_ = true;
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1251
|
+
if (!IsObject(env, element)) continue;
|
|
1522
1252
|
|
|
1523
|
-
|
|
1524
|
-
if (!hasData_) {
|
|
1525
|
-
return rocksdb::Status::OK();
|
|
1526
|
-
}
|
|
1253
|
+
const auto type = StringProperty(env, element, "type");
|
|
1527
1254
|
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
return database_->WriteBatch(options, &batch_);
|
|
1531
|
-
}
|
|
1255
|
+
if (type == "del") {
|
|
1256
|
+
if (!HasProperty(env, element, "key")) continue;
|
|
1532
1257
|
|
|
1533
|
-
|
|
1534
|
-
rocksdb::WriteBatch batch_;
|
|
1535
|
-
const bool sync_;
|
|
1536
|
-
bool hasData_;
|
|
1537
|
-
};
|
|
1258
|
+
const auto key = NapiSlice(env, GetProperty(env, element, "key"));
|
|
1538
1259
|
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1260
|
+
batch.Delete(key);
|
|
1261
|
+
} else if (type == "put") {
|
|
1262
|
+
if (!HasProperty(env, element, "key")) continue;
|
|
1263
|
+
if (!HasProperty(env, element, "value")) continue;
|
|
1542
1264
|
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
const auto callback = argv[3];
|
|
1265
|
+
const auto key = NapiSlice(env, GetProperty(env, element, "key"));
|
|
1266
|
+
const auto value = NapiSlice(env, GetProperty(env, element, "value"));
|
|
1546
1267
|
|
|
1547
|
-
|
|
1548
|
-
|
|
1268
|
+
batch.Put(key, value);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1549
1271
|
|
|
1550
|
-
|
|
1272
|
+
rocksdb::WriteOptions options;
|
|
1273
|
+
return ToError(env, database->db_->Write(options, &batch));
|
|
1551
1274
|
}
|
|
1552
1275
|
|
|
1553
1276
|
static void FinalizeBatch (napi_env env, void* data, void* hint) {
|
|
@@ -1571,8 +1294,8 @@ NAPI_METHOD(batch_put) {
|
|
|
1571
1294
|
NAPI_ARGV(3);
|
|
1572
1295
|
NAPI_BATCH_CONTEXT();
|
|
1573
1296
|
|
|
1574
|
-
const auto key =
|
|
1575
|
-
const auto value =
|
|
1297
|
+
const auto key = NapiSlice(env, argv[1]);
|
|
1298
|
+
const auto value = NapiSlice(env, argv[2]);
|
|
1576
1299
|
|
|
1577
1300
|
batch->Put(key, value);
|
|
1578
1301
|
|
|
@@ -1583,7 +1306,7 @@ NAPI_METHOD(batch_del) {
|
|
|
1583
1306
|
NAPI_ARGV(2);
|
|
1584
1307
|
NAPI_BATCH_CONTEXT();
|
|
1585
1308
|
|
|
1586
|
-
const auto key =
|
|
1309
|
+
const auto key = NapiSlice(env, argv[1]);
|
|
1587
1310
|
|
|
1588
1311
|
batch->Delete(key);
|
|
1589
1312
|
|
|
@@ -1599,51 +1322,15 @@ NAPI_METHOD(batch_clear) {
|
|
|
1599
1322
|
return 0;
|
|
1600
1323
|
}
|
|
1601
1324
|
|
|
1602
|
-
struct BatchWriteWorker final : public PriorityWorker {
|
|
1603
|
-
BatchWriteWorker (napi_env env,
|
|
1604
|
-
Database* database,
|
|
1605
|
-
napi_value batch,
|
|
1606
|
-
napi_value callback,
|
|
1607
|
-
const bool sync)
|
|
1608
|
-
: PriorityWorker(env, database, callback, "leveldown.batch.write"),
|
|
1609
|
-
sync_(sync) {
|
|
1610
|
-
|
|
1611
|
-
NAPI_STATUS_THROWS_VOID(napi_get_value_external(env, batch, reinterpret_cast<void**>(&batch_)));
|
|
1612
|
-
|
|
1613
|
-
// Prevent GC of batch object before we execute
|
|
1614
|
-
NAPI_STATUS_THROWS_VOID(napi_create_reference(env, batch, 1, &batchRef_));
|
|
1615
|
-
}
|
|
1616
|
-
|
|
1617
|
-
rocksdb::Status Execute () override {
|
|
1618
|
-
rocksdb::WriteOptions options;
|
|
1619
|
-
options.sync = sync_;
|
|
1620
|
-
return database_->WriteBatch(options, batch_);
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
void Finally (napi_env env) override {
|
|
1624
|
-
napi_delete_reference(env, batchRef_);
|
|
1625
|
-
PriorityWorker::Finally(env);
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
private:
|
|
1629
|
-
rocksdb::WriteBatch* batch_;
|
|
1630
|
-
const bool sync_;
|
|
1631
|
-
napi_ref batchRef_;
|
|
1632
|
-
};
|
|
1633
|
-
|
|
1634
1325
|
NAPI_METHOD(batch_write) {
|
|
1635
1326
|
NAPI_ARGV(4);
|
|
1636
1327
|
NAPI_DB_CONTEXT();
|
|
1637
1328
|
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
const auto sync = BooleanProperty(env, options, "sync", false);
|
|
1641
|
-
const auto callback = argv[3];
|
|
1329
|
+
rocksdb::WriteBatch* batch;
|
|
1330
|
+
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], reinterpret_cast<void**>(&batch)));
|
|
1642
1331
|
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
return 0;
|
|
1332
|
+
rocksdb::WriteOptions options;
|
|
1333
|
+
return ToError(env, database->db_->Write(options, batch));
|
|
1647
1334
|
}
|
|
1648
1335
|
|
|
1649
1336
|
NAPI_INIT() {
|
|
@@ -1655,13 +1342,8 @@ NAPI_INIT() {
|
|
|
1655
1342
|
NAPI_EXPORT_FUNCTION(db_get_many);
|
|
1656
1343
|
NAPI_EXPORT_FUNCTION(db_del);
|
|
1657
1344
|
NAPI_EXPORT_FUNCTION(db_clear);
|
|
1658
|
-
NAPI_EXPORT_FUNCTION(db_approximate_size);
|
|
1659
|
-
NAPI_EXPORT_FUNCTION(db_compact_range);
|
|
1660
1345
|
NAPI_EXPORT_FUNCTION(db_get_property);
|
|
1661
1346
|
|
|
1662
|
-
NAPI_EXPORT_FUNCTION(destroy_db);
|
|
1663
|
-
NAPI_EXPORT_FUNCTION(repair_db);
|
|
1664
|
-
|
|
1665
1347
|
NAPI_EXPORT_FUNCTION(iterator_init);
|
|
1666
1348
|
NAPI_EXPORT_FUNCTION(iterator_seek);
|
|
1667
1349
|
NAPI_EXPORT_FUNCTION(iterator_close);
|