@nxtedition/rocksdb 7.1.5 → 7.1.8

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 (67) hide show
  1. package/binding.cc +32 -14
  2. package/deps/rocksdb/rocksdb/cache/cache.cc +4 -0
  3. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +6 -8
  4. package/deps/rocksdb/rocksdb/cache/cache_key.cc +184 -164
  5. package/deps/rocksdb/rocksdb/cache/cache_key.h +38 -29
  6. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager_test.cc +4 -4
  7. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +4 -2
  8. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +11 -9
  9. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +1 -1
  10. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +28 -18
  11. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +86 -17
  12. package/deps/rocksdb/rocksdb/cache/lru_cache.h +48 -8
  13. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +356 -153
  14. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +3 -7
  15. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +4 -5
  16. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +2 -3
  17. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +12 -4
  18. package/deps/rocksdb/rocksdb/db/blob/db_blob_compaction_test.cc +69 -0
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +6 -1
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +4 -1
  21. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +222 -182
  22. package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +239 -23
  23. package/deps/rocksdb/rocksdb/db/db_test2.cc +6 -2
  24. package/deps/rocksdb/rocksdb/db/event_helpers.cc +2 -1
  25. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +6 -0
  26. package/deps/rocksdb/rocksdb/db/import_column_family_job.h +6 -0
  27. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +6 -0
  28. package/deps/rocksdb/rocksdb/db/kv_checksum.h +8 -4
  29. package/deps/rocksdb/rocksdb/db/memtable.cc +173 -33
  30. package/deps/rocksdb/rocksdb/db/memtable.h +10 -0
  31. package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +2 -1
  32. package/deps/rocksdb/rocksdb/db/version_set.cc +37 -18
  33. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +2 -1
  34. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -0
  35. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +6 -0
  36. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +2 -0
  37. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +15 -0
  38. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +31 -6
  39. package/deps/rocksdb/rocksdb/memory/memory_allocator_test.cc +1 -1
  40. package/deps/rocksdb/rocksdb/options/cf_options.cc +4 -0
  41. package/deps/rocksdb/rocksdb/options/cf_options.h +4 -0
  42. package/deps/rocksdb/rocksdb/options/options_helper.cc +2 -0
  43. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +2 -1
  44. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +2 -6
  45. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +1 -0
  46. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +2 -4
  47. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +1 -7
  48. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +2 -1
  49. package/deps/rocksdb/rocksdb/table/unique_id.cc +22 -24
  50. package/deps/rocksdb/rocksdb/table/unique_id_impl.h +2 -1
  51. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py +7 -0
  52. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +27 -3
  53. package/deps/rocksdb/rocksdb/util/async_file_reader.cc +2 -1
  54. package/deps/rocksdb/rocksdb/util/async_file_reader.h +3 -3
  55. package/deps/rocksdb/rocksdb/util/coro_utils.h +2 -1
  56. package/deps/rocksdb/rocksdb/util/hash_test.cc +67 -0
  57. package/deps/rocksdb/rocksdb/util/math.h +41 -0
  58. package/deps/rocksdb/rocksdb/util/math128.h +6 -0
  59. package/deps/rocksdb/rocksdb/util/single_thread_executor.h +2 -1
  60. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +3 -6
  61. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_test.h +5 -0
  62. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_lock_manager.h +6 -0
  63. package/index.js +15 -6
  64. package/package.json +1 -1
  65. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  66. package/prebuilds/darwin-x64/node.napi.node +0 -0
  67. package/prebuilds/linux-x64/node.napi.node +0 -0
@@ -162,6 +162,8 @@ struct MutableCFOptions {
162
162
  Temperature::kUnknown
163
163
  ? options.bottommost_temperature
164
164
  : options.last_level_temperature),
165
+ memtable_protection_bytes_per_key(
166
+ options.memtable_protection_bytes_per_key),
165
167
  sample_for_compression(
166
168
  options.sample_for_compression), // TODO: is 0 fine here?
167
169
  compression_per_level(options.compression_per_level) {
@@ -210,6 +212,7 @@ struct MutableCFOptions {
210
212
  compression(Snappy_Supported() ? kSnappyCompression : kNoCompression),
211
213
  bottommost_compression(kDisableCompressionOption),
212
214
  last_level_temperature(Temperature::kUnknown),
215
+ memtable_protection_bytes_per_key(0),
213
216
  sample_for_compression(0) {}
214
217
 
215
218
  explicit MutableCFOptions(const Options& options);
@@ -298,6 +301,7 @@ struct MutableCFOptions {
298
301
  CompressionOptions compression_opts;
299
302
  CompressionOptions bottommost_compression_opts;
300
303
  Temperature last_level_temperature;
304
+ uint32_t memtable_protection_bytes_per_key;
301
305
 
302
306
  uint64_t sample_for_compression;
303
307
  std::vector<CompressionType> compression_per_level;
@@ -214,6 +214,8 @@ void UpdateColumnFamilyOptions(const MutableCFOptions& moptions,
214
214
  cf_opts->prefix_extractor = moptions.prefix_extractor;
215
215
  cf_opts->experimental_mempurge_threshold =
216
216
  moptions.experimental_mempurge_threshold;
217
+ cf_opts->memtable_protection_bytes_per_key =
218
+ moptions.memtable_protection_bytes_per_key;
217
219
 
218
220
  // Compaction related options
219
221
  cf_opts->disable_auto_compactions = moptions.disable_auto_compactions;
@@ -532,7 +532,8 @@ TEST_F(OptionsSettableTest, ColumnFamilyOptionsAllFieldsSettable) {
532
532
  "preclude_last_level_data_seconds=86400;"
533
533
  "compaction_options_fifo={max_table_files_size=3;allow_"
534
534
  "compaction=false;age_for_warm=1;};"
535
- "blob_cache=1M;",
535
+ "blob_cache=1M;"
536
+ "memtable_protection_bytes_per_key=2;",
536
537
  new_options));
537
538
 
538
539
  ASSERT_NE(new_options->blob_cache.get(), nullptr);
@@ -895,12 +895,8 @@ BlockBasedTableBuilder::BlockBasedTableBuilder(
895
895
  "BlockBasedTableBuilder::BlockBasedTableBuilder:PreSetupBaseCacheKey",
896
896
  const_cast<TableProperties*>(&rep_->props));
897
897
 
898
- // Extremely large files use atypical cache key encoding, and we don't
899
- // know ahead of time how big the file will be. But assuming it's less
900
- // than 4TB, we will correctly predict the cache keys.
901
- BlockBasedTable::SetupBaseCacheKey(
902
- &rep_->props, tbo.db_session_id, tbo.cur_file_num,
903
- BlockBasedTable::kMaxFileSizeStandardEncoding, &rep_->base_cache_key);
898
+ BlockBasedTable::SetupBaseCacheKey(&rep_->props, tbo.db_session_id,
899
+ tbo.cur_file_num, &rep_->base_cache_key);
904
900
 
905
901
  if (rep_->IsParallelCompressionEnabled()) {
906
902
  StartParallelCompression();
@@ -454,6 +454,7 @@ void BlockBasedTableFactory::InitializeOptions() {
454
454
  // It makes little sense to pay overhead for mid-point insertion while the
455
455
  // block size is only 8MB.
456
456
  co.high_pri_pool_ratio = 0.0;
457
+ co.low_pri_pool_ratio = 0.0;
457
458
  table_options_.block_cache = NewLRUCache(co);
458
459
  }
459
460
  if (table_options_.block_size_deviation < 0 ||
@@ -521,7 +521,6 @@ Status GetGlobalSequenceNumber(const TableProperties& table_properties,
521
521
  void BlockBasedTable::SetupBaseCacheKey(const TableProperties* properties,
522
522
  const std::string& cur_db_session_id,
523
523
  uint64_t cur_file_number,
524
- uint64_t file_size,
525
524
  OffsetableCacheKey* out_base_cache_key,
526
525
  bool* out_is_stable) {
527
526
  // Use a stable cache key if sufficient data is in table properties
@@ -565,8 +564,7 @@ void BlockBasedTable::SetupBaseCacheKey(const TableProperties* properties,
565
564
 
566
565
  // Minimum block size is 5 bytes; therefore we can trim off two lower bits
567
566
  // from offsets. See GetCacheKey.
568
- *out_base_cache_key = OffsetableCacheKey(db_id, db_session_id, file_num,
569
- /*max_offset*/ file_size >> 2);
567
+ *out_base_cache_key = OffsetableCacheKey(db_id, db_session_id, file_num);
570
568
  }
571
569
 
572
570
  CacheKey BlockBasedTable::GetCacheKey(const OffsetableCacheKey& base_cache_key,
@@ -717,7 +715,7 @@ Status BlockBasedTable::Open(
717
715
 
718
716
  // With properties loaded, we can set up portable/stable cache keys
719
717
  SetupBaseCacheKey(rep->table_properties.get(), cur_db_session_id,
720
- cur_file_num, file_size, &rep->base_cache_key);
718
+ cur_file_num, &rep->base_cache_key);
721
719
 
722
720
  rep->persistent_cache_options =
723
721
  PersistentCacheOptions(rep->table_options.persistent_cache,
@@ -231,15 +231,9 @@ class BlockBasedTable : public TableReader {
231
231
 
232
232
  class IndexReaderCommon;
233
233
 
234
- // Maximum SST file size that uses standard CacheKey encoding scheme.
235
- // See GetCacheKey to explain << 2. + 3 is permitted because it is trimmed
236
- // off by >> 2 in GetCacheKey.
237
- static constexpr uint64_t kMaxFileSizeStandardEncoding =
238
- (OffsetableCacheKey::kMaxOffsetStandardEncoding << 2) + 3;
239
-
240
234
  static void SetupBaseCacheKey(const TableProperties* properties,
241
235
  const std::string& cur_db_session_id,
242
- uint64_t cur_file_number, uint64_t file_size,
236
+ uint64_t cur_file_number,
243
237
  OffsetableCacheKey* out_base_cache_key,
244
238
  bool* out_is_stable = nullptr);
245
239
 
@@ -1,4 +1,5 @@
1
- // Copyright (c) Meta Platforms, Inc. and its affiliates. All Rights Reserved.
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ //
2
3
  // This source code is licensed under both the GPLv2 (found in the
3
4
  // COPYING file in the root directory) and Apache 2.0 License
4
5
  // (found in the LICENSE.Apache file in the root directory).
@@ -58,22 +58,34 @@ Status DecodeSessionId(const std::string &db_session_id, uint64_t *upper,
58
58
 
59
59
  Status GetSstInternalUniqueId(const std::string &db_id,
60
60
  const std::string &db_session_id,
61
- uint64_t file_number, UniqueIdPtr out) {
62
- if (db_id.empty()) {
63
- return Status::NotSupported("Missing db_id");
64
- }
65
- if (file_number == 0) {
66
- return Status::NotSupported("Missing or bad file number");
67
- }
68
- if (db_session_id.empty()) {
69
- return Status::NotSupported("Missing db_session_id");
61
+ uint64_t file_number, UniqueIdPtr out,
62
+ bool force) {
63
+ if (!force) {
64
+ if (db_id.empty()) {
65
+ return Status::NotSupported("Missing db_id");
66
+ }
67
+ if (file_number == 0) {
68
+ return Status::NotSupported("Missing or bad file number");
69
+ }
70
+ if (db_session_id.empty()) {
71
+ return Status::NotSupported("Missing db_session_id");
72
+ }
70
73
  }
71
74
  uint64_t session_upper = 0; // Assignment to appease clang-analyze
72
75
  uint64_t session_lower = 0; // Assignment to appease clang-analyze
73
76
  {
74
77
  Status s = DecodeSessionId(db_session_id, &session_upper, &session_lower);
75
78
  if (!s.ok()) {
76
- return s;
79
+ if (!force) {
80
+ return s;
81
+ } else {
82
+ // A reasonable fallback in case malformed
83
+ Hash2x64(db_session_id.data(), db_session_id.size(), &session_upper,
84
+ &session_lower);
85
+ if (session_lower == 0) {
86
+ session_lower = session_upper | 1;
87
+ }
88
+ }
77
89
  }
78
90
  }
79
91
 
@@ -107,20 +119,6 @@ Status GetSstInternalUniqueId(const std::string &db_id,
107
119
  return Status::OK();
108
120
  }
109
121
 
110
- Status GetSstInternalUniqueId(const std::string &db_id,
111
- const std::string &db_session_id,
112
- uint64_t file_number, UniqueId64x2 *out) {
113
- UniqueId64x3 tmp{};
114
- Status s = GetSstInternalUniqueId(db_id, db_session_id, file_number, &tmp);
115
- if (s.ok()) {
116
- (*out)[0] = tmp[0];
117
- (*out)[1] = tmp[1];
118
- } else {
119
- *out = {0, 0};
120
- }
121
- return s;
122
- }
123
-
124
122
  namespace {
125
123
  // For InternalUniqueIdToExternal / ExternalUniqueIdToInternal we want all
126
124
  // zeros in first 128 bits to map to itself, so that excluding zero in
@@ -47,7 +47,8 @@ struct UniqueIdPtr {
47
47
  // is long term stable.
48
48
  Status GetSstInternalUniqueId(const std::string &db_id,
49
49
  const std::string &db_session_id,
50
- uint64_t file_number, UniqueIdPtr out);
50
+ uint64_t file_number, UniqueIdPtr out,
51
+ bool force = false);
51
52
 
52
53
  // Helper for GetUniqueIdFromTableProperties. External unique ids go through
53
54
  // this extra hashing layer so that prefixes of the unique id have predictable
@@ -1,4 +1,11 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ #
3
+ # This source code is licensed under both the GPLv2 (found in the
4
+ # COPYING file in the root directory) and Apache 2.0 License
5
+ # (found in the LICENSE.Apache file in the root directory).
6
+
1
7
  #!/usr/bin/env python3
8
+
2
9
  import csv
3
10
  import math
4
11
  import os
@@ -570,6 +570,9 @@ DEFINE_double(cache_high_pri_pool_ratio, 0.0,
570
570
  "If > 0.0, we also enable "
571
571
  "cache_index_and_filter_blocks_with_high_priority.");
572
572
 
573
+ DEFINE_double(cache_low_pri_pool_ratio, 0.0,
574
+ "Ratio of block cache reserve for low pri blocks.");
575
+
573
576
  DEFINE_string(cache_type, "lru_cache", "Type of block cache.");
574
577
 
575
578
  DEFINE_bool(use_compressed_secondary_cache, false,
@@ -589,6 +592,9 @@ DEFINE_double(compressed_secondary_cache_high_pri_pool_ratio, 0.0,
589
592
  "If > 0.0, we also enable "
590
593
  "cache_index_and_filter_blocks_with_high_priority.");
591
594
 
595
+ DEFINE_double(compressed_secondary_cache_low_pri_pool_ratio, 0.0,
596
+ "Ratio of block cache reserve for low pri blocks.");
597
+
592
598
  DEFINE_string(compressed_secondary_cache_compression_type, "lz4",
593
599
  "The compression algorithm to use for large "
594
600
  "values stored in CompressedSecondaryCache.");
@@ -1695,6 +1701,13 @@ DEFINE_uint32(write_batch_protection_bytes_per_key, 0,
1695
1701
  "Size of per-key-value checksum in each write batch. Currently "
1696
1702
  "only value 0 and 8 are supported.");
1697
1703
 
1704
+ DEFINE_uint32(
1705
+ memtable_protection_bytes_per_key, 0,
1706
+ "Enable memtable per key-value checksum protection. "
1707
+ "Each entry in memtable will be suffixed by a per key-value checksum. "
1708
+ "This options determines the size of such checksums. "
1709
+ "Supported values: 0, 1, 2, 4, 8.");
1710
+
1698
1711
  DEFINE_bool(build_info, false,
1699
1712
  "Print the build info via GetRocksBuildInfoAsString");
1700
1713
 
@@ -3015,11 +3028,12 @@ class Benchmark {
3015
3028
  #ifdef MEMKIND
3016
3029
  FLAGS_use_cache_memkind_kmem_allocator
3017
3030
  ? std::make_shared<MemkindKmemAllocator>()
3018
- : nullptr
3031
+ : nullptr,
3019
3032
  #else
3020
- nullptr
3033
+ nullptr,
3021
3034
  #endif
3022
- );
3035
+ kDefaultToAdaptiveMutex, kDefaultCacheMetadataChargePolicy,
3036
+ FLAGS_cache_low_pri_pool_ratio);
3023
3037
  if (FLAGS_use_cache_memkind_kmem_allocator) {
3024
3038
  #ifndef MEMKIND
3025
3039
  fprintf(stderr, "Memkind library is not linked with the binary.");
@@ -3048,6 +3062,8 @@ class Benchmark {
3048
3062
  FLAGS_compressed_secondary_cache_numshardbits;
3049
3063
  secondary_cache_opts.high_pri_pool_ratio =
3050
3064
  FLAGS_compressed_secondary_cache_high_pri_pool_ratio;
3065
+ secondary_cache_opts.low_pri_pool_ratio =
3066
+ FLAGS_compressed_secondary_cache_low_pri_pool_ratio;
3051
3067
  secondary_cache_opts.compression_type =
3052
3068
  FLAGS_compressed_secondary_cache_compression_type_e;
3053
3069
  secondary_cache_opts.compress_format_version =
@@ -4289,6 +4305,12 @@ class Benchmark {
4289
4305
  block_based_options.cache_index_and_filter_blocks_with_high_priority =
4290
4306
  true;
4291
4307
  }
4308
+ if (FLAGS_cache_high_pri_pool_ratio + FLAGS_cache_low_pri_pool_ratio >
4309
+ 1.0) {
4310
+ fprintf(stderr,
4311
+ "Sum of high_pri_pool_ratio and low_pri_pool_ratio "
4312
+ "cannot exceed 1.0.\n");
4313
+ }
4292
4314
  block_based_options.block_cache = cache_;
4293
4315
  block_based_options.cache_usage_options.options_overrides.insert(
4294
4316
  {CacheEntryRole::kCompressionDictionaryBuildingBuffer,
@@ -4586,6 +4608,8 @@ class Benchmark {
4586
4608
  exit(1);
4587
4609
  }
4588
4610
  #endif // ROCKSDB_LITE
4611
+ options.memtable_protection_bytes_per_key =
4612
+ FLAGS_memtable_protection_bytes_per_key;
4589
4613
  }
4590
4614
 
4591
4615
  void InitializeOptionsGeneral(Options* opts) {
@@ -1,4 +1,5 @@
1
- // Copyright (c) Meta Platforms, Inc. and its affiliates. All Rights Reserved.
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ //
2
3
  // This source code is licensed under both the GPLv2 (found in the
3
4
  // COPYING file in the root directory) and Apache 2.0 License
4
5
  // (found in the LICENSE.Apache file in the root directory).
@@ -1,8 +1,8 @@
1
- // Copyright (c) Meta Platforms, Inc. and its affiliates. All Rights Reserved.
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ //
2
3
  // This source code is licensed under both the GPLv2 (found in the
3
4
  // COPYING file in the root directory) and Apache 2.0 License
4
- // (found in the LICENSE.Apache file in the root directory).
5
- //
5
+ // (found in the LICENSE.Apache file in the root directory).#pragma once
6
6
  #pragma once
7
7
 
8
8
  #if USE_COROUTINES
@@ -1,4 +1,5 @@
1
- // Copyright (c) Meta Platforms, Inc. and its affiliates. All Rights Reserved.
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ //
2
3
  // This source code is licensed under both the GPLv2 (found in the
3
4
  // COPYING file in the root directory) and Apache 2.0 License
4
5
  // (found in the LICENSE.Apache file in the root directory).
@@ -569,6 +569,7 @@ using ROCKSDB_NAMESPACE::ConstexprFloorLog2;
569
569
  using ROCKSDB_NAMESPACE::CountTrailingZeroBits;
570
570
  using ROCKSDB_NAMESPACE::DecodeFixed128;
571
571
  using ROCKSDB_NAMESPACE::DecodeFixedGeneric;
572
+ using ROCKSDB_NAMESPACE::DownwardInvolution;
572
573
  using ROCKSDB_NAMESPACE::EncodeFixed128;
573
574
  using ROCKSDB_NAMESPACE::EncodeFixedGeneric;
574
575
  using ROCKSDB_NAMESPACE::FloorLog2;
@@ -577,6 +578,8 @@ using ROCKSDB_NAMESPACE::Multiply64to128;
577
578
  using ROCKSDB_NAMESPACE::Unsigned128;
578
579
  using ROCKSDB_NAMESPACE::Upper64of128;
579
580
 
581
+ int blah(int x) { return DownwardInvolution(x); }
582
+
580
583
  template <typename T>
581
584
  static void test_BitOps() {
582
585
  // This complex code is to generalize to 128-bit values. Otherwise
@@ -640,6 +643,70 @@ static void test_BitOps() {
640
643
  EXPECT_EQ(ReverseBits(vm1), static_cast<T>(rv * ~T{1}));
641
644
  }
642
645
  #endif
646
+
647
+ // DownwardInvolution
648
+ {
649
+ T misc = static_cast<T>(/*random*/ 0xc682cd153d0e3279U +
650
+ i * /*random*/ 0x9b3972f3bea0baa3U);
651
+ if constexpr (sizeof(T) > 8) {
652
+ misc = (misc << 64) | (/*random*/ 0x52af031a38ced62dU +
653
+ i * /*random*/ 0x936f803d9752ddc3U);
654
+ }
655
+ T misc_masked = misc & vm1;
656
+ EXPECT_LE(misc_masked, vm1);
657
+ T di_misc_masked = DownwardInvolution(misc_masked);
658
+ EXPECT_LE(di_misc_masked, vm1);
659
+ if (misc_masked > 0) {
660
+ // Highest-order 1 in same position
661
+ EXPECT_EQ(FloorLog2(misc_masked), FloorLog2(di_misc_masked));
662
+ }
663
+ // Validate involution property on short value
664
+ EXPECT_EQ(DownwardInvolution(di_misc_masked), misc_masked);
665
+
666
+ // Validate involution property on large value
667
+ T di_misc = DownwardInvolution(misc);
668
+ EXPECT_EQ(DownwardInvolution(di_misc), misc);
669
+ // Highest-order 1 in same position
670
+ if (misc > 0) {
671
+ EXPECT_EQ(FloorLog2(misc), FloorLog2(di_misc));
672
+ }
673
+
674
+ // Validate distributes over xor.
675
+ // static_casts to avoid numerical promotion effects.
676
+ EXPECT_EQ(DownwardInvolution(static_cast<T>(misc_masked ^ vm1)),
677
+ static_cast<T>(di_misc_masked ^ DownwardInvolution(vm1)));
678
+ T misc2 = static_cast<T>(misc >> 1);
679
+ EXPECT_EQ(DownwardInvolution(static_cast<T>(misc ^ misc2)),
680
+ static_cast<T>(di_misc ^ DownwardInvolution(misc2)));
681
+
682
+ // Choose some small number of bits to pull off to test combined
683
+ // uniqueness guarantee
684
+ int in_bits = i % 7;
685
+ unsigned in_mask = (unsigned{1} << in_bits) - 1U;
686
+ // IMPLICIT: int out_bits = 8 - in_bits;
687
+ std::vector<bool> seen(256, false);
688
+ for (int j = 0; j < 255; ++j) {
689
+ T t_in = misc ^ static_cast<T>(j);
690
+ unsigned in = static_cast<unsigned>(t_in);
691
+ unsigned out = static_cast<unsigned>(DownwardInvolution(t_in));
692
+ unsigned val = ((out << in_bits) | (in & in_mask)) & 255U;
693
+ EXPECT_FALSE(seen[val]);
694
+ seen[val] = true;
695
+ }
696
+
697
+ if (i + 8 < int{8 * sizeof(T)}) {
698
+ // Also test manipulating bits in the middle of input is
699
+ // bijective in bottom of output
700
+ seen = std::vector<bool>(256, false);
701
+ for (int j = 0; j < 255; ++j) {
702
+ T in = misc ^ (static_cast<T>(j) << i);
703
+ unsigned val = static_cast<unsigned>(DownwardInvolution(in)) & 255U;
704
+ EXPECT_FALSE(seen[val]);
705
+ seen[val] = true;
706
+ }
707
+ }
708
+ }
709
+
643
710
  vm1 = (vm1 << 1) | 1;
644
711
  }
645
712
 
@@ -250,4 +250,45 @@ inline T ReverseBits(T v) {
250
250
  return r;
251
251
  }
252
252
 
253
+ // Every output bit depends on many input bits in the same and higher
254
+ // positions, but not lower positions. Specifically, this function
255
+ // * Output highest bit set to 1 is same as input (same FloorLog2, or
256
+ // equivalently, same number of leading zeros)
257
+ // * Is its own inverse (an involution)
258
+ // * Guarantees that b bottom bits of v and c bottom bits of
259
+ // DownwardInvolution(v) uniquely identify b + c bottom bits of v
260
+ // (which is all of v if v < 2**(b + c)).
261
+ // ** A notable special case is that modifying c adjacent bits at
262
+ // some chosen position in the input is bijective with the bottom c
263
+ // output bits.
264
+ // * Distributes over xor, as in DI(a ^ b) == DI(a) ^ DI(b)
265
+ //
266
+ // This transformation is equivalent to a matrix*vector multiplication in
267
+ // GF(2) where the matrix is recursively defined by the pattern matrix
268
+ // P = | 1 1 |
269
+ // | 0 1 |
270
+ // and replacing 1's with P and 0's with 2x2 zero matices to some depth,
271
+ // e.g. depth of 6 for 64-bit T. An essential feature of this matrix
272
+ // is that all square sub-matrices that include the top row are invertible.
273
+ template <typename T>
274
+ inline T DownwardInvolution(T v) {
275
+ static_assert(std::is_integral<T>::value, "non-integral type");
276
+ static_assert(sizeof(T) <= 8, "only supported up to 64 bits");
277
+
278
+ uint64_t r = static_cast<uint64_t>(v);
279
+ if constexpr (sizeof(T) > 4) {
280
+ r ^= r >> 32;
281
+ }
282
+ if constexpr (sizeof(T) > 2) {
283
+ r ^= (r & 0xffff0000ffff0000U) >> 16;
284
+ }
285
+ if constexpr (sizeof(T) > 1) {
286
+ r ^= (r & 0xff00ff00ff00ff00U) >> 8;
287
+ }
288
+ r ^= (r & 0xf0f0f0f0f0f0f0f0U) >> 4;
289
+ r ^= (r & 0xccccccccccccccccU) >> 2;
290
+ r ^= (r & 0xaaaaaaaaaaaaaaaaU) >> 1;
291
+ return static_cast<T>(r);
292
+ }
293
+
253
294
  } // namespace ROCKSDB_NAMESPACE
@@ -230,6 +230,12 @@ inline Unsigned128 ReverseBits(Unsigned128 v) {
230
230
  ReverseBits(Upper64of128(v));
231
231
  }
232
232
 
233
+ template <>
234
+ inline Unsigned128 DownwardInvolution(Unsigned128 v) {
235
+ return (Unsigned128{DownwardInvolution(Upper64of128(v))} << 64) |
236
+ DownwardInvolution(Upper64of128(v) ^ Lower64of128(v));
237
+ }
238
+
233
239
  template <typename T>
234
240
  struct IsUnsignedUpTo128
235
241
  : std::integral_constant<bool, std::is_unsigned<T>::value ||
@@ -1,4 +1,5 @@
1
- // Copyright (c) Meta Platforms, Inc. and its affiliates. All Rights Reserved.
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ //
2
3
  // This source code is licensed under both the GPLv2 (found in the
3
4
  // COPYING file in the root directory) and Apache 2.0 License
4
5
  // (found in the LICENSE.Apache file in the root directory).
@@ -39,12 +39,9 @@ Status CacheDumperImpl::SetDumpFilter(std::vector<DB*> db_list) {
39
39
  // We only want to save cache entries that are portable to another
40
40
  // DB::Open, so only save entries with stable keys.
41
41
  bool is_stable;
42
- // WART: if the file is extremely large (> kMaxFileSizeStandardEncoding)
43
- // then the prefix will be different. But this should not be a concern
44
- // in practice because that limit is currently 4TB on a single file.
45
- BlockBasedTable::SetupBaseCacheKey(
46
- id->second.get(), /*cur_db_session_id*/ "", /*cur_file_num*/ 0,
47
- /*file_size*/ 42, &base, &is_stable);
42
+ BlockBasedTable::SetupBaseCacheKey(id->second.get(),
43
+ /*cur_db_session_id*/ "",
44
+ /*cur_file_num*/ 0, &base, &is_stable);
48
45
  if (is_stable) {
49
46
  Slice prefix_slice = base.CommonPrefixSlice();
50
47
  assert(prefix_slice.size() == OffsetableCacheKey::kCommonPrefixSize);
@@ -1,3 +1,8 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ //
3
+ // This source code is licensed under both the GPLv2 (found in the
4
+ // COPYING file in the root directory) and Apache 2.0 License
5
+ // (found in the LICENSE.Apache file in the root directory).
1
6
 
2
7
  #include "file/file_util.h"
3
8
  #include "port/port.h"
@@ -1,3 +1,9 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ //
3
+ // This source code is licensed under both the GPLv2 (found in the
4
+ // COPYING file in the root directory) and Apache 2.0 License
5
+ // (found in the LICENSE.Apache file in the root directory).
6
+
1
7
  //
2
8
  // Generic definitions for a Range-based Lock Manager
3
9
  //
package/index.js CHANGED
@@ -204,13 +204,22 @@ class RocksLevel extends AbstractLevel {
204
204
  return new ChainedBatch(this, this[kContext], (batch, context, options, callback) => {
205
205
  try {
206
206
  const seq = this.sequence
207
- binding.batch_write(this[kContext], context, options)
208
- this.emit('update', {
209
- rows: batch.toArray(),
210
- count: batch.length,
211
- sequence: seq + 1
207
+ let sync = true
208
+ binding.batch_write(this[kContext], context, options, (err) => {
209
+ if (!err) {
210
+ this.emit('update', {
211
+ rows: batch.toArray(),
212
+ count: batch.length,
213
+ sequence: seq + 1
214
+ })
215
+ }
216
+ if (sync) {
217
+ process.nextTick(callback, err)
218
+ } else {
219
+ callback(err)
220
+ }
212
221
  })
213
- process.nextTick(callback, null)
222
+ sync = false
214
223
  } catch (err) {
215
224
  process.nextTick(callback, err)
216
225
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/rocksdb",
3
- "version": "7.1.5",
3
+ "version": "7.1.8",
4
4
  "description": "A low-level Node.js RocksDB binding",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
Binary file
Binary file