@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
@@ -722,6 +722,88 @@ static void LoadAndCheckLatestOptions(const char* db_name, rocksdb_env_t* env,
722
722
  num_column_families);
723
723
  }
724
724
 
725
+ // Global state for tracking remote compaction calls
726
+ typedef struct {
727
+ int schedule_called;
728
+ int wait_called;
729
+ int cancel_called;
730
+ char last_scheduled_job_id[256];
731
+ char last_db_name[256];
732
+ } RemoteCompactionState;
733
+
734
+ // Schedule callback - gets called when compaction is scheduled
735
+ static rocksdb_compactionservice_scheduleresponse_t* RemoteCompactionSchedule(
736
+ void* state, const rocksdb_compactionservice_jobinfo_t* info,
737
+ const char* input, size_t input_len) {
738
+ (void)input;
739
+ (void)input_len;
740
+ RemoteCompactionState* rcs = (RemoteCompactionState*)state;
741
+ rcs->schedule_called++;
742
+
743
+ // Extract job info
744
+ size_t db_name_len;
745
+ const char* db_name =
746
+ rocksdb_compactionservice_jobinfo_t_get_db_name(info, &db_name_len);
747
+ memcpy(rcs->last_db_name, db_name, db_name_len);
748
+ rcs->last_db_name[db_name_len] = '\0';
749
+
750
+ // Generate a job ID
751
+ snprintf(rcs->last_scheduled_job_id, sizeof(rcs->last_scheduled_job_id),
752
+ "job-%d", rcs->schedule_called);
753
+
754
+ // Create response with success status
755
+ char* err = NULL;
756
+ rocksdb_compactionservice_scheduleresponse_t* response =
757
+ rocksdb_compactionservice_scheduleresponse_create(
758
+ rcs->last_scheduled_job_id,
759
+ rocksdb_compactionservice_jobstatus_success, &err);
760
+ if (err) {
761
+ free(err);
762
+ }
763
+ return response;
764
+ }
765
+
766
+ // Wait callback - simulates waiting for remote compaction to complete
767
+ static int RemoteCompactionWait(void* state, const char* scheduled_job_id,
768
+ char** result, size_t* result_len) {
769
+ RemoteCompactionState* rcs = (RemoteCompactionState*)state;
770
+ rcs->wait_called++;
771
+
772
+ if (strcmp(scheduled_job_id, rcs->last_scheduled_job_id) != 0) {
773
+ return rocksdb_compactionservice_jobstatus_failure;
774
+ }
775
+
776
+ // For testing purposes, return kUseLocal to cause RocksDB to fall back to
777
+ // local compaction. This tests the callback mechanism without needing a fully
778
+ // serialized result. In a real scenario, this would communicate with a remote
779
+ // worker that calls rocksdb_open_and_compact() and returns a properly
780
+ // serialized CompactionServiceResult
781
+ *result = NULL;
782
+ *result_len = 0;
783
+
784
+ return rocksdb_compactionservice_jobstatus_use_local;
785
+ }
786
+
787
+ // Cancel callback - cancels pending jobs
788
+ static void RemoteCompactionCancel(void* state) {
789
+ RemoteCompactionState* rcs = (RemoteCompactionState*)state;
790
+ rcs->cancel_called++;
791
+ }
792
+
793
+ // Destructor callback
794
+ static void RemoteCompactionDestroy(void* state) { (void)state; }
795
+
796
+ // NULL schedule callback for testing failure handling
797
+ static rocksdb_compactionservice_scheduleresponse_t* NullSchedule(
798
+ void* state, const rocksdb_compactionservice_jobinfo_t* info,
799
+ const char* input, size_t input_len) {
800
+ (void)state;
801
+ (void)info;
802
+ (void)input;
803
+ (void)input_len;
804
+ return NULL; // Return NULL to simulate failure
805
+ }
806
+
725
807
  int main(int argc, char** argv) {
726
808
  (void)argc;
727
809
  (void)argv;
@@ -1255,6 +1337,70 @@ int main(int argc, char** argv) {
1255
1337
  rocksdb_writebatch_destroy(wb);
1256
1338
  }
1257
1339
 
1340
+ StartPhase("writebatch_vectors_cf");
1341
+ {
1342
+ const char* cf_name = "wb_vectors_cf";
1343
+ rocksdb_column_family_handle_t* wb_cf =
1344
+ rocksdb_create_column_family(db, options, cf_name, &err);
1345
+ CheckNoError(err);
1346
+
1347
+ rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
1348
+
1349
+ // Test putv_cf: concatenates multiple slices into a single key/value
1350
+ const char* put_keys[2] = {"k", "ey"};
1351
+ const size_t put_key_sizes[2] = {1, 2};
1352
+ const char* put_vals[3] = {"v", "a", "l"};
1353
+ const size_t put_val_sizes[3] = {1, 1, 1};
1354
+ rocksdb_writebatch_putv_cf(wb, wb_cf, 2, put_keys, put_key_sizes, 3,
1355
+ put_vals, put_val_sizes);
1356
+ rocksdb_write(db, woptions, wb, &err);
1357
+ CheckNoError(err);
1358
+ // putv_cf concatenates: key="k"+"ey"="key", value="v"+"a"+"l"="val"
1359
+ CheckGetCF(db, roptions, wb_cf, "key", "val");
1360
+ CheckGetCF(db, roptions, wb_cf, "k", NULL);
1361
+ CheckGetCF(db, roptions, wb_cf, "ey", NULL);
1362
+
1363
+ // Test deletev_cf: concatenates multiple slices for key
1364
+ rocksdb_writebatch_clear(wb);
1365
+ const char* del_keys[2] = {"k", "ey"};
1366
+ const size_t del_key_sizes[2] = {1, 2};
1367
+ rocksdb_writebatch_deletev_cf(wb, wb_cf, 2, del_keys, del_key_sizes);
1368
+ rocksdb_write(db, woptions, wb, &err);
1369
+ CheckNoError(err);
1370
+ CheckGetCF(db, roptions, wb_cf, "key", NULL);
1371
+
1372
+ // Test delete_rangev_cf: concatenates slices for range deletion
1373
+ rocksdb_writebatch_clear(wb);
1374
+ rocksdb_writebatch_put_cf(wb, wb_cf, "a", 1, "1", 1);
1375
+ rocksdb_writebatch_put_cf(wb, wb_cf, "b", 1, "2", 1);
1376
+ rocksdb_writebatch_put_cf(wb, wb_cf, "c", 1, "3", 1);
1377
+ rocksdb_write(db, woptions, wb, &err);
1378
+ CheckNoError(err);
1379
+ CheckGetCF(db, roptions, wb_cf, "a", "1");
1380
+ CheckGetCF(db, roptions, wb_cf, "b", "2");
1381
+ CheckGetCF(db, roptions, wb_cf, "c", "3");
1382
+
1383
+ rocksdb_writebatch_clear(wb);
1384
+ const char* range_start[2] = {"a", ""}; // "a" + "" = "a"
1385
+ const size_t range_start_sizes[2] = {1, 0};
1386
+ const char* range_end[2] = {"c", ""};
1387
+ const size_t range_end_sizes[2] = {1, 0};
1388
+ rocksdb_writebatch_delete_rangev_cf(wb, wb_cf, 2, range_start,
1389
+ range_start_sizes, range_end,
1390
+ range_end_sizes);
1391
+ rocksdb_write(db, woptions, wb, &err);
1392
+ CheckNoError(err);
1393
+ // Range [a, c) should delete "a" and "b", but not "c"
1394
+ CheckGetCF(db, roptions, wb_cf, "a", NULL);
1395
+ CheckGetCF(db, roptions, wb_cf, "b", NULL);
1396
+ CheckGetCF(db, roptions, wb_cf, "c", "3");
1397
+
1398
+ rocksdb_writebatch_destroy(wb);
1399
+ rocksdb_drop_column_family(db, wb_cf, &err);
1400
+ CheckNoError(err);
1401
+ rocksdb_column_family_handle_destroy(wb_cf);
1402
+ }
1403
+
1258
1404
  StartPhase("writebatch_vectors");
1259
1405
  {
1260
1406
  rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
@@ -1420,6 +1566,43 @@ int main(int argc, char** argv) {
1420
1566
  rocksdb_iter_destroy(iter);
1421
1567
  }
1422
1568
 
1569
+ StartPhase("iter_slice");
1570
+ {
1571
+ // Test the new slice-based iterator API for better performance
1572
+ rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
1573
+ CheckCondition(!rocksdb_iter_valid(iter));
1574
+ rocksdb_iter_seek_to_first(iter);
1575
+ CheckCondition(rocksdb_iter_valid(iter));
1576
+
1577
+ // Test rocksdb_iter_key_slice
1578
+ rocksdb_slice_t key_slice = rocksdb_iter_key_slice(iter);
1579
+ CheckEqual("box", key_slice.data, key_slice.size);
1580
+
1581
+ // Test rocksdb_iter_value_slice
1582
+ rocksdb_slice_t value_slice = rocksdb_iter_value_slice(iter);
1583
+ CheckEqual("c", value_slice.data, value_slice.size);
1584
+
1585
+ // Move to next entry and test again
1586
+ rocksdb_iter_next(iter);
1587
+ CheckCondition(rocksdb_iter_valid(iter));
1588
+ key_slice = rocksdb_iter_key_slice(iter);
1589
+ value_slice = rocksdb_iter_value_slice(iter);
1590
+ CheckEqual("foo", key_slice.data, key_slice.size);
1591
+ CheckEqual("hello", value_slice.data, value_slice.size);
1592
+
1593
+ // Test seeking with slice API
1594
+ rocksdb_iter_seek(iter, "b", 1);
1595
+ CheckCondition(rocksdb_iter_valid(iter));
1596
+ key_slice = rocksdb_iter_key_slice(iter);
1597
+ value_slice = rocksdb_iter_value_slice(iter);
1598
+ CheckEqual("box", key_slice.data, key_slice.size);
1599
+ CheckEqual("c", value_slice.data, value_slice.size);
1600
+
1601
+ rocksdb_iter_get_error(iter, &err);
1602
+ CheckNoError(err);
1603
+ rocksdb_iter_destroy(iter);
1604
+ }
1605
+
1423
1606
  StartPhase("wbwi_iter");
1424
1607
  {
1425
1608
  rocksdb_iterator_t* base_iter = rocksdb_create_iterator(db, roptions);
@@ -1505,6 +1688,53 @@ int main(int argc, char** argv) {
1505
1688
  CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
1506
1689
  }
1507
1690
 
1691
+ StartPhase("zero_copy_get_pinned_v2");
1692
+ {
1693
+ // Test new zero-copy get functions
1694
+
1695
+ // Test rocksdb_get_pinned_v2
1696
+ rocksdb_pinnable_handle_t* handle =
1697
+ rocksdb_get_pinned_v2(db, roptions, "foo", 3, &err);
1698
+ CheckNoError(err);
1699
+ CheckCondition(handle != NULL);
1700
+ size_t val_len;
1701
+ const char* val = rocksdb_pinnable_handle_get_value(handle, &val_len);
1702
+ CheckEqual("hello", val, val_len);
1703
+ rocksdb_pinnable_handle_destroy(handle);
1704
+
1705
+ // Test with non-existent key
1706
+ handle = rocksdb_get_pinned_v2(db, roptions, "notfound", 8, &err);
1707
+ CheckNoError(err);
1708
+ CheckCondition(handle == NULL);
1709
+
1710
+ // Test rocksdb_get_into_buffer
1711
+ char buffer[100];
1712
+ unsigned char found;
1713
+ unsigned char success = rocksdb_get_into_buffer(
1714
+ db, roptions, "foo", 3, buffer, sizeof(buffer), &val_len, &found, &err);
1715
+ CheckNoError(err);
1716
+ CheckCondition(success == 1);
1717
+ CheckCondition(found == 1);
1718
+ CheckCondition(val_len == 5);
1719
+ CheckCondition(memcmp(buffer, "hello", 5) == 0);
1720
+
1721
+ // Test with buffer too small
1722
+ success = rocksdb_get_into_buffer(db, roptions, "foo", 3, buffer,
1723
+ 2, // Buffer too small
1724
+ &val_len, &found, &err);
1725
+ CheckNoError(err);
1726
+ CheckCondition(success == 0); // Should fail due to small buffer
1727
+ CheckCondition(found == 1);
1728
+ CheckCondition(val_len == 5); // Should still report actual size
1729
+
1730
+ // Test with non-existent key
1731
+ success = rocksdb_get_into_buffer(db, roptions, "notfound", 8, buffer,
1732
+ sizeof(buffer), &val_len, &found, &err);
1733
+ CheckNoError(err);
1734
+ CheckCondition(success == 0);
1735
+ CheckCondition(found == 0);
1736
+ }
1737
+
1508
1738
  StartPhase("pin_get");
1509
1739
  {
1510
1740
  CheckPinGet(db, roptions, "box", "c");
@@ -1922,6 +2152,55 @@ int main(int argc, char** argv) {
1922
2152
  rocksdb_flush_wal(db, 1, &err);
1923
2153
  CheckNoError(err);
1924
2154
 
2155
+ // Test column family handle get name
2156
+ {
2157
+ size_t name_len;
2158
+ char* cf_name =
2159
+ rocksdb_column_family_handle_get_name(handles[1], &name_len);
2160
+ CheckCondition(name_len == 3);
2161
+ CheckCondition(memcmp(cf_name, "cf1", 3) == 0);
2162
+ rocksdb_free(cf_name);
2163
+ }
2164
+
2165
+ // Test zero-copy get with column families
2166
+ {
2167
+ rocksdb_pinnable_handle_t* handle =
2168
+ rocksdb_get_pinned_cf_v2(db, roptions, handles[1], "box", 3, &err);
2169
+ CheckNoError(err);
2170
+ CheckCondition(handle != NULL);
2171
+ size_t val_len;
2172
+ const char* val = rocksdb_pinnable_handle_get_value(handle, &val_len);
2173
+ CheckEqual("c", val, val_len);
2174
+ rocksdb_pinnable_handle_destroy(handle);
2175
+
2176
+ // Test with non-existent key
2177
+ handle = rocksdb_get_pinned_cf_v2(db, roptions, handles[1], "notfound", 8,
2178
+ &err);
2179
+ CheckNoError(err);
2180
+ CheckCondition(handle == NULL);
2181
+
2182
+ // Test rocksdb_get_into_buffer_cf
2183
+ char buffer[100];
2184
+ unsigned char found;
2185
+ unsigned char success = rocksdb_get_into_buffer_cf(
2186
+ db, roptions, handles[1], "buff", 4, buffer, sizeof(buffer), &val_len,
2187
+ &found, &err);
2188
+ CheckNoError(err);
2189
+ CheckCondition(success == 1);
2190
+ CheckCondition(found == 1);
2191
+ CheckCondition(val_len == 7);
2192
+ CheckCondition(memcmp(buffer, "rocksdb", 7) == 0);
2193
+
2194
+ // Test with buffer too small
2195
+ success = rocksdb_get_into_buffer_cf(db, roptions, handles[1], "buff", 4,
2196
+ buffer, 3, // Buffer too small
2197
+ &val_len, &found, &err);
2198
+ CheckNoError(err);
2199
+ CheckCondition(success == 0); // Should fail due to small buffer
2200
+ CheckCondition(found == 1);
2201
+ CheckCondition(val_len == 7); // Should still report actual size
2202
+ }
2203
+
1925
2204
  // Test WriteBatchWithIndex iteration with Column Family
1926
2205
  rocksdb_writebatch_wi_t* wbwi = rocksdb_writebatch_wi_create(0, true);
1927
2206
  rocksdb_writebatch_wi_put_cf(wbwi, handles[1], "boat", 4, "row",
@@ -1998,6 +2277,74 @@ int main(int argc, char** argv) {
1998
2277
  }
1999
2278
  }
2000
2279
 
2280
+ {
2281
+ // Test rocksdb_batched_multi_get_cf_slice for better performance
2282
+ // Build rocksdb_slice_t array directly to avoid conversion overhead
2283
+ rocksdb_slice_t batched_key_slices[4];
2284
+ batched_key_slices[0].data = "box";
2285
+ batched_key_slices[0].size = 3;
2286
+ batched_key_slices[1].data = "buff";
2287
+ batched_key_slices[1].size = 4;
2288
+ batched_key_slices[2].data = "barfooxx";
2289
+ batched_key_slices[2].size = 8;
2290
+ batched_key_slices[3].data = "box";
2291
+ batched_key_slices[3].size = 3;
2292
+
2293
+ const char* expected_value[4] = {"c", "rocksdb", NULL, "c"};
2294
+ char* batched_errs[4];
2295
+ rocksdb_pinnableslice_t* pvals[4];
2296
+
2297
+ rocksdb_batched_multi_get_cf_slice(db, roptions, handles[1], 4,
2298
+ batched_key_slices, pvals,
2299
+ batched_errs, false);
2300
+
2301
+ const char* val;
2302
+ size_t val_len;
2303
+ for (i = 0; i < 4; ++i) {
2304
+ CheckNoError(batched_errs[i]);
2305
+ if (pvals[i] != NULL) {
2306
+ val = rocksdb_pinnableslice_value(pvals[i], &val_len);
2307
+ CheckEqual(expected_value[i], val, val_len);
2308
+ rocksdb_pinnableslice_destroy(pvals[i]);
2309
+ } else {
2310
+ CheckEqual(expected_value[i], NULL, 0);
2311
+ }
2312
+ }
2313
+ }
2314
+
2315
+ {
2316
+ // Test rocksdb_batched_multi_get_cf_slice with sorted_input=true
2317
+ // Keys must be in sorted order for this optimization
2318
+ rocksdb_slice_t sorted_key_slices[3];
2319
+ sorted_key_slices[0].data = "box";
2320
+ sorted_key_slices[0].size = 3;
2321
+ sorted_key_slices[1].data = "buff";
2322
+ sorted_key_slices[1].size = 4;
2323
+ sorted_key_slices[2].data = "notfound";
2324
+ sorted_key_slices[2].size = 8;
2325
+
2326
+ const char* expected_value[3] = {"c", "rocksdb", NULL};
2327
+ char* batched_errs[3];
2328
+ rocksdb_pinnableslice_t* pvals[3];
2329
+
2330
+ rocksdb_batched_multi_get_cf_slice(db, roptions, handles[1], 3,
2331
+ sorted_key_slices, pvals, batched_errs,
2332
+ true);
2333
+
2334
+ const char* val;
2335
+ size_t val_len;
2336
+ for (i = 0; i < 3; ++i) {
2337
+ CheckNoError(batched_errs[i]);
2338
+ if (pvals[i] != NULL) {
2339
+ val = rocksdb_pinnableslice_value(pvals[i], &val_len);
2340
+ CheckEqual(expected_value[i], val, val_len);
2341
+ rocksdb_pinnableslice_destroy(pvals[i]);
2342
+ } else {
2343
+ CheckEqual(expected_value[i], NULL, 0);
2344
+ }
2345
+ }
2346
+ }
2347
+
2001
2348
  {
2002
2349
  unsigned char value_found = 0;
2003
2350
 
@@ -3469,6 +3816,17 @@ int main(int argc, char** argv) {
3469
3816
  rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err);
3470
3817
  CheckNoError(err);
3471
3818
 
3819
+ // test transaction get/set name (before commit)
3820
+ {
3821
+ rocksdb_transaction_set_name(txn, "test_txn", 8, &err);
3822
+ CheckNoError(err);
3823
+ size_t name_len;
3824
+ char* txn_name = rocksdb_transaction_get_name(txn, &name_len);
3825
+ CheckCondition(name_len == 8);
3826
+ CheckCondition(memcmp(txn_name, "test_txn", 8) == 0);
3827
+ rocksdb_free(txn_name);
3828
+ }
3829
+
3472
3830
  // read from outside transaction, before commit
3473
3831
  CheckTxnDBGet(txn_db, roptions, "foo", NULL);
3474
3832
  CheckTxnDBPinGet(txn_db, roptions, "foo", NULL);
@@ -4207,6 +4565,219 @@ int main(int argc, char** argv) {
4207
4565
  rocksdb_cache_destroy(lru);
4208
4566
  }
4209
4567
 
4568
+ StartPhase("remote_compaction_service");
4569
+ {
4570
+ RemoteCompactionState remote_state = {0, 0, 0, "", ""};
4571
+
4572
+ // Create compaction service
4573
+ rocksdb_compactionservice_t* service = rocksdb_compactionservice_create(
4574
+ &remote_state, // state
4575
+ RemoteCompactionDestroy, // destructor
4576
+ RemoteCompactionSchedule, // schedule callback
4577
+ "TestRemoteCompaction", // name
4578
+ RemoteCompactionWait, // wait callback
4579
+ RemoteCompactionCancel, // cancel_awaiting_jobs
4580
+ NULL); // on_installation
4581
+
4582
+ // Create options with remote compaction
4583
+ rocksdb_options_t* remote_options = rocksdb_options_create();
4584
+ rocksdb_options_set_create_if_missing(remote_options, 1);
4585
+ rocksdb_options_set_level0_file_num_compaction_trigger(remote_options, 2);
4586
+ rocksdb_options_set_write_buffer_size(remote_options,
4587
+ 64 * 1024); // 64KB buffer
4588
+ rocksdb_options_set_max_bytes_for_level_base(remote_options,
4589
+ 256 * 1024); // 256KB
4590
+ rocksdb_options_set_target_file_size_base(
4591
+ remote_options, 64 * 1024); // 64KB target file size
4592
+ // Disable automatic compactions to test manual compaction only
4593
+ rocksdb_options_set_disable_auto_compactions(remote_options, 1);
4594
+ rocksdb_options_set_compaction_service(remote_options, service);
4595
+
4596
+ // Destroy old DB and create new one
4597
+ rocksdb_close(db);
4598
+ rocksdb_destroy_db(remote_options, dbname, &err);
4599
+ CheckNoError(err);
4600
+
4601
+ db = rocksdb_open(remote_options, dbname, &err);
4602
+ CheckNoError(err);
4603
+
4604
+ // Create multiple SST files to trigger compaction
4605
+ rocksdb_flushoptions_t* flush_opts = rocksdb_flushoptions_create();
4606
+ rocksdb_flushoptions_set_wait(flush_opts, 1);
4607
+
4608
+ // Write and flush multiple times to create multiple L0 files
4609
+ // Write more data with larger values to ensure files are substantial
4610
+ for (int batch = 0; batch < 5; batch++) {
4611
+ for (int i = 0; i < 200; i++) {
4612
+ char key[20], val[1000];
4613
+ snprintf(key, sizeof(key), "key%d_%d", batch, i);
4614
+ // Fill value with repeated data to make it larger
4615
+ memset(val, 'a' + (batch % 26), sizeof(val) - 1);
4616
+ val[sizeof(val) - 1] = '\0';
4617
+ rocksdb_put(db, woptions, key, strlen(key), val, strlen(val), &err);
4618
+ CheckNoError(err);
4619
+ }
4620
+ rocksdb_flush(db, flush_opts, &err);
4621
+ CheckNoError(err);
4622
+ }
4623
+ rocksdb_flushoptions_destroy(flush_opts);
4624
+
4625
+ // Trigger manual compaction to invoke remote compaction service
4626
+ rocksdb_compact_range(db, NULL, 0, NULL, 0);
4627
+
4628
+ rocksdb_wait_for_compact_options_t* wco =
4629
+ rocksdb_wait_for_compact_options_create();
4630
+ rocksdb_wait_for_compact(db, wco, &err);
4631
+ CheckNoError(err);
4632
+ rocksdb_wait_for_compact_options_destroy(wco);
4633
+
4634
+ // Verify that callbacks were actually called
4635
+ CheckCondition(remote_state.schedule_called > 0);
4636
+ CheckCondition(remote_state.wait_called > 0);
4637
+ CheckCondition(strlen(remote_state.last_db_name) > 0);
4638
+ CheckCondition(strstr(remote_state.last_db_name, "rocksdb_c_test") != NULL);
4639
+
4640
+ // Verify data is still accessible after remote compaction
4641
+ // Just check a few keys to verify data integrity
4642
+ for (int batch = 0; batch < 5; batch++) {
4643
+ char key[20];
4644
+ snprintf(key, sizeof(key), "key%d_0", batch);
4645
+ size_t vallen;
4646
+ char* val = rocksdb_get(db, roptions, key, strlen(key), &vallen, &err);
4647
+ CheckNoError(err);
4648
+ CheckCondition(val != NULL);
4649
+ CheckCondition(vallen == 999); // strlen of 1000-byte string
4650
+ free(val);
4651
+ }
4652
+
4653
+ // Test cancellation API directly
4654
+ RemoteCompactionCancel(&remote_state);
4655
+ CheckCondition(remote_state.cancel_called > 0);
4656
+
4657
+ // Cleanup
4658
+ rocksdb_close(db);
4659
+ rocksdb_destroy_db(remote_options, dbname, &err);
4660
+ CheckNoError(err);
4661
+ rocksdb_options_destroy(remote_options);
4662
+
4663
+ // Reopen DB with original options for subsequent tests
4664
+ db = rocksdb_open(options, dbname, &err);
4665
+ CheckNoError(err);
4666
+ }
4667
+
4668
+ StartPhase("remote_compaction_scheduleresponse");
4669
+ {
4670
+ // Test scheduleresponse creation and getters
4671
+ rocksdb_compactionservice_scheduleresponse_t* response;
4672
+
4673
+ // Test success response
4674
+ err = NULL;
4675
+ response = rocksdb_compactionservice_scheduleresponse_create(
4676
+ "test-job-123", rocksdb_compactionservice_jobstatus_success, &err);
4677
+ CheckNoError(err);
4678
+ CheckCondition(response != NULL);
4679
+ CheckCondition(
4680
+ rocksdb_compactionservice_scheduleresponse_getstatus(response) ==
4681
+ rocksdb_compactionservice_jobstatus_success);
4682
+
4683
+ size_t job_id_len;
4684
+ const char* job_id =
4685
+ rocksdb_compactionservice_scheduleresponse_get_scheduled_job_id(
4686
+ response, &job_id_len);
4687
+ CheckCondition(job_id_len == strlen("test-job-123"));
4688
+ CheckCondition(memcmp(job_id, "test-job-123", job_id_len) == 0);
4689
+ rocksdb_compactionservice_scheduleresponse_t_destroy(response);
4690
+
4691
+ // Test failure response
4692
+ response = rocksdb_compactionservice_scheduleresponse_create_with_status(
4693
+ rocksdb_compactionservice_jobstatus_failure, &err);
4694
+ CheckCondition(response != NULL);
4695
+ CheckCondition(
4696
+ rocksdb_compactionservice_scheduleresponse_getstatus(response) ==
4697
+ rocksdb_compactionservice_jobstatus_failure);
4698
+ rocksdb_compactionservice_scheduleresponse_t_destroy(response);
4699
+
4700
+ response = rocksdb_compactionservice_scheduleresponse_create_with_status(
4701
+ 999, &err);
4702
+ CheckCondition(response == NULL); // Invalid status
4703
+ if (err) {
4704
+ Free(&err);
4705
+ }
4706
+ }
4707
+
4708
+ StartPhase("remote_compaction_options_override");
4709
+ {
4710
+ // Test CompactionServiceOptionsOverride API
4711
+ rocksdb_compaction_service_options_override_t* override_opts =
4712
+ rocksdb_compaction_service_options_override_create();
4713
+ CheckCondition(override_opts != NULL);
4714
+
4715
+ // Set up override options
4716
+ rocksdb_compaction_service_options_override_set_env(override_opts, env);
4717
+ rocksdb_compaction_service_options_override_set_comparator(override_opts,
4718
+ cmp);
4719
+
4720
+ rocksdb_compaction_service_options_override_destroy(override_opts);
4721
+ }
4722
+
4723
+ StartPhase("remote_compaction_null_callback_handling");
4724
+ {
4725
+ // Test that NULL callback returns are handled gracefully
4726
+ // This simulates a failure in the remote compaction service
4727
+ rocksdb_compactionservice_t* null_service =
4728
+ rocksdb_compactionservice_create(NULL, NULL, NullSchedule,
4729
+ "NullTestService", NULL, NULL, NULL);
4730
+
4731
+ rocksdb_options_t* null_opts = rocksdb_options_create();
4732
+ rocksdb_options_set_create_if_missing(null_opts, 1);
4733
+ rocksdb_options_set_compaction_service(null_opts, null_service);
4734
+
4735
+ const char* null_db = "rocksdb_c_test_null_service";
4736
+
4737
+ rocksdb_t* null_db_handle = rocksdb_open(null_opts, null_db, &err);
4738
+ CheckNoError(err);
4739
+
4740
+ // Write data and trigger compaction
4741
+ for (int i = 0; i < 100; i++) {
4742
+ char key[20], val[50];
4743
+ snprintf(key, sizeof(key), "key%d", i);
4744
+ snprintf(val, sizeof(val), "val%d", i);
4745
+ rocksdb_put(null_db_handle, woptions, key, strlen(key), val, strlen(val),
4746
+ &err);
4747
+ CheckNoError(err);
4748
+ }
4749
+
4750
+ // This should fall back to local compaction (not crash)
4751
+ rocksdb_compact_range(null_db_handle, NULL, 0, NULL, 0);
4752
+
4753
+ // Data should still be readable
4754
+ CheckGet(null_db_handle, roptions, "key50", "val50");
4755
+
4756
+ rocksdb_close(null_db_handle);
4757
+ rocksdb_destroy_db(null_opts, null_db, &err);
4758
+ rocksdb_options_destroy(null_opts);
4759
+ }
4760
+
4761
+ StartPhase("remote_compaction_canceled_flag");
4762
+ {
4763
+ // Test atomic cancellation flag API
4764
+ unsigned char* canceled = rocksdb_open_and_compact_canceled_create();
4765
+ CheckCondition(canceled != NULL);
4766
+
4767
+ // Set cancellation
4768
+ rocksdb_open_and_compact_canceled_set(canceled, 1);
4769
+
4770
+ // Use with OpenAndCompactOptions
4771
+ rocksdb_open_and_compact_options_t* oac_opts =
4772
+ rocksdb_open_and_compact_options_create();
4773
+ rocksdb_open_and_compact_options_set_canceled(oac_opts, canceled);
4774
+ rocksdb_open_and_compact_options_set_allow_resumption(oac_opts, 1);
4775
+
4776
+ // Cleanup
4777
+ rocksdb_open_and_compact_options_destroy(oac_opts);
4778
+ rocksdb_open_and_compact_canceled_destroy(canceled);
4779
+ }
4780
+
4210
4781
  StartPhase("sst_file_manager");
4211
4782
  {
4212
4783
  rocksdb_sst_file_manager_t* sst_file_manager;