From 74f18c13019cb367bdafef4ee7c618d02d62c08d Mon Sep 17 00:00:00 2001 From: Andrew Kryczka Date: Fri, 11 Aug 2017 13:46:41 -0700 Subject: [PATCH] db_bench support for non-uniform column family ops Summary: Previously we could only select the CF on which to operate uniformly at random. This is a limitation, e.g., when testing universal compaction as all CFs would need to run full compaction at roughly the same time, which isn't realistic. This PR allows the user to specify the probability distribution for selecting CFs via the `--column_family_distribution` argument. Closes https://github.com/facebook/rocksdb/pull/2677 Differential Revision: D5544436 Pulled By: ajkr fbshipit-source-id: 478d56260995236ae90895ce5bd51f38882e185a --- tools/db_bench_tool.cc | 52 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/tools/db_bench_tool.cc b/tools/db_bench_tool.cc index 6f12390af..0f8909543 100644 --- a/tools/db_bench_tool.cc +++ b/tools/db_bench_tool.cc @@ -206,6 +206,15 @@ DEFINE_int32( "create new set of column families and insert to them. Only used " "when num_column_families > 1."); +DEFINE_string(column_family_distribution, "", + "Comma-separated list of percentages, where the ith element " + "indicates the probability of an op using the ith column family. " + "The number of elements must be `num_hot_column_families` if " + "specified; otherwise, it must be `num_column_families`. The " + "sum of elements must be 100. E.g., if `num_column_families=4`, " + "and `num_hot_column_families=0`, a valid list could be " + "\"10,20,30,40\"."); + DEFINE_int64(reads, -1, "Number of read operations to do. " "If negative, do FLAGS_num reads."); @@ -1198,6 +1207,8 @@ struct DBWithColumnFamilies { // After each CreateNewCf(), another num_hot number of new // Column families will be created and used to be queried. port::Mutex create_cf_mutex; // Only one thread can execute CreateNewCf() + std::vector cfh_idx_to_prob; // ith index holds probability of operating + // on cfh[i]. DBWithColumnFamilies() : db(nullptr) @@ -1217,7 +1228,9 @@ struct DBWithColumnFamilies { opt_txn_db(other.opt_txn_db), #endif // ROCKSDB_LITE num_created(other.num_created.load()), - num_hot(other.num_hot) {} + num_hot(other.num_hot), + cfh_idx_to_prob(other.cfh_idx_to_prob) { + } void DeleteDBs() { std::for_each(cfh.begin(), cfh.end(), @@ -1239,8 +1252,20 @@ struct DBWithColumnFamilies { ColumnFamilyHandle* GetCfh(int64_t rand_num) { assert(num_hot > 0); + size_t rand_offset = 0; + if (!cfh_idx_to_prob.empty()) { + assert(cfh_idx_to_prob.size() == num_hot); + int sum = 0; + while (sum + cfh_idx_to_prob[rand_offset] < rand_num % 100) { + sum += cfh_idx_to_prob[rand_offset]; + ++rand_offset; + } + assert(rand_offset < cfh_idx_to_prob.size()); + } else { + rand_offset = rand_num % num_hot; + } return cfh[num_created.load(std::memory_order_acquire) - num_hot + - rand_num % num_hot]; + rand_offset]; } // stage: assume CF from 0 to stage * num_hot has be created. Need to create @@ -3275,6 +3300,28 @@ void VerifyDBFromDB(std::string& truth_db_name) { column_families.push_back(ColumnFamilyDescriptor( ColumnFamilyName(i), ColumnFamilyOptions(options))); } + std::vector cfh_idx_to_prob; + if (!FLAGS_column_family_distribution.empty()) { + std::stringstream cf_prob_stream(FLAGS_column_family_distribution); + std::string cf_prob; + int sum = 0; + while (std::getline(cf_prob_stream, cf_prob, ',')) { + cfh_idx_to_prob.push_back(std::stoi(cf_prob)); + sum += cfh_idx_to_prob.back(); + } + if (sum != 100) { + fprintf(stderr, "column_family_distribution items must sum to 100\n"); + exit(1); + } + if (cfh_idx_to_prob.size() != num_hot) { + fprintf(stderr, + "got %" ROCKSDB_PRIszt + " column_family_distribution items; expected " + "%" ROCKSDB_PRIszt "\n", + cfh_idx_to_prob.size(), num_hot); + exit(1); + } + } #ifndef ROCKSDB_LITE if (FLAGS_readonly) { s = DB::OpenForReadOnly(options, db_name, column_families, @@ -3302,6 +3349,7 @@ void VerifyDBFromDB(std::string& truth_db_name) { db->cfh.resize(FLAGS_num_column_families); db->num_created = num_hot; db->num_hot = num_hot; + db->cfh_idx_to_prob = std::move(cfh_idx_to_prob); #ifndef ROCKSDB_LITE } else if (FLAGS_readonly) { s = DB::OpenForReadOnly(options, db_name, &db->db);