|
53 | 53 | #include "rocksdb/trace_record.h" |
54 | 54 | #include "rocksdb/unique_id.h" |
55 | 55 | #include "rocksdb/user_defined_index.h" |
| 56 | +#include "rocksdb/utilities/object_registry.h" |
56 | 57 | #include "rocksdb/write_buffer_manager.h" |
57 | 58 | #include "table/block_based/block.h" |
58 | 59 | #include "table/block_based/block_based_table_builder.h" |
@@ -8068,6 +8069,92 @@ TEST_F(UserDefinedIndexTest, IngestFailTest) { |
8068 | 8069 | ASSERT_OK(db->Close()); |
8069 | 8070 | ASSERT_OK(DestroyDB(dbname, options)); |
8070 | 8071 | } |
| 8072 | + |
| 8073 | +TEST_F(UserDefinedIndexTest, ConfigTest) { |
| 8074 | + Options options; |
| 8075 | + BlockBasedTableOptions table_options; |
| 8076 | + std::string dbname = test::PerThreadDBPath("user_defined_index_test"); |
| 8077 | + std::string ingest_file = dbname + "test.sst"; |
| 8078 | + |
| 8079 | + // Set up the user-defined index factory |
| 8080 | + auto user_defined_index_factory = |
| 8081 | + std::make_shared<TestUserDefinedIndexFactory>(); |
| 8082 | + table_options.user_defined_index_factory = user_defined_index_factory; |
| 8083 | + |
| 8084 | + // Set up custom flush block policy that flushes every 3 keys |
| 8085 | + table_options.flush_block_policy_factory = |
| 8086 | + std::make_shared<CustomFlushBlockPolicyFactory>(); |
| 8087 | + |
| 8088 | + options.table_factory.reset(NewBlockBasedTableFactory(table_options)); |
| 8089 | + |
| 8090 | + std::unique_ptr<SstFileWriter> writer; |
| 8091 | + writer.reset(new SstFileWriter(EnvOptions(), options)); |
| 8092 | + ASSERT_OK(writer->Open(ingest_file)); |
| 8093 | + |
| 8094 | + // Add 100 keys instead of just 5 |
| 8095 | + for (int i = 0; i < 100; i++) { |
| 8096 | + std::stringstream ss; |
| 8097 | + ss << std::setw(2) << std::setfill('0') << i; |
| 8098 | + std::string key = "key" + ss.str(); |
| 8099 | + std::string value = "value" + ss.str(); |
| 8100 | + ASSERT_OK(writer->Put(key, value)); |
| 8101 | + } |
| 8102 | + ASSERT_OK(writer->Finish()); |
| 8103 | + writer.reset(); |
| 8104 | + |
| 8105 | + table_options.user_defined_index_factory.reset(); |
| 8106 | + options.table_factory.reset(NewBlockBasedTableFactory(table_options)); |
| 8107 | + // Set up the user-defined index factory |
| 8108 | + ObjectLibrary::Default().get()->AddFactory<UserDefinedIndexFactory>( |
| 8109 | + "test_index", [](const std::string& /* uri */, |
| 8110 | + std::unique_ptr<UserDefinedIndexFactory>* guard, |
| 8111 | + std::string* /* errmsg */) { |
| 8112 | + auto factory = new TestUserDefinedIndexFactory(); |
| 8113 | + guard->reset(factory); |
| 8114 | + return guard->get(); |
| 8115 | + }); |
| 8116 | + ASSERT_OK(GetColumnFamilyOptionsFromString( |
| 8117 | + ConfigOptions(), options, |
| 8118 | + "block_based_table_factory={user_defined_index_factory=test_index;}", |
| 8119 | + &options)); |
| 8120 | + |
| 8121 | + std::unique_ptr<DB> db; |
| 8122 | + options.create_if_missing = true; |
| 8123 | + Status s = DB::Open(options, dbname, &db); |
| 8124 | + ASSERT_OK(s); |
| 8125 | + ASSERT_TRUE(db != nullptr); |
| 8126 | + ColumnFamilyHandle* cfh = nullptr; |
| 8127 | + ASSERT_OK(db->CreateColumnFamily(options, "new_cf", &cfh)); |
| 8128 | + |
| 8129 | + IngestExternalFileOptions ifo; |
| 8130 | + s = db->IngestExternalFile(cfh, {ingest_file}, ifo); |
| 8131 | + ASSERT_OK(s); |
| 8132 | + |
| 8133 | + ReadOptions ro; |
| 8134 | + ro.table_index_factory = user_defined_index_factory.get(); |
| 8135 | + std::unique_ptr<Iterator> iter(db->NewIterator(ro, cfh)); |
| 8136 | + ASSERT_NE(iter, nullptr); |
| 8137 | + MultiScanArgs scan_opts; |
| 8138 | + std::unordered_map<std::string, std::string> property_bag; |
| 8139 | + property_bag["count"] = std::to_string(25); |
| 8140 | + scan_opts.insert(Slice("key20"), std::optional(property_bag)); |
| 8141 | + iter->Prepare(scan_opts); |
| 8142 | + // Test that we can read all the keys |
| 8143 | + int key_count = 0; |
| 8144 | + for (iter->Seek(scan_opts.GetScanRanges()[0].range.start.value()); |
| 8145 | + iter->Valid(); iter->Next()) { |
| 8146 | + key_count++; |
| 8147 | + } |
| 8148 | + ASSERT_GE(key_count, 25); |
| 8149 | + // The index may undercount by 2 blocks |
| 8150 | + ASSERT_LE(key_count, 30); |
| 8151 | + ASSERT_OK(iter->status()); |
| 8152 | + iter.reset(); |
| 8153 | + |
| 8154 | + ASSERT_OK(db->DestroyColumnFamilyHandle(cfh)); |
| 8155 | + ASSERT_OK(db->Close()); |
| 8156 | + ASSERT_OK(DestroyDB(dbname, options)); |
| 8157 | +} |
8071 | 8158 | } // namespace ROCKSDB_NAMESPACE |
8072 | 8159 |
|
8073 | 8160 | int main(int argc, char** argv) { |
|
0 commit comments