@nxtedition/rocksdb 8.0.4 → 8.1.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 +72 -2
- package/deps/rocksdb/rocksdb/CMakeLists.txt +7 -0
- package/deps/rocksdb/rocksdb/Makefile +13 -1
- package/deps/rocksdb/rocksdb/db/builder.cc +13 -4
- package/deps/rocksdb/rocksdb/db/builder.h +2 -1
- package/deps/rocksdb/rocksdb/db/c.cc +6 -0
- package/deps/rocksdb/rocksdb/db/column_family.cc +1 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +18 -4
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +2 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +22 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +5 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +14 -14
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +1 -2
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +2 -3
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +225 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +8 -9
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +0 -8
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +63 -23
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +2 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +12 -8
- package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +115 -2
- package/deps/rocksdb/rocksdb/db/experimental.cc +2 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +88 -12
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +38 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +14 -110
- package/deps/rocksdb/rocksdb/db/flush_job.cc +2 -3
- package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +1 -1
- package/deps/rocksdb/rocksdb/db/repair.cc +2 -1
- package/deps/rocksdb/rocksdb/db/version_builder_test.cc +41 -39
- package/deps/rocksdb/rocksdb/db/version_edit.cc +12 -0
- package/deps/rocksdb/rocksdb/db/version_edit.h +18 -6
- package/deps/rocksdb/rocksdb/db/version_edit_test.cc +9 -9
- package/deps/rocksdb/rocksdb/db/version_set.cc +12 -6
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +23 -9
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +4 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/c.h +4 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +7 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +2 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/backup_engine.h +69 -9
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +245 -74
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +195 -4
- package/index.js +17 -0
- package/max_rev_operator.h +100 -0
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/darwin-x64/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
|
@@ -16,9 +16,11 @@
|
|
|
16
16
|
#include <atomic>
|
|
17
17
|
#include <cstddef>
|
|
18
18
|
#include <cstdint>
|
|
19
|
+
#include <exception>
|
|
19
20
|
#include <limits>
|
|
20
21
|
#include <memory>
|
|
21
22
|
#include <random>
|
|
23
|
+
#include <stdexcept>
|
|
22
24
|
#include <string>
|
|
23
25
|
#include <utility>
|
|
24
26
|
|
|
@@ -754,7 +756,7 @@ class BackupEngineTest : public testing::Test {
|
|
|
754
756
|
void CloseBackupEngine() { backup_engine_.reset(nullptr); }
|
|
755
757
|
|
|
756
758
|
// cross-cutting test of GetBackupInfo
|
|
757
|
-
void AssertBackupInfoConsistency() {
|
|
759
|
+
void AssertBackupInfoConsistency(bool allow_excluded = false) {
|
|
758
760
|
std::vector<BackupInfo> backup_info;
|
|
759
761
|
backup_engine_->GetBackupInfo(&backup_info, /*with file details*/ true);
|
|
760
762
|
std::map<std::string, uint64_t> file_sizes;
|
|
@@ -774,6 +776,9 @@ class BackupEngineTest : public testing::Test {
|
|
|
774
776
|
sum_for_backup += file.size;
|
|
775
777
|
}
|
|
776
778
|
ASSERT_EQ(backup.size, sum_for_backup);
|
|
779
|
+
if (!allow_excluded) {
|
|
780
|
+
ASSERT_EQ(backup.excluded_files.size(), 0);
|
|
781
|
+
}
|
|
777
782
|
}
|
|
778
783
|
|
|
779
784
|
std::vector<BackupID> corrupt_backup_ids;
|
|
@@ -3094,10 +3099,25 @@ TEST_F(BackupEngineTest, OpenBackupAsReadOnlyDB) {
|
|
|
3094
3099
|
|
|
3095
3100
|
TEST_F(BackupEngineTest, ProgressCallbackDuringBackup) {
|
|
3096
3101
|
DestroyDBWithoutCheck(dbname_, options_);
|
|
3097
|
-
|
|
3098
|
-
engine_options_->callback_trigger_interval_size = 100000;
|
|
3102
|
+
|
|
3099
3103
|
OpenDBAndBackupEngine(true);
|
|
3100
3104
|
FillDB(db_.get(), 0, 100);
|
|
3105
|
+
|
|
3106
|
+
// First test exception handling
|
|
3107
|
+
// Easily small enough for this small DB
|
|
3108
|
+
engine_options_->callback_trigger_interval_size = 1000;
|
|
3109
|
+
OpenBackupEngine();
|
|
3110
|
+
ASSERT_TRUE(
|
|
3111
|
+
backup_engine_->CreateNewBackup(db_.get(), true, []() { throw 42; })
|
|
3112
|
+
.IsAborted());
|
|
3113
|
+
ASSERT_TRUE(backup_engine_
|
|
3114
|
+
->CreateNewBackup(db_.get(), true,
|
|
3115
|
+
[]() { throw std::out_of_range("blah"); })
|
|
3116
|
+
.IsAborted());
|
|
3117
|
+
|
|
3118
|
+
// Too big for this small DB
|
|
3119
|
+
engine_options_->callback_trigger_interval_size = 100000;
|
|
3120
|
+
OpenBackupEngine();
|
|
3101
3121
|
bool is_callback_invoked = false;
|
|
3102
3122
|
ASSERT_OK(backup_engine_->CreateNewBackup(
|
|
3103
3123
|
db_.get(), true,
|
|
@@ -4180,7 +4200,7 @@ TEST_F(BackupEngineTest, FileTemperatures) {
|
|
|
4180
4200
|
&info, /*include_file_details*/ true));
|
|
4181
4201
|
ASSERT_GT(info.file_details.size(), 2);
|
|
4182
4202
|
for (auto& e : info.file_details) {
|
|
4183
|
-
|
|
4203
|
+
EXPECT_EQ(expected_temps[e.file_number], e.temperature);
|
|
4184
4204
|
}
|
|
4185
4205
|
|
|
4186
4206
|
// Restore backup to another virtual (tiered) dir
|
|
@@ -4202,6 +4222,177 @@ TEST_F(BackupEngineTest, FileTemperatures) {
|
|
|
4202
4222
|
}
|
|
4203
4223
|
}
|
|
4204
4224
|
|
|
4225
|
+
TEST_F(BackupEngineTest, ExcludeFiles) {
|
|
4226
|
+
// Required for excluding files
|
|
4227
|
+
engine_options_->schema_version = 2;
|
|
4228
|
+
|
|
4229
|
+
// Need a sufficent set of file numbers
|
|
4230
|
+
options_.level0_file_num_compaction_trigger = 100;
|
|
4231
|
+
|
|
4232
|
+
OpenDBAndBackupEngine(true, false, kShareWithChecksum);
|
|
4233
|
+
// Need a sufficent set of file numbers
|
|
4234
|
+
const int keys_iteration = 5000;
|
|
4235
|
+
FillDB(db_.get(), 0, keys_iteration / 3);
|
|
4236
|
+
FillDB(db_.get(), keys_iteration / 3, keys_iteration * 2 / 3);
|
|
4237
|
+
FillDB(db_.get(), keys_iteration * 2 / 3, keys_iteration);
|
|
4238
|
+
CloseAndReopenDB();
|
|
4239
|
+
|
|
4240
|
+
BackupEngine* alt_backup_engine;
|
|
4241
|
+
BackupEngineOptions alt_engine_options{*engine_options_};
|
|
4242
|
+
// Use an alternate Env to test that support
|
|
4243
|
+
std::string backup_alt_chroot = test::PerThreadDBPath("db_alt_backups");
|
|
4244
|
+
EXPECT_OK(Env::Default()->CreateDirIfMissing(backup_alt_chroot));
|
|
4245
|
+
alt_engine_options.backup_dir = "/altbk";
|
|
4246
|
+
std::shared_ptr<FileSystem> alt_fs{
|
|
4247
|
+
NewChrootFileSystem(FileSystem::Default(), backup_alt_chroot)};
|
|
4248
|
+
std::unique_ptr<Env> alt_env{new CompositeEnvWrapper(Env::Default(), alt_fs)};
|
|
4249
|
+
alt_engine_options.backup_env = alt_env.get();
|
|
4250
|
+
|
|
4251
|
+
ASSERT_OK(BackupEngine::Open(test_db_env_.get(), alt_engine_options,
|
|
4252
|
+
&alt_backup_engine));
|
|
4253
|
+
|
|
4254
|
+
// Ensure each backup is same set of files
|
|
4255
|
+
db_.reset();
|
|
4256
|
+
DB* db = nullptr;
|
|
4257
|
+
ASSERT_OK(DB::OpenForReadOnly(options_, dbname_, &db));
|
|
4258
|
+
|
|
4259
|
+
// A callback that throws should cleanly fail the backup creation.
|
|
4260
|
+
// Do this early to ensure later operations still work.
|
|
4261
|
+
CreateBackupOptions cbo;
|
|
4262
|
+
cbo.exclude_files_callback = [](MaybeExcludeBackupFile* /*files_begin*/,
|
|
4263
|
+
MaybeExcludeBackupFile* /*files_end*/) {
|
|
4264
|
+
throw 42;
|
|
4265
|
+
};
|
|
4266
|
+
ASSERT_TRUE(backup_engine_->CreateNewBackup(cbo, db).IsAborted());
|
|
4267
|
+
cbo.exclude_files_callback = [](MaybeExcludeBackupFile* /*files_begin*/,
|
|
4268
|
+
MaybeExcludeBackupFile* /*files_end*/) {
|
|
4269
|
+
throw std::out_of_range("blah");
|
|
4270
|
+
};
|
|
4271
|
+
ASSERT_TRUE(backup_engine_->CreateNewBackup(cbo, db).IsAborted());
|
|
4272
|
+
|
|
4273
|
+
// Include files only in given bucket, based on modulus and remainder
|
|
4274
|
+
constexpr int modulus = 4;
|
|
4275
|
+
int remainder = 0;
|
|
4276
|
+
|
|
4277
|
+
cbo.exclude_files_callback = [&remainder](MaybeExcludeBackupFile* files_begin,
|
|
4278
|
+
MaybeExcludeBackupFile* files_end) {
|
|
4279
|
+
for (auto* f = files_begin; f != files_end; ++f) {
|
|
4280
|
+
std::string s = StringSplit(f->info.relative_file, '/').back();
|
|
4281
|
+
s = s.substr(0, s.find("_"));
|
|
4282
|
+
int64_t num = std::strtoll(s.c_str(), nullptr, /*base*/ 10);
|
|
4283
|
+
// Exclude if not a match
|
|
4284
|
+
f->exclude_decision = (num % modulus) != remainder;
|
|
4285
|
+
}
|
|
4286
|
+
};
|
|
4287
|
+
|
|
4288
|
+
BackupID first_id{};
|
|
4289
|
+
BackupID last_alt_id{};
|
|
4290
|
+
remainder = 0;
|
|
4291
|
+
ASSERT_OK(backup_engine_->CreateNewBackup(cbo, db, &first_id));
|
|
4292
|
+
AssertBackupInfoConsistency(/*allow excluded*/ true);
|
|
4293
|
+
remainder = 1;
|
|
4294
|
+
ASSERT_OK(alt_backup_engine->CreateNewBackup(cbo, db));
|
|
4295
|
+
AssertBackupInfoConsistency(/*allow excluded*/ true);
|
|
4296
|
+
remainder = 2;
|
|
4297
|
+
ASSERT_OK(backup_engine_->CreateNewBackup(cbo, db));
|
|
4298
|
+
AssertBackupInfoConsistency(/*allow excluded*/ true);
|
|
4299
|
+
remainder = 3;
|
|
4300
|
+
ASSERT_OK(alt_backup_engine->CreateNewBackup(cbo, db, &last_alt_id));
|
|
4301
|
+
AssertBackupInfoConsistency(/*allow excluded*/ true);
|
|
4302
|
+
|
|
4303
|
+
// Close DB
|
|
4304
|
+
ASSERT_OK(db->Close());
|
|
4305
|
+
delete db;
|
|
4306
|
+
db = nullptr;
|
|
4307
|
+
|
|
4308
|
+
for (auto be_pair :
|
|
4309
|
+
{std::make_pair(backup_engine_.get(), alt_backup_engine),
|
|
4310
|
+
std::make_pair(alt_backup_engine, backup_engine_.get())}) {
|
|
4311
|
+
DestroyDB(dbname_, options_);
|
|
4312
|
+
RestoreOptions ro;
|
|
4313
|
+
// Fails without alternate dir
|
|
4314
|
+
ASSERT_TRUE(be_pair.first->RestoreDBFromLatestBackup(dbname_, dbname_, ro)
|
|
4315
|
+
.IsInvalidArgument());
|
|
4316
|
+
|
|
4317
|
+
DestroyDB(dbname_, options_);
|
|
4318
|
+
// Works with alternate dir
|
|
4319
|
+
ro.alternate_dirs.push_front(be_pair.second);
|
|
4320
|
+
ASSERT_OK(be_pair.first->RestoreDBFromLatestBackup(dbname_, dbname_, ro));
|
|
4321
|
+
|
|
4322
|
+
// Check DB contents
|
|
4323
|
+
db = OpenDB();
|
|
4324
|
+
AssertExists(db, 0, keys_iteration);
|
|
4325
|
+
delete db;
|
|
4326
|
+
}
|
|
4327
|
+
|
|
4328
|
+
// Should still work after close and re-open
|
|
4329
|
+
CloseBackupEngine();
|
|
4330
|
+
OpenBackupEngine();
|
|
4331
|
+
|
|
4332
|
+
for (auto be_pair :
|
|
4333
|
+
{std::make_pair(backup_engine_.get(), alt_backup_engine),
|
|
4334
|
+
std::make_pair(alt_backup_engine, backup_engine_.get())}) {
|
|
4335
|
+
DestroyDB(dbname_, options_);
|
|
4336
|
+
RestoreOptions ro;
|
|
4337
|
+
ro.alternate_dirs.push_front(be_pair.second);
|
|
4338
|
+
ASSERT_OK(be_pair.first->RestoreDBFromLatestBackup(dbname_, dbname_, ro));
|
|
4339
|
+
}
|
|
4340
|
+
|
|
4341
|
+
// Deletion semantics are tricky when within a single backup dir one backup
|
|
4342
|
+
// includes a file and the other backup excluded the file. The excluded one
|
|
4343
|
+
// does not have a persistent record of metadata like file checksum, etc.
|
|
4344
|
+
// Although it would be possible to amend the backup with the excluded file,
|
|
4345
|
+
// that is not currently supported (unless you open the backup as read-only
|
|
4346
|
+
// DB and take another backup of it). The "excluded" reference to the file
|
|
4347
|
+
// is like a weak reference: it doesn't prevent the file from being deleted
|
|
4348
|
+
// if all the backups with "included" references to it are deleted.
|
|
4349
|
+
CloseBackupEngine();
|
|
4350
|
+
OpenBackupEngine();
|
|
4351
|
+
|
|
4352
|
+
AssertBackupInfoConsistency(/*allow excluded*/ true);
|
|
4353
|
+
|
|
4354
|
+
ASSERT_OK(backup_engine_->DeleteBackup(first_id));
|
|
4355
|
+
ASSERT_OK(alt_backup_engine->DeleteBackup(last_alt_id));
|
|
4356
|
+
|
|
4357
|
+
// Includes check for any leaked backup files
|
|
4358
|
+
AssertBackupInfoConsistency(/*allow excluded*/ true);
|
|
4359
|
+
|
|
4360
|
+
// Excluded file(s) deleted, unable to restore
|
|
4361
|
+
for (auto be_pair :
|
|
4362
|
+
{std::make_pair(backup_engine_.get(), alt_backup_engine),
|
|
4363
|
+
std::make_pair(alt_backup_engine, backup_engine_.get())}) {
|
|
4364
|
+
RestoreOptions ro;
|
|
4365
|
+
ro.alternate_dirs.push_front(be_pair.second);
|
|
4366
|
+
ASSERT_TRUE(be_pair.first->RestoreDBFromLatestBackup(dbname_, dbname_, ro)
|
|
4367
|
+
.IsInvalidArgument());
|
|
4368
|
+
}
|
|
4369
|
+
|
|
4370
|
+
// Close & Re-open (no crash, etc.)
|
|
4371
|
+
CloseBackupEngine();
|
|
4372
|
+
OpenBackupEngine();
|
|
4373
|
+
|
|
4374
|
+
AssertBackupInfoConsistency(/*allow excluded*/ true);
|
|
4375
|
+
|
|
4376
|
+
// Excluded file(s) deleted, unable to restore
|
|
4377
|
+
for (auto be_pair :
|
|
4378
|
+
{std::make_pair(backup_engine_.get(), alt_backup_engine),
|
|
4379
|
+
std::make_pair(alt_backup_engine, backup_engine_.get())}) {
|
|
4380
|
+
RestoreOptions ro;
|
|
4381
|
+
ro.alternate_dirs.push_front(be_pair.second);
|
|
4382
|
+
ASSERT_TRUE(be_pair.first->RestoreDBFromLatestBackup(dbname_, dbname_, ro)
|
|
4383
|
+
.IsInvalidArgument());
|
|
4384
|
+
}
|
|
4385
|
+
|
|
4386
|
+
// Ensure files are not leaked after removing everything.
|
|
4387
|
+
ASSERT_OK(backup_engine_->DeleteBackup(first_id + 1));
|
|
4388
|
+
ASSERT_OK(alt_backup_engine->DeleteBackup(last_alt_id - 1));
|
|
4389
|
+
|
|
4390
|
+
// Includes check for leaked backups files
|
|
4391
|
+
AssertBackupInfoConsistency(/*allow excluded*/ false);
|
|
4392
|
+
|
|
4393
|
+
delete alt_backup_engine;
|
|
4394
|
+
}
|
|
4395
|
+
|
|
4205
4396
|
} // namespace
|
|
4206
4397
|
|
|
4207
4398
|
} // namespace ROCKSDB_NAMESPACE
|
package/index.js
CHANGED
|
@@ -168,6 +168,23 @@ class RocksLevel extends AbstractLevel {
|
|
|
168
168
|
return callback[kPromise]
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
_getMergeOperands(key, options, callback) {
|
|
172
|
+
callback = fromCallback(callback, kPromise)
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
this[kRef]()
|
|
176
|
+
binding.db_get_merge_operands(this[kContext], key, options ?? EMPTY, (err, val) => {
|
|
177
|
+
callback(err, val)
|
|
178
|
+
this[kUnref]()
|
|
179
|
+
})
|
|
180
|
+
} catch (err) {
|
|
181
|
+
process.nextTick(callback, err)
|
|
182
|
+
this[kUnref]()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return callback[kPromise]
|
|
186
|
+
}
|
|
187
|
+
|
|
171
188
|
_del (key, options, callback) {
|
|
172
189
|
callback = fromCallback(callback, kPromise)
|
|
173
190
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <rocksdb/slice.h>
|
|
4
|
+
#include <rocksdb/merge_operator.h>
|
|
5
|
+
|
|
6
|
+
int compareRev(const rocksdb::Slice& a, const rocksdb::Slice& b) {
|
|
7
|
+
auto indexA = 0UL;
|
|
8
|
+
auto indexB = 0UL;
|
|
9
|
+
const auto endA = a.size();
|
|
10
|
+
const auto endB = b.size();
|
|
11
|
+
|
|
12
|
+
// Compare the revision number
|
|
13
|
+
auto result = 0;
|
|
14
|
+
const auto end = std::min(endA, endB);
|
|
15
|
+
while (indexA < end && indexB < end) {
|
|
16
|
+
const auto ac = a[indexA++];
|
|
17
|
+
const auto bc = b[indexB++];
|
|
18
|
+
|
|
19
|
+
if (ac == '-') {
|
|
20
|
+
if (bc == '-') {
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
return -1;
|
|
24
|
+
} else if (bc == '-') {
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!result) {
|
|
29
|
+
result = ac == bc ? 0 : ac < bc ? -1 : 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (result) {
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Compare the rest
|
|
38
|
+
while (indexA < end && indexB < end) {
|
|
39
|
+
const auto ac = a[indexA++];
|
|
40
|
+
const auto bc = b[indexB++];
|
|
41
|
+
if (ac != bc) {
|
|
42
|
+
return ac < bc ? -1 : 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return endA - endB;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class MaxRevOperator : public rocksdb::MergeOperator {
|
|
50
|
+
public:
|
|
51
|
+
bool FullMergeV2(const MergeOperationInput& merge_in,
|
|
52
|
+
MergeOperationOutput* merge_out) const override {
|
|
53
|
+
rocksdb::Slice& max = merge_out->existing_operand;
|
|
54
|
+
if (merge_in.existing_value) {
|
|
55
|
+
max = rocksdb::Slice(merge_in.existing_value->data(),
|
|
56
|
+
merge_in.existing_value->size());
|
|
57
|
+
} else if (max.data() == nullptr) {
|
|
58
|
+
max = rocksdb::Slice();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const auto& op : merge_in.operand_list) {
|
|
62
|
+
if (compareRev(max, op) < 0) {
|
|
63
|
+
max = op;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
bool PartialMerge(const rocksdb::Slice& /*key*/, const rocksdb::Slice& left_operand,
|
|
71
|
+
const rocksdb::Slice& right_operand, std::string* new_value,
|
|
72
|
+
rocksdb::Logger* /*logger*/) const override {
|
|
73
|
+
if (compareRev(left_operand, right_operand) >= 0) {
|
|
74
|
+
new_value->assign(left_operand.data(), left_operand.size());
|
|
75
|
+
} else {
|
|
76
|
+
new_value->assign(right_operand.data(), right_operand.size());
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
bool PartialMergeMulti(const rocksdb::Slice& /*key*/,
|
|
82
|
+
const std::deque<rocksdb::Slice>& operand_list,
|
|
83
|
+
std::string* new_value,
|
|
84
|
+
rocksdb::Logger* /*logger*/) const override {
|
|
85
|
+
rocksdb::Slice max;
|
|
86
|
+
for (const auto& operand : operand_list) {
|
|
87
|
+
if (compareRev(max, operand) < 0) {
|
|
88
|
+
max = operand;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
new_value->assign(max.data(), max.size());
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static const char* kClassName() { return "MaxRevOperator"; }
|
|
97
|
+
static const char* kNickName() { return "maxRev"; }
|
|
98
|
+
const char* Name() const override { return kClassName(); }
|
|
99
|
+
const char* NickName() const override { return kNickName(); }
|
|
100
|
+
};
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|