@nxtedition/rocksdb 7.0.38 → 7.0.41

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.
Files changed (66) hide show
  1. package/binding.cc +62 -33
  2. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +27 -11
  3. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +310 -337
  4. package/deps/rocksdb/rocksdb/cache/clock_cache.h +394 -352
  5. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +1 -1
  6. package/deps/rocksdb/rocksdb/db/column_family.cc +2 -2
  7. package/deps/rocksdb/rocksdb/db/column_family_test.cc +1 -1
  8. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +13 -3
  9. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +273 -134
  10. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +33 -2
  11. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +11 -3
  12. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +2 -1
  13. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +2 -2
  14. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +133 -5
  15. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +130 -1
  16. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +8 -4
  17. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +11 -9
  18. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +209 -12
  19. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +54 -39
  20. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +102 -19
  21. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +30 -11
  22. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +1 -1
  23. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +28 -25
  24. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +0 -14
  25. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +63 -54
  26. package/deps/rocksdb/rocksdb/db/db_test.cc +6 -6
  27. package/deps/rocksdb/rocksdb/db/error_handler.cc +7 -0
  28. package/deps/rocksdb/rocksdb/db/error_handler.h +10 -9
  29. package/deps/rocksdb/rocksdb/db/log_test.cc +13 -6
  30. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +1 -1
  31. package/deps/rocksdb/rocksdb/db/table_cache.cc +21 -0
  32. package/deps/rocksdb/rocksdb/db/table_cache.h +5 -0
  33. package/deps/rocksdb/rocksdb/db/version_set.cc +3 -2
  34. package/deps/rocksdb/rocksdb/db/version_set.h +6 -4
  35. package/deps/rocksdb/rocksdb/db/version_set_test.cc +8 -6
  36. package/deps/rocksdb/rocksdb/db/wal_edit.cc +22 -15
  37. package/deps/rocksdb/rocksdb/db/wal_edit.h +10 -0
  38. package/deps/rocksdb/rocksdb/db/wal_edit_test.cc +4 -5
  39. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +0 -36
  40. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +1 -12
  41. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +23 -29
  42. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +0 -5
  43. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +7 -0
  44. package/deps/rocksdb/rocksdb/env/env_test.cc +0 -5
  45. package/deps/rocksdb/rocksdb/env/io_posix.cc +1 -7
  46. package/deps/rocksdb/rocksdb/memtable/hash_linklist_rep.cc +100 -78
  47. package/deps/rocksdb/rocksdb/options/options_test.cc +16 -0
  48. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +51 -0
  49. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +3 -0
  50. package/deps/rocksdb/rocksdb/table/table_reader.h +14 -0
  51. package/deps/rocksdb/rocksdb/table/table_test.cc +52 -0
  52. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +8 -38
  53. package/deps/rocksdb/rocksdb/util/rate_limiter.cc +27 -21
  54. package/deps/rocksdb/rocksdb/util/rate_limiter.h +12 -10
  55. package/deps/rocksdb/rocksdb/util/rate_limiter_test.cc +11 -8
  56. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +2 -1
  57. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.cc +59 -0
  58. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.h +12 -0
  59. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +31 -0
  60. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +0 -3
  61. package/index.js +2 -2
  62. package/iterator.js +1 -1
  63. package/max_rev_operator.h +114 -0
  64. package/package.json +1 -1
  65. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  66. 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;
@@ -130,17 +132,6 @@ static std::optional<int> Int32Property(napi_env env, napi_value obj, const std:
130
132
  return {};
131
133
  }
132
134
 
133
- static std::optional<int64_t> Int64Property(napi_env env, napi_value obj, const std::string_view& key) {
134
- if (HasProperty(env, obj, key.data())) {
135
- const auto value = GetProperty(env, obj, key.data());
136
- int64_t result;
137
- napi_get_value_int64(env, value, &result);
138
- return result;
139
- }
140
-
141
- return {};
142
- }
143
-
144
135
  static napi_status ToString(napi_env env, napi_value from, std::string& to) {
145
136
  napi_valuetype type;
146
137
  NAPI_STATUS_RETURN(napi_typeof(env, from, &type));
@@ -167,6 +158,37 @@ static napi_status ToString(napi_env env, napi_value from, std::string& to) {
167
158
  return napi_ok;
168
159
  }
169
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
+
170
192
  static std::optional<std::string> StringProperty(napi_env env, napi_value opts, const std::string_view& name) {
171
193
  if (HasProperty(env, opts, name)) {
172
194
  const auto property = GetProperty(env, opts, name);
@@ -226,7 +248,9 @@ napi_status Convert(napi_env env, T&& s, bool asBuffer, napi_value& result) {
226
248
  if (!s) {
227
249
  return napi_get_null(env, &result);
228
250
  } else if (asBuffer) {
229
- return napi_create_buffer_copy(env, s->size(), s->data(), NULL, &result);
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);
230
254
  } else {
231
255
  return napi_create_string_utf8(env, s->data(), s->size(), &result);
232
256
  }
@@ -760,8 +784,12 @@ rocksdb::Status InitOptions(napi_env env, T& columnOptions, const U& options) {
760
784
 
761
785
  const auto mergeOperatorOpt = StringProperty(env, options, "mergeOperator");
762
786
  if (mergeOperatorOpt) {
763
- ROCKS_STATUS_RETURN(
764
- rocksdb::MergeOperator::CreateFromString(configOptions, *mergeOperatorOpt, &columnOptions.merge_operator));
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
+ }
765
793
  }
766
794
 
767
795
  const auto cacheSize = Uint32Property(env, options, "cacheSize").value_or(8 << 20);
@@ -1180,10 +1208,10 @@ NAPI_METHOD(db_put) {
1180
1208
  Database* database;
1181
1209
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&database)));
1182
1210
 
1183
- std::string key;
1211
+ rocksdb::PinnableSlice key;
1184
1212
  NAPI_STATUS_THROWS(ToString(env, argv[1], key));
1185
1213
 
1186
- std::string val;
1214
+ rocksdb::PinnableSlice val;
1187
1215
  NAPI_STATUS_THROWS(ToString(env, argv[2], val));
1188
1216
 
1189
1217
  rocksdb::ColumnFamilyHandle* column;
@@ -1398,7 +1426,7 @@ NAPI_METHOD(db_del) {
1398
1426
  Database* database;
1399
1427
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&database)));
1400
1428
 
1401
- std::string key;
1429
+ rocksdb::PinnableSlice key;
1402
1430
  NAPI_STATUS_THROWS(ToString(env, argv[1], key));
1403
1431
 
1404
1432
  rocksdb::ColumnFamilyHandle* column;
@@ -1507,7 +1535,7 @@ NAPI_METHOD(db_get_property) {
1507
1535
  Database* database;
1508
1536
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&database)));
1509
1537
 
1510
- std::string property;
1538
+ rocksdb::PinnableSlice property;
1511
1539
  NAPI_STATUS_THROWS(ToString(env, argv[1], property));
1512
1540
 
1513
1541
  std::string value;
@@ -1528,7 +1556,7 @@ NAPI_METHOD(db_get_latest_sequence) {
1528
1556
  const auto seq = database->db_->GetLatestSequenceNumber();
1529
1557
 
1530
1558
  napi_value result;
1531
- NAPI_STATUS_THROWS(napi_create_bigint_int64(env, seq, &result));
1559
+ NAPI_STATUS_THROWS(napi_create_int64(env, seq, &result));
1532
1560
 
1533
1561
  return result;
1534
1562
  }
@@ -1579,7 +1607,7 @@ NAPI_METHOD(iterator_seek) {
1579
1607
  Iterator* iterator;
1580
1608
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&iterator)));
1581
1609
 
1582
- std::string target;
1610
+ rocksdb::PinnableSlice target;
1583
1611
  NAPI_STATUS_THROWS(ToString(env, argv[1], target));
1584
1612
 
1585
1613
  iterator->first_ = true;
@@ -1609,7 +1637,7 @@ NAPI_METHOD(iterator_get_sequence) {
1609
1637
  const auto seq = iterator->snapshot_->GetSequenceNumber();
1610
1638
 
1611
1639
  napi_value result;
1612
- NAPI_STATUS_THROWS(napi_create_bigint_int64(env, seq, &result));
1640
+ NAPI_STATUS_THROWS(napi_create_int64(env, seq, &result));
1613
1641
 
1614
1642
  return result;
1615
1643
  }
@@ -1716,14 +1744,14 @@ NAPI_METHOD(batch_do) {
1716
1744
 
1717
1745
  rocksdb::WriteBatch batch;
1718
1746
 
1719
- std::string type;
1720
- std::string key;
1721
- std::string value;
1722
-
1723
1747
  uint32_t length;
1724
1748
  NAPI_STATUS_THROWS(napi_get_array_length(env, argv[1], &length));
1725
1749
 
1726
1750
  for (uint32_t i = 0; i < length; i++) {
1751
+ rocksdb::PinnableSlice type;
1752
+ rocksdb::PinnableSlice key;
1753
+ rocksdb::PinnableSlice value;
1754
+
1727
1755
  napi_value element;
1728
1756
  NAPI_STATUS_THROWS(napi_get_element(env, argv[1], i, &element));
1729
1757
 
@@ -1800,10 +1828,10 @@ NAPI_METHOD(batch_put) {
1800
1828
  rocksdb::WriteBatch* batch;
1801
1829
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], (void**)(&batch)));
1802
1830
 
1803
- std::string key;
1831
+ rocksdb::PinnableSlice key;
1804
1832
  NAPI_STATUS_THROWS(ToString(env, argv[2], key));
1805
1833
 
1806
- std::string val;
1834
+ rocksdb::PinnableSlice val;
1807
1835
  NAPI_STATUS_THROWS(ToString(env, argv[3], val));
1808
1836
 
1809
1837
  rocksdb::ColumnFamilyHandle* column;
@@ -1823,7 +1851,7 @@ NAPI_METHOD(batch_del) {
1823
1851
  rocksdb::WriteBatch* batch;
1824
1852
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], reinterpret_cast<void**>(&batch)));
1825
1853
 
1826
- std::string key;
1854
+ rocksdb::PinnableSlice key;
1827
1855
  NAPI_STATUS_THROWS(ToString(env, argv[2], key));
1828
1856
 
1829
1857
  rocksdb::ColumnFamilyHandle* column;
@@ -1869,7 +1897,7 @@ NAPI_METHOD(batch_put_log_data) {
1869
1897
  rocksdb::WriteBatch* batch;
1870
1898
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], reinterpret_cast<void**>(&batch)));
1871
1899
 
1872
- std::string logData;
1900
+ rocksdb::PinnableSlice logData;
1873
1901
  NAPI_STATUS_THROWS(ToString(env, argv[2], logData));
1874
1902
 
1875
1903
  ROCKS_STATUS_THROWS(batch->PutLogData(logData));
@@ -1886,10 +1914,10 @@ NAPI_METHOD(batch_merge) {
1886
1914
  rocksdb::WriteBatch* batch;
1887
1915
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], (void**)(&batch)));
1888
1916
 
1889
- std::string key;
1917
+ rocksdb::PinnableSlice key;
1890
1918
  NAPI_STATUS_THROWS(ToString(env, argv[2], key));
1891
1919
 
1892
- std::string val;
1920
+ rocksdb::PinnableSlice val;
1893
1921
  NAPI_STATUS_THROWS(ToString(env, argv[3], val));
1894
1922
 
1895
1923
  rocksdb::ColumnFamilyHandle* column;
@@ -1907,7 +1935,7 @@ NAPI_METHOD(batch_count) {
1907
1935
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], reinterpret_cast<void**>(&batch)));
1908
1936
 
1909
1937
  napi_value result;
1910
- NAPI_STATUS_THROWS(napi_create_bigint_int64(env, batch->Count(), &result));
1938
+ NAPI_STATUS_THROWS(napi_create_int64(env, batch->Count(), &result));
1911
1939
 
1912
1940
  return result;
1913
1941
  }
@@ -1925,7 +1953,8 @@ NAPI_METHOD(db_flush_wal) {
1925
1953
  return 0;
1926
1954
  }
1927
1955
 
1928
- napi_status FromLogFile(napi_env env, const auto& file, napi_value* obj) {
1956
+ template <typename T>
1957
+ napi_status FromLogFile(napi_env env, const T& file, napi_value* obj) {
1929
1958
  NAPI_STATUS_RETURN(napi_create_object(env, obj));
1930
1959
 
1931
1960
  napi_value pathName;
@@ -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
- ResetProcess();
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
- " sess, %u coll, occ %g%%, ejected %g%% \r",
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_, collisions_this_run, 100.0 * sampled_count / 1000.0,
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;