From 5bc386e55f35692ba02638d51e5d6039ba7518e3 Mon Sep 17 00:00:00 2001 From: Radek Hubner Date: Tue, 30 Jul 2024 11:52:35 +0400 Subject: [PATCH 1/2] Add rocksdb_create_column_families_with_options to C API. --- db/c.cc | 28 ++++++++++++++++++++++++++++ db/c_test.c | 32 ++++++++++++++++++++++++++++++++ include/rocksdb/c.h | 7 +++++++ 3 files changed, 67 insertions(+) diff --git a/db/c.cc b/db/c.cc index 9b6db666da4..6005fd27de1 100644 --- a/db/c.cc +++ b/db/c.cc @@ -1145,6 +1145,34 @@ rocksdb_column_family_handle_t** rocksdb_create_column_families( return c_handles; } +rocksdb_column_family_handle_t** rocksdb_create_column_families_with_options( + rocksdb_t* db, int num_column_families, + const char* const* column_family_names, + const rocksdb_options_t* const* column_family_options, size_t* lencfs, + char** errptr) { + std::vector handles; + + std::vector column_families; + column_families.reserve(num_column_families); + for (int i = 0; i < num_column_families; i++) { + column_families.emplace_back( + std::string(column_family_names[i]), + ColumnFamilyOptions(column_family_options[i]->rep)); + } + SaveError(errptr, db->rep->CreateColumnFamilies(column_families, &handles)); + + *lencfs = handles.size(); + rocksdb_column_family_handle_t** c_handles = + static_cast( + malloc(sizeof(rocksdb_column_family_handle_t*) * handles.size())); + for (size_t i = 0; i != handles.size(); ++i) { + c_handles[i] = new rocksdb_column_family_handle_t; + c_handles[i]->rep = handles[i]; + c_handles[i]->immortal = false; + } + return c_handles; +} + void rocksdb_create_column_families_destroy( rocksdb_column_family_handle_t** list) { free(list); diff --git a/db/c_test.c b/db/c_test.c index eb9886ba467..a3b40051829 100644 --- a/db/c_test.c +++ b/db/c_test.c @@ -1634,6 +1634,37 @@ int main(int argc, char** argv) { CheckGet(db, roptions, "bar", "fake"); } + StartPhase("CF with option"); + { + rocksdb_close(db); + rocksdb_destroy_db(options, dbname, &err); + CheckNoError(err); + + rocksdb_options_t* db_options = rocksdb_options_create(); + rocksdb_options_set_create_if_missing(db_options, 1); + db = rocksdb_open(db_options, dbname, &err); + CheckNoError(err); + + char** list_const_cf_names = (char**)malloc(2 * sizeof(char*)); + list_const_cf_names[0] = "cf_with_options"; + list_const_cf_names[1] = "cf_with_option"; + size_t cflen; + const rocksdb_options_t* create_cf_options[2] = {db_options, db_options}; + rocksdb_column_family_handle_t** new_column_family_handle = + rocksdb_create_column_families_with_options( + db, 2, (const char* const*)list_const_cf_names, create_cf_options, + &cflen, &err); + free(list_const_cf_names); + CheckNoError(err); + assert(cflen == 2); + + rocksdb_column_family_handle_destroy(new_column_family_handle[0]); + rocksdb_column_family_handle_destroy(new_column_family_handle[1]); + + rocksdb_create_column_families_destroy(new_column_family_handle); + rocksdb_options_destroy(db_options); + } + StartPhase("columnfamilies"); { rocksdb_close(db); @@ -3710,6 +3741,7 @@ int main(int argc, char** argv) { cfh1 = list_cfh[0]; cfh2 = list_cfh[1]; rocksdb_create_column_families_destroy(list_cfh); + txn = rocksdb_optimistictransaction_begin(otxn_db, woptions, otxn_options, NULL); rocksdb_transaction_put_cf(txn, cfh1, "key_cf1", 7, "val_cf1", 7, &err); diff --git a/include/rocksdb/c.h b/include/rocksdb/c.h index ed403a6ea8e..76d5bc08320 100644 --- a/include/rocksdb/c.h +++ b/include/rocksdb/c.h @@ -423,6 +423,13 @@ rocksdb_create_column_families(rocksdb_t* db, const char* const* column_family_names, size_t* lencfs, char** errptr); +extern ROCKSDB_LIBRARY_API rocksdb_column_family_handle_t** +rocksdb_create_column_families_with_options( + rocksdb_t* db, int num_column_families, + const char* const* column_family_names, + const rocksdb_options_t* const* column_family_options, size_t* lencfs, + char** errptr); + extern ROCKSDB_LIBRARY_API void rocksdb_create_column_families_destroy( rocksdb_column_family_handle_t** list); From 40b5fb64f8929434039bc1b9004bacabcb07344b Mon Sep 17 00:00:00 2001 From: Radek Hubner Date: Fri, 2 Aug 2024 17:54:24 +0400 Subject: [PATCH 2/2] Address PR comments. --- db/c_test.c | 64 +++++++++++++++++++++++++++++++++++++-------- include/rocksdb/c.h | 21 +++++++++++++++ 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/db/c_test.c b/db/c_test.c index a3b40051829..49bde4dcfdd 100644 --- a/db/c_test.c +++ b/db/c_test.c @@ -1645,23 +1645,65 @@ int main(int argc, char** argv) { db = rocksdb_open(db_options, dbname, &err); CheckNoError(err); - char** list_const_cf_names = (char**)malloc(2 * sizeof(char*)); - list_const_cf_names[0] = "cf_with_options"; - list_const_cf_names[1] = "cf_with_option"; + char** cf_names = (char**)malloc(2 * sizeof(char*)); + cf_names[0] = "cf1"; + cf_names[1] = "cf2"; size_t cflen; - const rocksdb_options_t* create_cf_options[2] = {db_options, db_options}; - rocksdb_column_family_handle_t** new_column_family_handle = + + rocksdb_options_t* cf1_options = rocksdb_options_create(); + rocksdb_options_set_paranoid_checks(cf1_options, true); + rocksdb_options_set_create_if_missing(cf1_options, true); + + rocksdb_options_t* cf2_options = rocksdb_options_create(); + rocksdb_options_set_max_bytes_for_level_base(cf2_options, 4 * 1024); + rocksdb_options_set_create_if_missing(cf2_options, true); + + const rocksdb_options_t* cf_options[2] = {cf1_options, cf2_options}; + rocksdb_column_family_handle_t** column_family_handle = rocksdb_create_column_families_with_options( - db, 2, (const char* const*)list_const_cf_names, create_cf_options, - &cflen, &err); - free(list_const_cf_names); + db, 2, (const char* const*)cf_names, cf_options, &cflen, &err); + free(cf_names); CheckNoError(err); assert(cflen == 2); - rocksdb_column_family_handle_destroy(new_column_family_handle[0]); - rocksdb_column_family_handle_destroy(new_column_family_handle[1]); + rocksdb_writeoptions_t* write_options = rocksdb_writeoptions_create(); + + rocksdb_put_cf(db, write_options, column_family_handle[0], "cf1", 3, "val1", + 4, &err); + CheckNoError(err); + + rocksdb_put_cf(db, write_options, column_family_handle[1], "cf2", 3, "val2", + 4, &err); + CheckNoError(err); + + rocksdb_writeoptions_destroy(write_options); + + size_t val_len; + + rocksdb_readoptions_t* read_options = rocksdb_readoptions_create(); + + char* value1 = rocksdb_get_cf(db, read_options, column_family_handle[0], + "cf1", 3, &val_len, &err); + CheckNoError(err); + CheckEqual("val1", value1, val_len); + Free(&value1); + + char* value2 = rocksdb_get_cf(db, read_options, column_family_handle[1], + "cf2", 3, &val_len, &err); + CheckNoError(err); + CheckEqual("val2", value2, val_len); + Free(&value2); + + rocksdb_readoptions_destroy(read_options); + + rocksdb_column_family_handle_destroy(column_family_handle[0]); + rocksdb_column_family_handle_destroy(column_family_handle[1]); + + rocksdb_create_column_families_destroy(column_family_handle); + + rocksdb_options_destroy(cf1_options); + rocksdb_options_destroy(cf2_options); - rocksdb_create_column_families_destroy(new_column_family_handle); rocksdb_options_destroy(db_options); } diff --git a/include/rocksdb/c.h b/include/rocksdb/c.h index 76d5bc08320..abeb1591c94 100644 --- a/include/rocksdb/c.h +++ b/include/rocksdb/c.h @@ -423,6 +423,27 @@ rocksdb_create_column_families(rocksdb_t* db, const char* const* column_family_names, size_t* lencfs, char** errptr); +/** + * @brief Creates multiple column families in the specified RocksDB database + * with the given options for each column family. + * + * @param db A pointer to the RocksDB database instance. + * @param num_column_families The number of column families to create. + * @param column_family_names An array of null-terminated strings, each + * representing the name of a column family to create. + * @param column_family_options An array of pointers to rocksdb_options_t + * structures, each specifying the options for the corresponding column family. + * @param lencfs A pointer to a size_t variable where the length of the created + * column families will be stored. + * @param errptr A pointer to a char pointer. If an error occurs, a descriptive + * error message will be stored in the memory pointed to by errptr. The caller + * must free this memory using rocksdb_free when it is no longer needed. + * + * @return An array of pointers to rocksdb_column_family_handle_t structures, + * each representing a handle to the created column families. The length of this + * array is stored in the variable pointed to by lencfs. If an error occurs, + * NULL is returned and errptr is set to a descriptive error message. + */ extern ROCKSDB_LIBRARY_API rocksdb_column_family_handle_t** rocksdb_create_column_families_with_options( rocksdb_t* db, int num_column_families,