@nxtedition/rocksdb 7.0.40 → 7.0.43
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 +58 -19
- package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +27 -11
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +310 -337
- package/deps/rocksdb/rocksdb/cache/clock_cache.h +394 -352
- package/deps/rocksdb/rocksdb/memtable/hash_linklist_rep.cc +100 -78
- package/max_rev_operator.h +99 -0
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
package/binding.cc
CHANGED
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
#include <thread>
|
|
25
25
|
#include <vector>
|
|
26
26
|
|
|
27
|
+
#include "max_rev_operator.h"
|
|
28
|
+
|
|
27
29
|
class NullLogger : public rocksdb::Logger {
|
|
28
30
|
public:
|
|
29
31
|
using rocksdb::Logger::Logv;
|
|
@@ -156,6 +158,37 @@ static napi_status ToString(napi_env env, napi_value from, std::string& to) {
|
|
|
156
158
|
return napi_ok;
|
|
157
159
|
}
|
|
158
160
|
|
|
161
|
+
void noop(void* arg1, void* arg2) {}
|
|
162
|
+
|
|
163
|
+
// TODO (fix): Should use rocksdb::Slice since "to" cannot outlive "from".
|
|
164
|
+
static napi_status ToString(napi_env env, napi_value from, rocksdb::PinnableSlice& to) {
|
|
165
|
+
napi_valuetype type;
|
|
166
|
+
NAPI_STATUS_RETURN(napi_typeof(env, from, &type));
|
|
167
|
+
|
|
168
|
+
if (type == napi_string) {
|
|
169
|
+
size_t length = 0;
|
|
170
|
+
NAPI_STATUS_RETURN(napi_get_value_string_utf8(env, from, nullptr, 0, &length));
|
|
171
|
+
to.GetSelf()->resize(length, '\0');
|
|
172
|
+
NAPI_STATUS_RETURN(napi_get_value_string_utf8(env, from, &(*to.GetSelf())[0], length + 1, &length));
|
|
173
|
+
to.PinSelf();
|
|
174
|
+
} else {
|
|
175
|
+
bool isBuffer;
|
|
176
|
+
NAPI_STATUS_RETURN(napi_is_buffer(env, from, &isBuffer));
|
|
177
|
+
|
|
178
|
+
if (isBuffer) {
|
|
179
|
+
char* buf = nullptr;
|
|
180
|
+
size_t length = 0;
|
|
181
|
+
NAPI_STATUS_RETURN(napi_get_buffer_info(env, from, reinterpret_cast<void**>(&buf), &length));
|
|
182
|
+
|
|
183
|
+
to.PinSlice(rocksdb::Slice(buf, length), noop, nullptr, nullptr);
|
|
184
|
+
} else {
|
|
185
|
+
return napi_invalid_arg;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return napi_ok;
|
|
190
|
+
}
|
|
191
|
+
|
|
159
192
|
static std::optional<std::string> StringProperty(napi_env env, napi_value opts, const std::string_view& name) {
|
|
160
193
|
if (HasProperty(env, opts, name)) {
|
|
161
194
|
const auto property = GetProperty(env, opts, name);
|
|
@@ -215,7 +248,9 @@ napi_status Convert(napi_env env, T&& s, bool asBuffer, napi_value& result) {
|
|
|
215
248
|
if (!s) {
|
|
216
249
|
return napi_get_null(env, &result);
|
|
217
250
|
} else if (asBuffer) {
|
|
218
|
-
|
|
251
|
+
using Y = typename std::remove_pointer<typename std::decay<decltype(*s)>::type>::type;
|
|
252
|
+
auto ptr = new Y(std::move(*s));
|
|
253
|
+
return napi_create_external_buffer(env, ptr->size(), const_cast<char*>(ptr->data()), Finalize<Y>, ptr, &result);
|
|
219
254
|
} else {
|
|
220
255
|
return napi_create_string_utf8(env, s->data(), s->size(), &result);
|
|
221
256
|
}
|
|
@@ -749,8 +784,12 @@ rocksdb::Status InitOptions(napi_env env, T& columnOptions, const U& options) {
|
|
|
749
784
|
|
|
750
785
|
const auto mergeOperatorOpt = StringProperty(env, options, "mergeOperator");
|
|
751
786
|
if (mergeOperatorOpt) {
|
|
752
|
-
|
|
753
|
-
|
|
787
|
+
if (*mergeOperatorOpt == "maxRev") {
|
|
788
|
+
columnOptions.merge_operator = std::make_shared<MaxRevOperator>();
|
|
789
|
+
} else {
|
|
790
|
+
ROCKS_STATUS_RETURN(
|
|
791
|
+
rocksdb::MergeOperator::CreateFromString(configOptions, *mergeOperatorOpt, &columnOptions.merge_operator));
|
|
792
|
+
}
|
|
754
793
|
}
|
|
755
794
|
|
|
756
795
|
const auto cacheSize = Uint32Property(env, options, "cacheSize").value_or(8 << 20);
|
|
@@ -1169,10 +1208,10 @@ NAPI_METHOD(db_put) {
|
|
|
1169
1208
|
Database* database;
|
|
1170
1209
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&database)));
|
|
1171
1210
|
|
|
1172
|
-
|
|
1211
|
+
rocksdb::PinnableSlice key;
|
|
1173
1212
|
NAPI_STATUS_THROWS(ToString(env, argv[1], key));
|
|
1174
1213
|
|
|
1175
|
-
|
|
1214
|
+
rocksdb::PinnableSlice val;
|
|
1176
1215
|
NAPI_STATUS_THROWS(ToString(env, argv[2], val));
|
|
1177
1216
|
|
|
1178
1217
|
rocksdb::ColumnFamilyHandle* column;
|
|
@@ -1387,7 +1426,7 @@ NAPI_METHOD(db_del) {
|
|
|
1387
1426
|
Database* database;
|
|
1388
1427
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&database)));
|
|
1389
1428
|
|
|
1390
|
-
|
|
1429
|
+
rocksdb::PinnableSlice key;
|
|
1391
1430
|
NAPI_STATUS_THROWS(ToString(env, argv[1], key));
|
|
1392
1431
|
|
|
1393
1432
|
rocksdb::ColumnFamilyHandle* column;
|
|
@@ -1496,7 +1535,7 @@ NAPI_METHOD(db_get_property) {
|
|
|
1496
1535
|
Database* database;
|
|
1497
1536
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&database)));
|
|
1498
1537
|
|
|
1499
|
-
|
|
1538
|
+
rocksdb::PinnableSlice property;
|
|
1500
1539
|
NAPI_STATUS_THROWS(ToString(env, argv[1], property));
|
|
1501
1540
|
|
|
1502
1541
|
std::string value;
|
|
@@ -1568,7 +1607,7 @@ NAPI_METHOD(iterator_seek) {
|
|
|
1568
1607
|
Iterator* iterator;
|
|
1569
1608
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&iterator)));
|
|
1570
1609
|
|
|
1571
|
-
|
|
1610
|
+
rocksdb::PinnableSlice target;
|
|
1572
1611
|
NAPI_STATUS_THROWS(ToString(env, argv[1], target));
|
|
1573
1612
|
|
|
1574
1613
|
iterator->first_ = true;
|
|
@@ -1705,14 +1744,14 @@ NAPI_METHOD(batch_do) {
|
|
|
1705
1744
|
|
|
1706
1745
|
rocksdb::WriteBatch batch;
|
|
1707
1746
|
|
|
1708
|
-
std::string type;
|
|
1709
|
-
std::string key;
|
|
1710
|
-
std::string value;
|
|
1711
|
-
|
|
1712
1747
|
uint32_t length;
|
|
1713
1748
|
NAPI_STATUS_THROWS(napi_get_array_length(env, argv[1], &length));
|
|
1714
1749
|
|
|
1715
1750
|
for (uint32_t i = 0; i < length; i++) {
|
|
1751
|
+
rocksdb::PinnableSlice type;
|
|
1752
|
+
rocksdb::PinnableSlice key;
|
|
1753
|
+
rocksdb::PinnableSlice value;
|
|
1754
|
+
|
|
1716
1755
|
napi_value element;
|
|
1717
1756
|
NAPI_STATUS_THROWS(napi_get_element(env, argv[1], i, &element));
|
|
1718
1757
|
|
|
@@ -1789,10 +1828,10 @@ NAPI_METHOD(batch_put) {
|
|
|
1789
1828
|
rocksdb::WriteBatch* batch;
|
|
1790
1829
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], (void**)(&batch)));
|
|
1791
1830
|
|
|
1792
|
-
|
|
1831
|
+
rocksdb::PinnableSlice key;
|
|
1793
1832
|
NAPI_STATUS_THROWS(ToString(env, argv[2], key));
|
|
1794
1833
|
|
|
1795
|
-
|
|
1834
|
+
rocksdb::PinnableSlice val;
|
|
1796
1835
|
NAPI_STATUS_THROWS(ToString(env, argv[3], val));
|
|
1797
1836
|
|
|
1798
1837
|
rocksdb::ColumnFamilyHandle* column;
|
|
@@ -1812,7 +1851,7 @@ NAPI_METHOD(batch_del) {
|
|
|
1812
1851
|
rocksdb::WriteBatch* batch;
|
|
1813
1852
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], reinterpret_cast<void**>(&batch)));
|
|
1814
1853
|
|
|
1815
|
-
|
|
1854
|
+
rocksdb::PinnableSlice key;
|
|
1816
1855
|
NAPI_STATUS_THROWS(ToString(env, argv[2], key));
|
|
1817
1856
|
|
|
1818
1857
|
rocksdb::ColumnFamilyHandle* column;
|
|
@@ -1858,7 +1897,7 @@ NAPI_METHOD(batch_put_log_data) {
|
|
|
1858
1897
|
rocksdb::WriteBatch* batch;
|
|
1859
1898
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], reinterpret_cast<void**>(&batch)));
|
|
1860
1899
|
|
|
1861
|
-
|
|
1900
|
+
rocksdb::PinnableSlice logData;
|
|
1862
1901
|
NAPI_STATUS_THROWS(ToString(env, argv[2], logData));
|
|
1863
1902
|
|
|
1864
1903
|
ROCKS_STATUS_THROWS(batch->PutLogData(logData));
|
|
@@ -1875,10 +1914,10 @@ NAPI_METHOD(batch_merge) {
|
|
|
1875
1914
|
rocksdb::WriteBatch* batch;
|
|
1876
1915
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], (void**)(&batch)));
|
|
1877
1916
|
|
|
1878
|
-
|
|
1917
|
+
rocksdb::PinnableSlice key;
|
|
1879
1918
|
NAPI_STATUS_THROWS(ToString(env, argv[2], key));
|
|
1880
1919
|
|
|
1881
|
-
|
|
1920
|
+
rocksdb::PinnableSlice val;
|
|
1882
1921
|
NAPI_STATUS_THROWS(ToString(env, argv[3], val));
|
|
1883
1922
|
|
|
1884
1923
|
rocksdb::ColumnFamilyHandle* column;
|
|
@@ -1914,7 +1953,7 @@ NAPI_METHOD(db_flush_wal) {
|
|
|
1914
1953
|
return 0;
|
|
1915
1954
|
}
|
|
1916
1955
|
|
|
1917
|
-
template<typename T>
|
|
1956
|
+
template <typename T>
|
|
1918
1957
|
napi_status FromLogFile(napi_env env, const T& file, napi_value* obj) {
|
|
1919
1958
|
NAPI_STATUS_RETURN(napi_create_object(env, obj));
|
|
1920
1959
|
|
|
@@ -114,6 +114,8 @@ DEFINE_uint32(
|
|
|
114
114
|
"(-stress_cache_key) Simulated file size in MiB, for accounting purposes");
|
|
115
115
|
DEFINE_uint32(sck_reopen_nfiles, 100,
|
|
116
116
|
"(-stress_cache_key) Simulate DB re-open average every n files");
|
|
117
|
+
DEFINE_uint32(sck_newdb_nreopen, 1000,
|
|
118
|
+
"(-stress_cache_key) Simulate new DB average every n re-opens");
|
|
117
119
|
DEFINE_uint32(sck_restarts_per_day, 24,
|
|
118
120
|
"(-stress_cache_key) Average simulated process restarts per day "
|
|
119
121
|
"(across DBs)");
|
|
@@ -780,7 +782,7 @@ class StressCacheKey {
|
|
|
780
782
|
|
|
781
783
|
void RunOnce() {
|
|
782
784
|
// Re-initialized simulated state
|
|
783
|
-
const size_t db_count = FLAGS_sck_db_count;
|
|
785
|
+
const size_t db_count = std::max(size_t{FLAGS_sck_db_count}, size_t{1});
|
|
784
786
|
dbs_.reset(new TableProperties[db_count]{});
|
|
785
787
|
const size_t table_mask = (size_t{1} << FLAGS_sck_table_bits) - 1;
|
|
786
788
|
table_.reset(new uint64_t[table_mask + 1]{});
|
|
@@ -797,7 +799,8 @@ class StressCacheKey {
|
|
|
797
799
|
|
|
798
800
|
process_count_ = 0;
|
|
799
801
|
session_count_ = 0;
|
|
800
|
-
|
|
802
|
+
newdb_count_ = 0;
|
|
803
|
+
ResetProcess(/*newdbs*/ true);
|
|
801
804
|
|
|
802
805
|
Random64 r{std::random_device{}()};
|
|
803
806
|
|
|
@@ -816,9 +819,9 @@ class StressCacheKey {
|
|
|
816
819
|
}
|
|
817
820
|
// Any other periodic actions before simulating next file
|
|
818
821
|
if (!FLAGS_sck_footer_unique_id && r.OneIn(FLAGS_sck_reopen_nfiles)) {
|
|
819
|
-
ResetSession(db_i);
|
|
822
|
+
ResetSession(db_i, /*newdb*/ r.OneIn(FLAGS_sck_newdb_nreopen));
|
|
820
823
|
} else if (r.OneIn(restart_nfiles_)) {
|
|
821
|
-
ResetProcess();
|
|
824
|
+
ResetProcess(/*newdbs*/ false);
|
|
822
825
|
}
|
|
823
826
|
// Simulate next file
|
|
824
827
|
OffsetableCacheKey ock;
|
|
@@ -870,7 +873,7 @@ class StressCacheKey {
|
|
|
870
873
|
// Our goal is to predict probability of no collisions, not expected
|
|
871
874
|
// number of collisions. To make the distinction, we have to get rid
|
|
872
875
|
// of observing correlated collisions, which this takes care of:
|
|
873
|
-
ResetProcess();
|
|
876
|
+
ResetProcess(/*newdbs*/ false);
|
|
874
877
|
} else {
|
|
875
878
|
// Replace (end of lifetime for file that was in this slot)
|
|
876
879
|
table_[pos] = reduced_key;
|
|
@@ -888,10 +891,11 @@ class StressCacheKey {
|
|
|
888
891
|
}
|
|
889
892
|
// Report
|
|
890
893
|
printf(
|
|
891
|
-
"%" PRIu64 " days, %" PRIu64 " proc, %" PRIu64
|
|
892
|
-
"
|
|
894
|
+
"%" PRIu64 " days, %" PRIu64 " proc, %" PRIu64 " sess, %" PRIu64
|
|
895
|
+
" newdb, %u coll, occ %g%%, ejected %g%% \r",
|
|
893
896
|
file_count / FLAGS_sck_files_per_day, process_count_,
|
|
894
|
-
session_count_,
|
|
897
|
+
session_count_, newdb_count_ - FLAGS_sck_db_count,
|
|
898
|
+
collisions_this_run, 100.0 * sampled_count / 1000.0,
|
|
895
899
|
100.0 * (1.0 - sampled_count / 1000.0 * table_mask / file_count));
|
|
896
900
|
fflush(stdout);
|
|
897
901
|
}
|
|
@@ -899,16 +903,27 @@ class StressCacheKey {
|
|
|
899
903
|
collisions_ += collisions_this_run;
|
|
900
904
|
}
|
|
901
905
|
|
|
902
|
-
void ResetSession(size_t i) {
|
|
906
|
+
void ResetSession(size_t i, bool newdb) {
|
|
903
907
|
dbs_[i].db_session_id = DBImpl::GenerateDbSessionId(nullptr);
|
|
908
|
+
if (newdb) {
|
|
909
|
+
++newdb_count_;
|
|
910
|
+
if (FLAGS_sck_footer_unique_id) {
|
|
911
|
+
// Simulate how footer id would behave
|
|
912
|
+
dbs_[i].db_id = "none";
|
|
913
|
+
} else {
|
|
914
|
+
// db_id might be ignored, depending on the implementation details
|
|
915
|
+
dbs_[i].db_id = std::to_string(newdb_count_);
|
|
916
|
+
dbs_[i].orig_file_number = 0;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
904
919
|
session_count_++;
|
|
905
920
|
}
|
|
906
921
|
|
|
907
|
-
void ResetProcess() {
|
|
922
|
+
void ResetProcess(bool newdbs) {
|
|
908
923
|
process_count_++;
|
|
909
924
|
DBImpl::TEST_ResetDbSessionIdGen();
|
|
910
925
|
for (size_t i = 0; i < FLAGS_sck_db_count; ++i) {
|
|
911
|
-
ResetSession(i);
|
|
926
|
+
ResetSession(i, newdbs);
|
|
912
927
|
}
|
|
913
928
|
if (FLAGS_sck_footer_unique_id) {
|
|
914
929
|
// For footer unique ID, this tracks process-wide generated SST file
|
|
@@ -923,6 +938,7 @@ class StressCacheKey {
|
|
|
923
938
|
std::unique_ptr<uint64_t[]> table_;
|
|
924
939
|
uint64_t process_count_ = 0;
|
|
925
940
|
uint64_t session_count_ = 0;
|
|
941
|
+
uint64_t newdb_count_ = 0;
|
|
926
942
|
uint64_t collisions_ = 0;
|
|
927
943
|
uint32_t restart_nfiles_ = 0;
|
|
928
944
|
double multiplier_ = 0.0;
|