@nxtedition/rocksdb 15.1.2 → 15.1.3

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 (153) hide show
  1. package/binding.cc +79 -38
  2. package/build.sh +1 -2
  3. package/deps/rocksdb/rocksdb/BUCK +10 -8
  4. package/deps/rocksdb/rocksdb/CMakeLists.txt +27 -2
  5. package/deps/rocksdb/rocksdb/Makefile +27 -116
  6. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +1 -1
  7. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +101 -124
  8. package/deps/rocksdb/rocksdb/cache/clock_cache.h +47 -30
  9. package/deps/rocksdb/rocksdb/db/c.cc +793 -131
  10. package/deps/rocksdb/rocksdb/db/c_test.c +571 -0
  11. package/deps/rocksdb/rocksdb/db/compact_files_test.cc +226 -0
  12. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +4 -0
  13. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +95 -59
  14. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +2 -2
  15. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +45 -35
  16. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +8 -4
  17. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +1 -1
  18. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +11 -6
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +8 -2
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +47 -0
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +12 -2
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +82 -0
  23. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +2 -2
  24. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +1 -1
  25. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +69 -24
  26. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +9 -1
  27. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +65 -0
  28. package/deps/rocksdb/rocksdb/db/db_etc3_test.cc +161 -0
  29. package/deps/rocksdb/rocksdb/db/db_filesnapshot.cc +1 -0
  30. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +20 -7
  31. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +13 -0
  32. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +114 -39
  33. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +3 -0
  34. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_follower.cc +3 -3
  35. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +1 -1
  36. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +39 -25
  37. package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +361 -0
  38. package/deps/rocksdb/rocksdb/db/db_options_test.cc +35 -0
  39. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +83 -0
  40. package/deps/rocksdb/rocksdb/db/db_test.cc +249 -4
  41. package/deps/rocksdb/rocksdb/db/db_test2.cc +3 -0
  42. package/deps/rocksdb/rocksdb/db/db_test_util.cc +2 -1
  43. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +3 -2
  44. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +7 -7
  45. package/deps/rocksdb/rocksdb/db/listener_test.cc +7 -17
  46. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +4 -2
  47. package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +41 -0
  48. package/deps/rocksdb/rocksdb/db/repair.cc +2 -2
  49. package/deps/rocksdb/rocksdb/db/version_edit.h +7 -4
  50. package/deps/rocksdb/rocksdb/db/version_set.cc +299 -90
  51. package/deps/rocksdb/rocksdb/db/version_set.h +56 -9
  52. package/deps/rocksdb/rocksdb/db/version_set_test.cc +41 -39
  53. package/deps/rocksdb/rocksdb/db/version_util.h +3 -2
  54. package/deps/rocksdb/rocksdb/db/wal_manager.cc +7 -1
  55. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +48 -10
  56. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -0
  57. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +5 -1
  58. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +16 -5
  59. package/deps/rocksdb/rocksdb/env/env_test.cc +126 -41
  60. package/deps/rocksdb/rocksdb/env/fs_posix.cc +14 -7
  61. package/deps/rocksdb/rocksdb/env/io_posix.cc +304 -112
  62. package/deps/rocksdb/rocksdb/env/io_posix.h +16 -4
  63. package/deps/rocksdb/rocksdb/env/io_posix_test.cc +43 -0
  64. package/deps/rocksdb/rocksdb/folly.mk +148 -0
  65. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_compression.h +29 -3
  66. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +73 -0
  67. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +246 -0
  68. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_filter.h +0 -2
  69. package/deps/rocksdb/rocksdb/include/rocksdb/data_structure.h +15 -9
  70. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +19 -9
  71. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +1 -1
  72. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +6 -4
  73. package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +14 -0
  74. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +67 -6
  75. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +1 -7
  76. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +3 -0
  77. package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +6 -14
  78. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/backup_engine.h +8 -1
  79. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/env_mirror.h +2 -2
  80. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd_execute_result.h +0 -4
  81. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/option_change_migration.h +33 -5
  82. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +6 -0
  83. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  84. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +2 -0
  85. package/deps/rocksdb/rocksdb/monitoring/thread_status_impl.cc +5 -2
  86. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.cc +2 -2
  87. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.h +6 -6
  88. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater_debug.cc +2 -2
  89. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.cc +10 -5
  90. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.h +2 -2
  91. package/deps/rocksdb/rocksdb/options/cf_options.cc +15 -3
  92. package/deps/rocksdb/rocksdb/options/cf_options.h +7 -0
  93. package/deps/rocksdb/rocksdb/options/db_options.cc +27 -36
  94. package/deps/rocksdb/rocksdb/options/db_options.h +3 -2
  95. package/deps/rocksdb/rocksdb/options/options.cc +4 -0
  96. package/deps/rocksdb/rocksdb/options/options_helper.cc +8 -2
  97. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +4 -1
  98. package/deps/rocksdb/rocksdb/options/options_test.cc +19 -3
  99. package/deps/rocksdb/rocksdb/src.mk +1 -1
  100. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +155 -32
  101. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +7 -3
  102. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +169 -125
  103. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +22 -7
  104. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +43 -24
  105. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +9 -5
  106. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +9 -8
  107. package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +17 -0
  108. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +15 -5
  109. package/deps/rocksdb/rocksdb/table/block_based/filter_policy_internal.h +13 -18
  110. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +29 -0
  111. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +6 -0
  112. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +15 -0
  113. package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +79 -19
  114. package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +48 -20
  115. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +51 -0
  116. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +19 -0
  117. package/deps/rocksdb/rocksdb/table/block_based/user_defined_index_wrapper.h +1 -1
  118. package/deps/rocksdb/rocksdb/table/external_table.cc +2 -2
  119. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +3 -2
  120. package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +3 -1
  121. package/deps/rocksdb/rocksdb/table/table_builder.h +5 -0
  122. package/deps/rocksdb/rocksdb/table/table_reader.h +4 -2
  123. package/deps/rocksdb/rocksdb/table/table_test.cc +48 -39
  124. package/deps/rocksdb/rocksdb/test_util/sync_point.cc +4 -0
  125. package/deps/rocksdb/rocksdb/test_util/sync_point.h +32 -0
  126. package/deps/rocksdb/rocksdb/test_util/testutil.h +6 -2
  127. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +14 -4
  128. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +8 -5
  129. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +3 -2
  130. package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +63 -12
  131. package/deps/rocksdb/rocksdb/util/auto_tune_compressor.cc +16 -1
  132. package/deps/rocksdb/rocksdb/util/auto_tune_compressor.h +5 -1
  133. package/deps/rocksdb/rocksdb/util/bit_fields.h +133 -23
  134. package/deps/rocksdb/rocksdb/util/bloom_test.cc +2 -5
  135. package/deps/rocksdb/rocksdb/util/compression.cc +51 -23
  136. package/deps/rocksdb/rocksdb/util/compression_test.cc +525 -270
  137. package/deps/rocksdb/rocksdb/util/filter_bench.cc +3 -4
  138. package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.cc +11 -2
  139. package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.h +4 -1
  140. package/deps/rocksdb/rocksdb/util/slice_test.cc +92 -0
  141. package/deps/rocksdb/rocksdb/util/thread_list_test.cc +2 -2
  142. package/deps/rocksdb/rocksdb/util/thread_operation.h +2 -2
  143. package/deps/rocksdb/rocksdb/util/threadpool_imp.cc +2 -2
  144. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +19 -2
  145. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +75 -0
  146. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +1 -0
  147. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration.cc +303 -111
  148. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration_test.cc +379 -0
  149. package/deps/rocksdb/rocksdb.gyp +6 -4
  150. package/iterator.js +66 -70
  151. package/package.json +6 -6
  152. package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
  153. package/deps/rocksdb/rocksdb/table/block_based/index_builder_test.cc +0 -183
@@ -556,6 +556,385 @@ TEST_F(DBOptionChangeMigrationTest, CompactedSrcToUniversal) {
556
556
  }
557
557
  }
558
558
 
559
+ class DBOptionChangeMigrationMultiCFTest : public DBTestBase {
560
+ public:
561
+ DBOptionChangeMigrationMultiCFTest()
562
+ : DBTestBase("db_option_change_migration_multi_cf_test",
563
+ /*env_do_fsync=*/true) {}
564
+ };
565
+
566
+ TEST_F(DBOptionChangeMigrationMultiCFTest, BasicMultiCF) {
567
+ Options options = CurrentOptions();
568
+ options.compaction_style = CompactionStyle::kCompactionStyleLevel;
569
+ options.level_compaction_dynamic_level_bytes = false;
570
+ options.num_levels = 4;
571
+ options.write_buffer_size = 64 * 1024;
572
+ options.target_file_size_base = 128 * 1024;
573
+
574
+ // Create DB with default CF
575
+ Reopen(options);
576
+
577
+ // Create additional CF
578
+ ColumnFamilyHandle* cf_handle;
579
+ ASSERT_OK(db_->CreateColumnFamily(options, "cf1", &cf_handle));
580
+
581
+ // Write data to both CFs
582
+ Random rnd(301);
583
+ for (int i = 0; i < 100; i++) {
584
+ ASSERT_OK(Put("key" + std::to_string(i), rnd.RandomString(900)));
585
+ ASSERT_OK(db_->Put(WriteOptions(), cf_handle, "key" + std::to_string(i),
586
+ rnd.RandomString(900)));
587
+ }
588
+ ASSERT_OK(Flush());
589
+ ASSERT_OK(db_->Flush(FlushOptions(), cf_handle));
590
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
591
+
592
+ // Collect keys from both CFs
593
+ std::set<std::string> keys_default;
594
+ std::set<std::string> keys_cf1;
595
+ {
596
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions()));
597
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
598
+ keys_default.insert(it->key().ToString());
599
+ }
600
+ ASSERT_OK(it->status());
601
+ }
602
+ {
603
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions(), cf_handle));
604
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
605
+ keys_cf1.insert(it->key().ToString());
606
+ }
607
+ ASSERT_OK(it->status());
608
+ }
609
+
610
+ delete cf_handle;
611
+ Close();
612
+
613
+ // Prepare old and new options
614
+ DBOptions old_db_opts(options);
615
+ ColumnFamilyOptions old_cf_opts(options);
616
+
617
+ std::vector<ColumnFamilyDescriptor> old_cf_descs = {
618
+ {kDefaultColumnFamilyName, old_cf_opts}, {"cf1", old_cf_opts}};
619
+
620
+ // New options: migrate to Universal compaction
621
+ Options new_options = options;
622
+ new_options.compaction_style = CompactionStyle::kCompactionStyleUniversal;
623
+ new_options.num_levels = 5;
624
+ new_options.target_file_size_base = 256 * 1024;
625
+
626
+ DBOptions new_db_opts(new_options);
627
+ ColumnFamilyOptions new_cf_opts(new_options);
628
+
629
+ std::vector<ColumnFamilyDescriptor> new_cf_descs = {
630
+ {kDefaultColumnFamilyName, new_cf_opts}, {"cf1", new_cf_opts}};
631
+
632
+ // Perform multi-CF migration
633
+ ASSERT_OK(OptionChangeMigration(dbname_, old_db_opts, old_cf_descs,
634
+ new_db_opts, new_cf_descs));
635
+
636
+ // Reopen with new options
637
+ std::vector<ColumnFamilyHandle*> handles;
638
+ ASSERT_OK(DB::Open(new_db_opts, dbname_, new_cf_descs, &handles, &db_));
639
+ ASSERT_EQ(handles.size(), 2);
640
+
641
+ // Verify data in default CF
642
+ {
643
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions()));
644
+ it->SeekToFirst();
645
+ for (const std::string& key : keys_default) {
646
+ ASSERT_TRUE(it->Valid());
647
+ ASSERT_EQ(key, it->key().ToString());
648
+ it->Next();
649
+ }
650
+ ASSERT_TRUE(!it->Valid());
651
+ ASSERT_OK(it->status());
652
+ }
653
+
654
+ // Verify data in cf1
655
+ {
656
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions(), handles[1]));
657
+ it->SeekToFirst();
658
+ for (const std::string& key : keys_cf1) {
659
+ ASSERT_TRUE(it->Valid());
660
+ ASSERT_EQ(key, it->key().ToString());
661
+ it->Next();
662
+ }
663
+ ASSERT_TRUE(!it->Valid());
664
+ ASSERT_OK(it->status());
665
+ }
666
+
667
+ // Cleanup
668
+ for (auto* handle : handles) {
669
+ if (handle != db_->DefaultColumnFamily()) {
670
+ ASSERT_OK(db_->DestroyColumnFamilyHandle(handle));
671
+ }
672
+ }
673
+ }
674
+
675
+ TEST_F(DBOptionChangeMigrationMultiCFTest, DifferentStylesPerCF) {
676
+ // Create DB with 2 CFs, both using Level compaction
677
+ Options options1 = CurrentOptions();
678
+ options1.compaction_style = CompactionStyle::kCompactionStyleLevel;
679
+ options1.num_levels = 4;
680
+ options1.write_buffer_size = 64 * 1024;
681
+
682
+ Reopen(options1);
683
+
684
+ ColumnFamilyHandle* cf_handle;
685
+ ASSERT_OK(db_->CreateColumnFamily(options1, "cf1", &cf_handle));
686
+
687
+ // Write data
688
+ Random rnd(301);
689
+ for (int i = 0; i < 50; i++) {
690
+ ASSERT_OK(Put("key" + std::to_string(i), rnd.RandomString(900)));
691
+ ASSERT_OK(db_->Put(WriteOptions(), cf_handle, "key" + std::to_string(i),
692
+ rnd.RandomString(900)));
693
+ }
694
+ ASSERT_OK(Flush());
695
+ ASSERT_OK(db_->Flush(FlushOptions(), cf_handle));
696
+
697
+ // Collect keys from both CFs
698
+ std::set<std::string> keys_default;
699
+ std::set<std::string> keys_cf1;
700
+ {
701
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions()));
702
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
703
+ keys_default.insert(it->key().ToString());
704
+ }
705
+ ASSERT_OK(it->status());
706
+ }
707
+ {
708
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions(), cf_handle));
709
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
710
+ keys_cf1.insert(it->key().ToString());
711
+ }
712
+ ASSERT_OK(it->status());
713
+ }
714
+
715
+ delete cf_handle;
716
+ Close();
717
+
718
+ // Old descriptors
719
+ DBOptions old_db_opts(options1);
720
+ ColumnFamilyOptions old_cf_opts(options1);
721
+
722
+ std::vector<ColumnFamilyDescriptor> old_cf_descs = {
723
+ {kDefaultColumnFamilyName, old_cf_opts}, {"cf1", old_cf_opts}};
724
+
725
+ // New descriptors: default CF to Universal, cf1 to Level with dynamic
726
+ Options new_opts_default = options1;
727
+ new_opts_default.compaction_style =
728
+ CompactionStyle::kCompactionStyleUniversal;
729
+ new_opts_default.num_levels = 5;
730
+
731
+ Options new_opts_cf1 = options1;
732
+ new_opts_cf1.compaction_style = CompactionStyle::kCompactionStyleLevel;
733
+ new_opts_cf1.level_compaction_dynamic_level_bytes = true;
734
+ new_opts_cf1.num_levels = 5;
735
+
736
+ DBOptions new_db_opts(new_opts_default);
737
+
738
+ std::vector<ColumnFamilyDescriptor> new_cf_descs = {
739
+ {kDefaultColumnFamilyName, ColumnFamilyOptions(new_opts_default)},
740
+ {"cf1", ColumnFamilyOptions(new_opts_cf1)}};
741
+
742
+ // Perform migration
743
+ ASSERT_OK(OptionChangeMigration(dbname_, old_db_opts, old_cf_descs,
744
+ new_db_opts, new_cf_descs));
745
+
746
+ // Reopen and verify
747
+ std::vector<ColumnFamilyHandle*> handles;
748
+ ASSERT_OK(DB::Open(new_db_opts, dbname_, new_cf_descs, &handles, &db_));
749
+ ASSERT_EQ(handles.size(), 2);
750
+
751
+ // Verify data in default CF
752
+ {
753
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions()));
754
+ it->SeekToFirst();
755
+ for (const std::string& key : keys_default) {
756
+ ASSERT_TRUE(it->Valid());
757
+ ASSERT_EQ(key, it->key().ToString());
758
+ it->Next();
759
+ }
760
+ ASSERT_TRUE(!it->Valid());
761
+ ASSERT_OK(it->status());
762
+ }
763
+
764
+ // Verify data in cf1
765
+ {
766
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions(), handles[1]));
767
+ it->SeekToFirst();
768
+ for (const std::string& key : keys_cf1) {
769
+ ASSERT_TRUE(it->Valid());
770
+ ASSERT_EQ(key, it->key().ToString());
771
+ it->Next();
772
+ }
773
+ ASSERT_TRUE(!it->Valid());
774
+ ASSERT_OK(it->status());
775
+ }
776
+
777
+ // Cleanup
778
+ for (auto* handle : handles) {
779
+ if (handle != db_->DefaultColumnFamily()) {
780
+ ASSERT_OK(db_->DestroyColumnFamilyHandle(handle));
781
+ }
782
+ }
783
+ }
784
+
785
+ TEST_F(DBOptionChangeMigrationMultiCFTest, ValidationMismatched) {
786
+ Options options = CurrentOptions();
787
+ DBOptions db_opts(options);
788
+ ColumnFamilyOptions cf_opts(options);
789
+
790
+ // Test 1: Mismatched CF count (missing cf1)
791
+ {
792
+ std::vector<ColumnFamilyDescriptor> old_cf_descs = {
793
+ {kDefaultColumnFamilyName, cf_opts}, {"cf1", cf_opts}};
794
+
795
+ std::vector<ColumnFamilyDescriptor> new_cf_descs = {
796
+ {kDefaultColumnFamilyName, cf_opts}}; // Missing cf1
797
+
798
+ Status s = OptionChangeMigration(dbname_, db_opts, old_cf_descs, db_opts,
799
+ new_cf_descs);
800
+ ASSERT_TRUE(s.IsInvalidArgument());
801
+ ASSERT_TRUE(s.ToString().find("same number") != std::string::npos);
802
+ }
803
+
804
+ // Test 2: Mismatched CF names (cf2 instead of cf1)
805
+ {
806
+ std::vector<ColumnFamilyDescriptor> old_cf_descs = {
807
+ {kDefaultColumnFamilyName, cf_opts}, {"cf1", cf_opts}};
808
+
809
+ std::vector<ColumnFamilyDescriptor> new_cf_descs = {
810
+ {kDefaultColumnFamilyName, cf_opts},
811
+ {"cf2", cf_opts}}; // Different name
812
+
813
+ Status s = OptionChangeMigration(dbname_, db_opts, old_cf_descs, db_opts,
814
+ new_cf_descs);
815
+ ASSERT_TRUE(s.IsInvalidArgument());
816
+ ASSERT_TRUE(s.ToString().find("mismatch") != std::string::npos);
817
+ }
818
+
819
+ // Test 3: Mismatched CF order (swapped)
820
+ {
821
+ std::vector<ColumnFamilyDescriptor> old_cf_descs = {
822
+ {kDefaultColumnFamilyName, cf_opts}, {"cf1", cf_opts}};
823
+
824
+ std::vector<ColumnFamilyDescriptor> new_cf_descs = {
825
+ {"cf1", cf_opts}, // Swapped order
826
+ {kDefaultColumnFamilyName, cf_opts}};
827
+
828
+ Status s = OptionChangeMigration(dbname_, db_opts, old_cf_descs, db_opts,
829
+ new_cf_descs);
830
+ ASSERT_TRUE(s.IsInvalidArgument());
831
+ ASSERT_TRUE(s.ToString().find("mismatch") != std::string::npos);
832
+ }
833
+ }
834
+
835
+ TEST_F(DBOptionChangeMigrationMultiCFTest, FromFIFOMultiCF) {
836
+ Options options = CurrentOptions();
837
+ options.compaction_style = CompactionStyle::kCompactionStyleFIFO;
838
+ options.num_levels = 1;
839
+ options.max_open_files = -1;
840
+
841
+ Reopen(options);
842
+
843
+ ColumnFamilyHandle* cf_handle;
844
+ ASSERT_OK(db_->CreateColumnFamily(options, "cf1", &cf_handle));
845
+
846
+ // Write some data
847
+ Random rnd(301);
848
+ for (int i = 0; i < 50; i++) {
849
+ ASSERT_OK(Put("key" + std::to_string(i), rnd.RandomString(900)));
850
+ ASSERT_OK(db_->Put(WriteOptions(), cf_handle, "key" + std::to_string(i),
851
+ rnd.RandomString(900)));
852
+ }
853
+ ASSERT_OK(Flush());
854
+ ASSERT_OK(db_->Flush(FlushOptions(), cf_handle));
855
+
856
+ // Collect keys from both CFs
857
+ std::set<std::string> keys_default;
858
+ std::set<std::string> keys_cf1;
859
+ {
860
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions()));
861
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
862
+ keys_default.insert(it->key().ToString());
863
+ }
864
+ ASSERT_OK(it->status());
865
+ }
866
+ {
867
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions(), cf_handle));
868
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
869
+ keys_cf1.insert(it->key().ToString());
870
+ }
871
+ ASSERT_OK(it->status());
872
+ }
873
+
874
+ delete cf_handle;
875
+ Close();
876
+
877
+ // Migrate from FIFO to Level
878
+ DBOptions old_db_opts(options);
879
+ ColumnFamilyOptions old_cf_opts(options);
880
+
881
+ std::vector<ColumnFamilyDescriptor> old_cf_descs = {
882
+ {kDefaultColumnFamilyName, old_cf_opts}, {"cf1", old_cf_opts}};
883
+
884
+ Options new_options = options;
885
+ new_options.compaction_style = CompactionStyle::kCompactionStyleLevel;
886
+ new_options.num_levels = 4;
887
+ new_options.max_open_files = 1000;
888
+
889
+ DBOptions new_db_opts(new_options);
890
+ ColumnFamilyOptions new_cf_opts(new_options);
891
+
892
+ std::vector<ColumnFamilyDescriptor> new_cf_descs = {
893
+ {kDefaultColumnFamilyName, new_cf_opts}, {"cf1", new_cf_opts}};
894
+
895
+ // Migration should succeed (FIFO is special case)
896
+ ASSERT_OK(OptionChangeMigration(dbname_, old_db_opts, old_cf_descs,
897
+ new_db_opts, new_cf_descs));
898
+
899
+ // Reopen and verify
900
+ std::vector<ColumnFamilyHandle*> handles;
901
+ ASSERT_OK(DB::Open(new_db_opts, dbname_, new_cf_descs, &handles, &db_));
902
+ ASSERT_EQ(handles.size(), 2);
903
+
904
+ // Verify data in default CF
905
+ {
906
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions()));
907
+ it->SeekToFirst();
908
+ for (const std::string& key : keys_default) {
909
+ ASSERT_TRUE(it->Valid());
910
+ ASSERT_EQ(key, it->key().ToString());
911
+ it->Next();
912
+ }
913
+ ASSERT_TRUE(!it->Valid());
914
+ ASSERT_OK(it->status());
915
+ }
916
+
917
+ // Verify data in cf1
918
+ {
919
+ std::unique_ptr<Iterator> it(db_->NewIterator(ReadOptions(), handles[1]));
920
+ it->SeekToFirst();
921
+ for (const std::string& key : keys_cf1) {
922
+ ASSERT_TRUE(it->Valid());
923
+ ASSERT_EQ(key, it->key().ToString());
924
+ it->Next();
925
+ }
926
+ ASSERT_TRUE(!it->Valid());
927
+ ASSERT_OK(it->status());
928
+ }
929
+
930
+ // Cleanup
931
+ for (auto* handle : handles) {
932
+ if (handle != db_->DefaultColumnFamily()) {
933
+ ASSERT_OK(db_->DestroyColumnFamilyHandle(handle));
934
+ }
935
+ }
936
+ }
937
+
559
938
  } // namespace ROCKSDB_NAMESPACE
560
939
 
561
940
  int main(int argc, char** argv) {
@@ -9,6 +9,7 @@
9
9
  "include_dirs": ["rocksdb/include/"]
10
10
  },
11
11
  "defines": [
12
+ "NDEBUG=1",
12
13
  "ZSTD=1",
13
14
  "ZSTD_STATIC_LINKING_ONLY=1",
14
15
  "ROCKSDB_BACKTRACE=1",
@@ -257,6 +258,7 @@
257
258
  "rocksdb/db/write_controller.cc",
258
259
  "rocksdb/db/write_stall_stats.cc",
259
260
  "rocksdb/db/write_thread.cc",
261
+ # "rocksdb/db_stress_tool/db_stress_compression_manager.cc",
260
262
  "rocksdb/env/composite_env.cc",
261
263
  "rocksdb/env/env.cc",
262
264
  "rocksdb/env/env_chroot.cc",
@@ -367,10 +369,10 @@
367
369
  "rocksdb/table/table_properties.cc",
368
370
  "rocksdb/table/two_level_iterator.cc",
369
371
  "rocksdb/table/unique_id.cc",
370
- "rocksdb/test_util/sync_point.cc",
371
- "rocksdb/test_util/sync_point_impl.cc",
372
- "rocksdb/test_util/testutil.cc",
373
- "rocksdb/test_util/transaction_test_util.cc",
372
+ # "rocksdb/test_util/sync_point.cc",
373
+ # "rocksdb/test_util/sync_point_impl.cc",
374
+ # "rocksdb/test_util/testutil.cc",
375
+ # "rocksdb/test_util/transaction_test_util.cc",
374
376
  # "rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer.cc",
375
377
  # "rocksdb/tools/dump/db_dump_tool.cc",
376
378
  # "rocksdb/tools/io_tracer_parser_tool.cc",
package/iterator.js CHANGED
@@ -17,13 +17,12 @@ const kPosition = Symbol('position')
17
17
  const kBusy = Symbol('busy')
18
18
 
19
19
  const kEmpty = []
20
- const kForceSync = false
21
20
 
22
21
  class Iterator extends AbstractIterator {
23
22
  constructor (db, context, options) {
24
23
  super(db, options)
25
24
 
26
- this[kContext] = binding.iterator_init(context, options)
25
+ this[kContext] = binding.iterator_init_sync(context, options)
27
26
 
28
27
  this[kFirst] = true
29
28
  this[kCache] = kEmpty
@@ -50,40 +49,9 @@ class Iterator extends AbstractIterator {
50
49
  return (this[kCache].length - this[kPosition]) / 2
51
50
  }
52
51
 
53
- // nxt API
54
-
55
- _seekSync (target) {
56
- assert(this[kContext])
57
-
58
- if (target.length === 0) {
59
- throw new Error('cannot seek() to an empty target')
60
- }
61
-
62
- this[kFirst] = true
63
- this[kCache] = kEmpty
64
- this[kFinished] = false
65
- this[kPosition] = 0
66
-
67
- binding.iterator_seek(this[kContext], target)
68
- }
69
-
70
- _seekAsync (target, callback) {
71
- assert(this[kContext])
72
-
73
- callback = fromCallback(callback, kPromise)
74
-
75
- try {
76
- this._seekSync(target)
77
- process.nextTick(callback)
78
- } catch (err) {
79
- process.nextTick(callback, err)
80
- }
81
-
82
- return callback[kPromise]
83
- }
84
-
85
52
  _next (callback) {
86
53
  assert(this[kContext])
54
+ assert(!this[kBusy])
87
55
 
88
56
  if (this[kPosition] < this[kCache].length) {
89
57
  const key = this[kCache][this[kPosition]++]
@@ -112,43 +80,72 @@ class Iterator extends AbstractIterator {
112
80
 
113
81
  _nextv (size, options, callback) {
114
82
  assert(this[kContext])
83
+ assert(!this[kBusy])
115
84
 
116
85
  callback = fromCallback(callback, kPromise)
117
86
 
118
- if (this[kFinished]) {
119
- process.nextTick(callback, null, [])
120
- } else {
121
- this[kFirst] = false
87
+ this._nextvAsync(size, options, (err, val) => {
88
+ if (err) {
89
+ callback(err)
90
+ } else {
91
+ const { rows, finished } = val
122
92
 
123
- try {
124
- if (kForceSync) {
125
- const { rows, finished } = this._nextvSync(size, options)
93
+ const entries = []
94
+ for (let n = 0; n < rows.length; n += 2) {
95
+ entries.push([rows[n + 0], rows[n + 1]])
96
+ }
126
97
 
127
- const entries = []
128
- for (let n = 0; n < rows.length; n += 2) {
129
- entries.push([rows[n + 0], rows[n + 1]])
130
- }
98
+ callback(null, entries, finished)
99
+ }
100
+ })
101
+
102
+ return callback[kPromise]
103
+ }
104
+
105
+ // nxt API
106
+
107
+ _seekSync (target) {
108
+ assert(this[kContext])
109
+ assert(!this[kBusy])
110
+
111
+ if (target.length === 0) {
112
+ throw new Error('cannot seek() to an empty target')
113
+ }
114
+
115
+ this[kFirst] = true
116
+ this[kCache] = kEmpty
117
+ this[kFinished] = false
118
+ this[kPosition] = 0
119
+
120
+ binding.iterator_seek_sync(this[kContext], target)
121
+ }
122
+
123
+ _seekAsync (target, callback) {
124
+ assert(this[kContext])
125
+ assert(!this[kBusy])
131
126
 
132
- process.nextTick(callback, null, entries, finished)
127
+ callback = fromCallback(callback, kPromise)
128
+
129
+ this[kFirst] = true
130
+ this[kCache] = kEmpty
131
+ this[kFinished] = false
132
+ this[kPosition] = 0
133
+
134
+ try {
135
+ binding.iterator_seek(this[kContext], target, (err) => {
136
+ this[kBusy] = false
137
+ this[kDB][kUnref]()
138
+
139
+ if (err) {
140
+ callback(err)
133
141
  } else {
134
- this._nextvAsync(size, options, (err, val) => {
135
- if (err) {
136
- process.nextTick(callback, err)
137
- } else {
138
- const { rows, finished } = val
139
-
140
- const entries = []
141
- for (let n = 0; n < rows.length; n += 2) {
142
- entries.push([rows[n + 0], rows[n + 1]])
143
- }
144
-
145
- callback(null, entries, finished)
146
- }
147
- })
142
+ callback(null)
148
143
  }
149
- } catch (err) {
150
- process.nextTick(callback, err)
151
- }
144
+ })
145
+ this[kDB][kRef]()
146
+ this[kBusy] = true
147
+ } catch (err) {
148
+ process.nextTick(callback, err)
152
149
  }
153
150
 
154
151
  return callback[kPromise]
@@ -156,12 +153,12 @@ class Iterator extends AbstractIterator {
156
153
 
157
154
  _nextvSync (size, options) {
158
155
  assert(this[kContext])
156
+ assert(!this[kBusy])
159
157
 
160
158
  if (this[kFinished]) {
161
159
  return { rows: [], finished: true }
162
160
  }
163
161
 
164
- this[kFirst] = false
165
162
  const result = binding.iterator_nextv_sync(this[kContext], size, options)
166
163
  this[kFinished] = result.finished
167
164
 
@@ -170,6 +167,7 @@ class Iterator extends AbstractIterator {
170
167
 
171
168
  _nextvAsync (size, options, callback) {
172
169
  assert(this[kContext])
170
+ assert(!this[kBusy])
173
171
 
174
172
  callback = fromCallback(callback, kPromise)
175
173
 
@@ -177,14 +175,10 @@ class Iterator extends AbstractIterator {
177
175
  if (this[kFinished]) {
178
176
  process.nextTick(callback, null, { rows: [], finished: true })
179
177
  } else {
180
- assert(!this[kBusy])
181
-
182
- this[kFirst] = false
183
- this[kBusy] = true
184
- this[kDB][kRef]()
185
178
  binding.iterator_nextv(this[kContext], size, options, (err, result) => {
186
179
  this[kBusy] = false
187
180
  this[kDB][kUnref]()
181
+
188
182
  if (err) {
189
183
  callback(err)
190
184
  } else {
@@ -192,6 +186,8 @@ class Iterator extends AbstractIterator {
192
186
  callback(null, result)
193
187
  }
194
188
  })
189
+ this[kBusy] = true
190
+ this[kDB][kRef]()
195
191
  }
196
192
  } catch (err) {
197
193
  process.nextTick(callback, err)
@@ -204,7 +200,7 @@ class Iterator extends AbstractIterator {
204
200
  this[kCache] = kEmpty
205
201
 
206
202
  if (this[kContext]) {
207
- binding.iterator_close(this[kContext])
203
+ binding.iterator_close_sync(this[kContext])
208
204
  this[kContext] = null
209
205
  }
210
206
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/rocksdb",
3
- "version": "15.1.2",
3
+ "version": "15.1.3",
4
4
  "description": "A low-level Node.js RocksDB binding",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -20,7 +20,7 @@
20
20
  "prebuildify": "^6.0.1"
21
21
  },
22
22
  "devDependencies": {
23
- "@types/node": "^24.10.2",
23
+ "@types/node": "^25.2.1",
24
24
  "@voxpelli/tsconfig": "^16.1.0",
25
25
  "async-each": "^1.0.3",
26
26
  "cross-env": "^10.1.0",
@@ -28,17 +28,17 @@
28
28
  "dependency-check": "^4.1.0",
29
29
  "du": "^1.0.0",
30
30
  "faucet": "^0.0.4",
31
- "glob": "^13.0.0",
32
- "lru-cache": "^11.2.4",
31
+ "glob": "^13.0.1",
32
+ "lru-cache": "^11.2.5",
33
33
  "mitata": "^1.0.10",
34
34
  "mkfiletree": "^3.0.0",
35
- "node-gyp": "^12.1.0",
35
+ "node-gyp": "^12.2.0",
36
36
  "nyc": "^17.1.0",
37
37
  "readfiletree": "^2.0.0",
38
38
  "rimraf": "^6.1.2",
39
39
  "standard": "^17.1.2",
40
40
  "tape": "^5.9.0",
41
- "tempy": "^3.1.0"
41
+ "tempy": "^1.0.1"
42
42
  },
43
43
  "standard": {
44
44
  "ignore": [