diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 42844d22a..decd98b22 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -121,5 +121,8 @@ if (${non_coverage_build}) add_executable(log_store_benchmark) target_sources(log_store_benchmark PRIVATE log_store_benchmark.cpp) target_link_libraries(log_store_benchmark hs_logdev homestore ${COMMON_TEST_DEPS} benchmark::benchmark) - #add_test(NAME LogStoreBench COMMAND test_log_benchmark) + + add_executable(index_btree_benchmark) + target_sources(index_btree_benchmark PRIVATE index_btree_benchmark.cpp) + target_link_libraries(index_btree_benchmark homestore ${COMMON_TEST_DEPS} benchmark::benchmark) endif() diff --git a/src/tests/btree_helpers/btree_decls.h b/src/tests/btree_helpers/btree_decls.h new file mode 100644 index 000000000..2c99e90a3 --- /dev/null +++ b/src/tests/btree_helpers/btree_decls.h @@ -0,0 +1,59 @@ + +/********************************************************************************* + * Modifications Copyright 2017-2019 eBay Inc. + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + *********************************************************************************/ +#pragma once + +#include + +struct FixedLenBtree { + using BtreeType = IndexTable< TestFixedKey, TestFixedValue >; + using KeyType = TestFixedKey; + using ValueType = TestFixedValue; + static constexpr btree_node_type leaf_node_type = btree_node_type::FIXED; + static constexpr btree_node_type interior_node_type = btree_node_type::FIXED; +}; + +struct VarKeySizeBtree { + using BtreeType = IndexTable< TestVarLenKey, TestFixedValue >; + using KeyType = TestVarLenKey; + using ValueType = TestFixedValue; + static constexpr btree_node_type leaf_node_type = btree_node_type::VAR_KEY; + static constexpr btree_node_type interior_node_type = btree_node_type::VAR_KEY; +}; + +struct VarValueSizeBtree { + using BtreeType = IndexTable< TestVarLenKey, TestVarLenValue >; + using KeyType = TestVarLenKey; + using ValueType = TestVarLenValue; + static constexpr btree_node_type leaf_node_type = btree_node_type::VAR_OBJECT; + static constexpr btree_node_type interior_node_type = btree_node_type::VAR_OBJECT; +}; + +struct VarObjSizeBtree { + using BtreeType = IndexTable< TestVarLenKey, TestVarLenValue >; + using KeyType = TestVarLenKey; + using ValueType = TestVarLenValue; + static constexpr btree_node_type leaf_node_type = btree_node_type::VAR_OBJECT; + static constexpr btree_node_type interior_node_type = btree_node_type::VAR_OBJECT; +}; + +struct PrefixIntervalBtree { + using BtreeType = IndexTable< TestIntervalKey, TestIntervalValue >; + using KeyType = TestIntervalKey; + using ValueType = TestIntervalValue; + static constexpr btree_node_type leaf_node_type = btree_node_type::PREFIX; + static constexpr btree_node_type interior_node_type = btree_node_type::FIXED; +}; \ No newline at end of file diff --git a/src/tests/btree_helpers/btree_test_helper.hpp b/src/tests/btree_helpers/btree_test_helper.hpp index a5fba4132..e9e93b491 100644 --- a/src/tests/btree_helpers/btree_test_helper.hpp +++ b/src/tests/btree_helpers/btree_test_helper.hpp @@ -13,37 +13,35 @@ * specific language governing permissions and limitations under the License. * *********************************************************************************/ +#pragma once + #include #include +#include #include -#include #include #include #include #include #include -#include -#include -#include #include #include "test_common/range_scheduler.hpp" #include "shadow_map.hpp" -#include "btree_test_kvs.hpp" static constexpr uint32_t g_node_size{4096}; template < typename TestType > -struct BtreeTestHelper : public testing::Test { +struct BtreeTestHelper { using T = TestType; using K = typename TestType::KeyType; using V = typename TestType::ValueType; using mutex = iomgr::FiberManagerLib::shared_mutex; using op_func_t = std::function< void(void) >; - BtreeTestHelper() : testing::Test(), m_shadow_map{SISL_OPTIONS["num_entries"].as< uint32_t >()} {} + BtreeTestHelper() : m_shadow_map{SISL_OPTIONS["num_entries"].as< uint32_t >()} {} - void SetUp() override { + void SetUp() { m_cfg.m_leaf_node_type = T::leaf_node_type; m_cfg.m_int_node_type = T::interior_node_type; m_max_range_input = SISL_OPTIONS["num_entries"].as< uint32_t >(); @@ -66,7 +64,7 @@ struct BtreeTestHelper : public testing::Test { m_operations["query"] = std::bind(&BtreeTestHelper::query_random, this); } - void TearDown() override {} + void TearDown() {} protected: std::shared_ptr< typename T::BtreeType > m_bt; @@ -82,6 +80,7 @@ struct BtreeTestHelper : public testing::Test { std::condition_variable m_test_done_cv; std::random_device m_re; + std::atomic< uint32_t > m_num_ops{0}; public: void preload(uint32_t preload_size) { @@ -110,6 +109,8 @@ struct BtreeTestHelper : public testing::Test { LOGINFO("Preload Done"); } + uint32_t get_op_num() const { return m_num_ops.load(); } + ////////////////////// All put operation variants /////////////////////////////// void put(uint64_t k, btree_put_type put_type) { do_put(k, put_type, V::generate_rand()); } @@ -364,6 +365,7 @@ struct BtreeTestHelper : public testing::Test { } } +protected: void run_in_parallel(const std::vector< std::pair< std::string, int > >& op_list) { auto test_count = m_fibers.size(); for (auto it = m_fibers.begin(); it < m_fibers.end(); ++it) { @@ -379,10 +381,13 @@ struct BtreeTestHelper : public testing::Test { // Construct a weighted distribution based on the input frequencies std::discrete_distribution< uint32_t > s_rand_op_generator(weights.begin(), weights.end()); auto m_start_time = Clock::now(); - auto time_to_stop = [this, m_start_time]() {return (get_elapsed_time_sec(m_start_time) > m_run_time);}; + auto time_to_stop = [this, m_start_time]() { + return (get_elapsed_time_sec(m_start_time) > m_run_time); + }; for (uint32_t i = 0; i < num_iters_per_thread && !time_to_stop(); i++) { uint32_t op_idx = s_rand_op_generator(re); (this->m_operations[op_list[op_idx].first])(); + m_num_ops.fetch_add(1); } { std::unique_lock lg(m_test_done_mtx); @@ -397,4 +402,35 @@ struct BtreeTestHelper : public testing::Test { } LOGINFO("ALL parallel jobs joined"); } + + std::vector< std::pair< std::string, int > > build_op_list(std::vector< std::string >& input_ops) { + std::vector< std::pair< std::string, int > > ops; + int total = std::accumulate(input_ops.begin(), input_ops.end(), 0, [](int sum, const auto& str) { + std::vector< std::string > tokens; + boost::split(tokens, str, boost::is_any_of(":")); + if (tokens.size() == 2) { + try { + return sum + std::stoi(tokens[1]); + } catch (const std::exception&) { + // Invalid frequency, ignore this element + } + } + return sum; // Ignore malformed strings + }); + + std::transform(input_ops.begin(), input_ops.end(), std::back_inserter(ops), [total](const auto& str) { + std::vector< std::string > tokens; + boost::split(tokens, str, boost::is_any_of(":")); + if (tokens.size() == 2) { + try { + return std::make_pair(tokens[0], (int)(100.0 * std::stoi(tokens[1]) / total)); + } catch (const std::exception&) { + // Invalid frequency, ignore this element + } + } + return std::make_pair(std::string(), 0); + }); + + return ops; + } }; diff --git a/src/tests/btree_helpers/btree_test_kvs.hpp b/src/tests/btree_helpers/btree_test_kvs.hpp index a5dada646..f13aa1d5d 100644 --- a/src/tests/btree_helpers/btree_test_kvs.hpp +++ b/src/tests/btree_helpers/btree_test_kvs.hpp @@ -14,12 +14,17 @@ * *********************************************************************************/ #pragma once + #include #include #include #include #include + #include +#include +#include +#include static constexpr uint32_t g_max_keysize{100}; // for node size = 512 : free space : 442 => 100+100+6(record size) = 46% static constexpr uint32_t g_max_valsize{100}; diff --git a/src/tests/index_btree_benchmark.cpp b/src/tests/index_btree_benchmark.cpp new file mode 100644 index 000000000..b71ccac19 --- /dev/null +++ b/src/tests/index_btree_benchmark.cpp @@ -0,0 +1,142 @@ +/********************************************************************************* + * Modifications Copyright 2017-2019 eBay Inc. + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + *********************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include "test_common/homestore_test_common.hpp" +#include "btree_helpers/btree_test_kvs.hpp" +#include "test_common/range_scheduler.hpp" +#include "btree_helpers/btree_test_helper.hpp" +#include "btree_helpers/btree_decls.h" + +using namespace homestore; + +#define INDEX_BETREE_BENCHMARK(BTREE_TYPE) \ + BENCHMARK(run_benchmark< BTREE_TYPE >) \ + ->Setup(BM_Setup< BTREE_TYPE >) \ + ->Teardown(BM_Teardown< BTREE_TYPE >) \ + ->UseRealTime() \ + ->Iterations(1) \ + ->Name(#BTREE_TYPE); + +// this is used to splite the setup and teardown from the benchmark to get a more accurate result +void* globle_helper{nullptr}; + +#define GET_BENCHMARK_HELPER(BTREE_TYPE) static_cast< IndexBtreeBenchmark< BTREE_TYPE >* >(globle_helper) + +SISL_LOGGING_INIT(HOMESTORE_LOG_MODS) +std::vector< std::string > test_common::HSTestHelper::s_dev_names; +SISL_OPTIONS_ENABLE(logging, index_btree_benchmark, iomgr, test_common_setup) + +SISL_OPTION_GROUP(index_btree_benchmark, + (num_iters, "", "num_iters", "number of iterations for rand ops", + ::cxxopts::value< uint32_t >()->default_value("500"), "number"), + (num_entries, "", "num_entries", "number of entries to test with", + ::cxxopts::value< uint32_t >()->default_value("5000"), "number"), + (run_time, "", "run_time", "run time for io", ::cxxopts::value< uint32_t >()->default_value("30"), + "seconds"), + (operation_list, "", "operation_list", + "operation list instead of default created following by percentage", + ::cxxopts::value< std::vector< std::string > >()->default_value({"put:100"}), "operations [...]"), + (preload_size, "", "preload_size", "number of entries to preload tree with", + ::cxxopts::value< uint32_t >()->default_value("1000"), "number")) + +template < typename TestType > +struct IndexBtreeBenchmark : public BtreeTestHelper< TestType > { + using T = TestType; + using K = typename TestType::KeyType; + using V = typename TestType::ValueType; + IndexBtreeBenchmark() { SetUp(); } + + ~IndexBtreeBenchmark() { TearDown(); } + + void SetUp() { + test_common::HSTestHelper::start_homestore( + "index_btree_benchmark", {{HS_SERVICE::META, {.size_pct = 10.0}}, {HS_SERVICE::INDEX, {.size_pct = 70.0}}}); + + this->m_cfg = BtreeConfig(hs()->index_service().node_size()); + this->m_is_multi_threaded = true; + + auto uuid = boost::uuids::random_generator()(); + auto parent_uuid = boost::uuids::random_generator()(); + + BtreeTestHelper< TestType >::SetUp(); + this->m_bt = std::make_shared< typename T::BtreeType >(uuid, parent_uuid, 0, this->m_cfg); + hs()->index_service().add_index_table(this->m_bt); + auto input_ops = SISL_OPTIONS["operation_list"].as< std::vector< std::string > >(); + m_op_list = this->build_op_list(input_ops); + } + + void TearDown() { + BtreeTestHelper< TestType >::TearDown(); + test_common::HSTestHelper::shutdown_homestore(); + } + + void run_benchmark() { this->run_in_parallel(m_op_list); } + +private: + std::vector< std::pair< std::string, int > > m_op_list; +}; + +template < class BenchmarkType > +void BM_Setup(const benchmark::State& state) { + globle_helper = new IndexBtreeBenchmark< BenchmarkType >(); + auto helper = GET_BENCHMARK_HELPER(BenchmarkType); + helper->preload(SISL_OPTIONS["preload_size"].as< uint32_t >()); +} + +template < class BenchmarkType > +void BM_Teardown(const benchmark::State& state) { + delete GET_BENCHMARK_HELPER(BenchmarkType); +} + +template < class BenchmarkType > +void add_custom_counter(benchmark::State& state) { + auto helper = GET_BENCHMARK_HELPER(BenchmarkType); + auto totol_ops = helper->get_op_num(); + state.counters["thread_num"] = SISL_OPTIONS["num_threads"].as< uint32_t >(); + state.counters["fiber_num"] = SISL_OPTIONS["num_fibers"].as< uint32_t >(); + state.counters["total_ops"] = totol_ops; + state.counters["rate"] = benchmark::Counter(totol_ops, benchmark::Counter::kIsRate); + state.counters["InvRate"] = + benchmark::Counter(totol_ops, benchmark::Counter::kIsRate | benchmark::Counter::kInvert); +} + +template < class BenchmarkType > +void run_benchmark(benchmark::State& state) { + auto helper = GET_BENCHMARK_HELPER(BenchmarkType); + for (auto _ : state) { + helper->run_benchmark(); + } + add_custom_counter< BenchmarkType >(state); +} + +INDEX_BETREE_BENCHMARK(FixedLenBtree) +INDEX_BETREE_BENCHMARK(VarKeySizeBtree) +INDEX_BETREE_BENCHMARK(VarValueSizeBtree) +INDEX_BETREE_BENCHMARK(VarObjSizeBtree) +INDEX_BETREE_BENCHMARK(PrefixIntervalBtree) + +int main(int argc, char** argv) { + SISL_OPTIONS_LOAD(argc, argv, logging, index_btree_benchmark, iomgr, test_common_setup); + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); +} diff --git a/src/tests/test_btree_node.cpp b/src/tests/test_btree_node.cpp index 23109cd58..7ba6f9611 100644 --- a/src/tests/test_btree_node.cpp +++ b/src/tests/test_btree_node.cpp @@ -14,9 +14,6 @@ * *********************************************************************************/ #include -#include -#include -#include #include #include diff --git a/src/tests/test_common/homestore_test_common.hpp b/src/tests/test_common/homestore_test_common.hpp index 84062b8a6..846e1c801 100644 --- a/src/tests/test_common/homestore_test_common.hpp +++ b/src/tests/test_common/homestore_test_common.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -152,7 +153,8 @@ class HSTestHelper { } LOGINFO("Starting iomgr with {} threads, spdk: {}", num_threads, is_spdk); - ioenvironment.with_iomgr(iomgr::iomgr_params{.num_threads = num_threads, .is_spdk = is_spdk, .num_fibers = num_fibers}); + ioenvironment.with_iomgr( + iomgr::iomgr_params{.num_threads = num_threads, .is_spdk = is_spdk, .num_fibers = num_fibers}); auto const http_port = SISL_OPTIONS["http_port"].as< int >(); if (http_port != 0) { @@ -305,4 +307,4 @@ class HSTestHelper { } } }; -} // namespace test_common +}; // namespace test_common diff --git a/src/tests/test_index_btree.cpp b/src/tests/test_index_btree.cpp index b5f9eabaf..1872b79f5 100644 --- a/src/tests/test_index_btree.cpp +++ b/src/tests/test_index_btree.cpp @@ -13,27 +13,17 @@ * specific language governing permissions and limitations under the License. * *********************************************************************************/ - -#include -#include -#include #include #include -#include -#include -#include #include -#include -#include -#include -#include #include "common/homestore_config.hpp" #include "common/resource_mgr.hpp" #include "test_common/homestore_test_common.hpp" #include "test_common/range_scheduler.hpp" -#include "btree_helpers/btree_test_kvs.hpp" #include "btree_helpers/btree_test_helper.hpp" +#include "btree_helpers/btree_test_kvs.hpp" +#include "btree_helpers/btree_decls.h" using namespace homestore; @@ -46,62 +36,23 @@ std::vector< std::string > test_common::HSTestHelper::s_dev_names; // TODO Add tests to do write,remove after recovery. // TODO Test with var len key with io mgr page size is 512. -SISL_OPTION_GROUP(test_index_btree, - (num_iters, "", "num_iters", "number of iterations for rand ops", - ::cxxopts::value< uint32_t >()->default_value("500"), "number"), - (num_entries, "", "num_entries", "number of entries to test with", - ::cxxopts::value< uint32_t >()->default_value("5000"), "number"), - (run_time, "", "run_time", "run time for io", ::cxxopts::value< uint32_t >()->default_value("360000"), "seconds"), - (disable_merge, "", "disable_merge", "disable_merge", ::cxxopts::value< bool >()->default_value("0"), ""), - (operation_list, "", "operation_list", "operation list instead of default created following by percentage", - ::cxxopts::value< std::vector< std::string > >(), "operations [...]"), - (preload_size, "", "preload_size", "number of entries to preload tree with", - ::cxxopts::value< uint32_t >()->default_value("1000"), "number"), - (seed, "", "seed", "random engine seed, use random if not defined", - ::cxxopts::value< uint64_t >()->default_value("0"), "number")) - -struct FixedLenBtreeTest { - using BtreeType = IndexTable< TestFixedKey, TestFixedValue >; - using KeyType = TestFixedKey; - using ValueType = TestFixedValue; - static constexpr btree_node_type leaf_node_type = btree_node_type::FIXED; - static constexpr btree_node_type interior_node_type = btree_node_type::FIXED; -}; - -struct VarKeySizeBtreeTest { - using BtreeType = IndexTable< TestVarLenKey, TestFixedValue >; - using KeyType = TestVarLenKey; - using ValueType = TestFixedValue; - static constexpr btree_node_type leaf_node_type = btree_node_type::VAR_KEY; - static constexpr btree_node_type interior_node_type = btree_node_type::VAR_KEY; -}; - -struct VarValueSizeBtreeTest { - using BtreeType = IndexTable< TestFixedKey, TestVarLenValue >; - using KeyType = TestFixedKey; - using ValueType = TestVarLenValue; - static constexpr btree_node_type leaf_node_type = btree_node_type::VAR_VALUE; - static constexpr btree_node_type interior_node_type = btree_node_type::FIXED; -}; - -struct VarObjSizeBtreeTest { - using BtreeType = IndexTable< TestVarLenKey, TestVarLenValue >; - using KeyType = TestVarLenKey; - using ValueType = TestVarLenValue; - static constexpr btree_node_type leaf_node_type = btree_node_type::VAR_OBJECT; - static constexpr btree_node_type interior_node_type = btree_node_type::VAR_OBJECT; -}; - -struct PrefixIntervalBtreeTest { - using BtreeType = IndexTable< TestIntervalKey, TestIntervalValue >; - using KeyType = TestIntervalKey; - using ValueType = TestIntervalValue; - static constexpr btree_node_type leaf_node_type = btree_node_type::PREFIX; - static constexpr btree_node_type interior_node_type = btree_node_type::FIXED; -}; +SISL_OPTION_GROUP( + test_index_btree, + (num_iters, "", "num_iters", "number of iterations for rand ops", + ::cxxopts::value< uint32_t >()->default_value("500"), "number"), + (num_entries, "", "num_entries", "number of entries to test with", + ::cxxopts::value< uint32_t >()->default_value("5000"), "number"), + (run_time, "", "run_time", "run time for io", ::cxxopts::value< uint32_t >()->default_value("360000"), "seconds"), + (disable_merge, "", "disable_merge", "disable_merge", ::cxxopts::value< bool >()->default_value("0"), ""), + (operation_list, "", "operation_list", "operation list instead of default created following by percentage", + ::cxxopts::value< std::vector< std::string > >(), "operations [...]"), + (preload_size, "", "preload_size", "number of entries to preload tree with", + ::cxxopts::value< uint32_t >()->default_value("1000"), "number"), + (seed, "", "seed", "random engine seed, use random if not defined", + ::cxxopts::value< uint64_t >()->default_value("0"), "number")) template < typename TestType > -struct BtreeTest : public BtreeTestHelper< TestType > { +struct BtreeTest : public BtreeTestHelper< TestType >, public ::testing::Test { using T = TestType; using K = typename TestType::KeyType; using V = typename TestType::ValueType; @@ -120,6 +71,8 @@ struct BtreeTest : public BtreeTestHelper< TestType > { BtreeTest* m_test; }; + BtreeTest() : testing::Test() {} + void SetUp() override { test_common::HSTestHelper::start_homestore( "test_index_btree", @@ -167,7 +120,7 @@ struct BtreeTest : public BtreeTestHelper< TestType > { } }; -using BtreeTypes = testing::Types< FixedLenBtreeTest, VarKeySizeBtreeTest, VarValueSizeBtreeTest, VarObjSizeBtreeTest >; +using BtreeTypes = testing::Types< FixedLenBtree, VarKeySizeBtree, VarValueSizeBtree, VarObjSizeBtree >; TYPED_TEST_SUITE(BtreeTest, BtreeTypes); @@ -456,7 +409,7 @@ TYPED_TEST(BtreeTest, ThreadedCpFlush) { } template < typename TestType > -struct BtreeConcurrentTest : public BtreeTestHelper< TestType > { +struct BtreeConcurrentTest : public BtreeTestHelper< TestType >, public ::testing::Test { using T = TestType; using K = typename TestType::KeyType; @@ -475,7 +428,7 @@ struct BtreeConcurrentTest : public BtreeTestHelper< TestType > { BtreeConcurrentTest* m_test; }; - BtreeConcurrentTest() { this->m_is_multi_threaded = true; } + BtreeConcurrentTest() : testing::Test() { this->m_is_multi_threaded = true; } void SetUp() override { test_common::HSTestHelper::start_homestore( @@ -513,35 +466,10 @@ TYPED_TEST_SUITE(BtreeConcurrentTest, BtreeTypes); TYPED_TEST(BtreeConcurrentTest, ConcurrentAllOps) { // range put is not supported for non-extent keys std::vector< std::string > input_ops = {"put:20", "remove:20", "range_put:20", "range_remove:20", "query:20"}; - std::vector< std::pair< std::string, int > > ops; if (SISL_OPTIONS.count("operation_list")) { input_ops = SISL_OPTIONS["operation_list"].as< std::vector< std::string > >(); } - int total = std::accumulate(input_ops.begin(), input_ops.end(), 0, [](int sum, const auto& str) { - std::vector< std::string > tokens; - boost::split(tokens, str, boost::is_any_of(":")); - if (tokens.size() == 2) { - try { - return sum + std::stoi(tokens[1]); - } catch (const std::exception&) { - // Invalid frequency, ignore this element - } - } - return sum; // Ignore malformed strings - }); - - std::transform(input_ops.begin(), input_ops.end(), std::back_inserter(ops), [total](const auto& str) { - std::vector< std::string > tokens; - boost::split(tokens, str, boost::is_any_of(":")); - if (tokens.size() == 2) { - try { - return std::make_pair(tokens[0], (int)(100.0 * std::stoi(tokens[1]) / total)); - } catch (const std::exception&) { - // Invalid frequency, ignore this element - } - } - return std::make_pair(std::string(), 0); - }); + auto ops = this->build_op_list(input_ops); this->multi_op_execute(ops); } diff --git a/src/tests/test_mem_btree.cpp b/src/tests/test_mem_btree.cpp index 94e78d53c..44995e360 100644 --- a/src/tests/test_mem_btree.cpp +++ b/src/tests/test_mem_btree.cpp @@ -22,12 +22,11 @@ #include #include +#include +#include "test_common/range_scheduler.hpp" #include #include #include -#include -#include "test_common/range_scheduler.hpp" -#include "btree_helpers/btree_test_kvs.hpp" #include "btree_helpers/btree_test_helper.hpp" using namespace homestore; @@ -92,11 +91,13 @@ struct PrefixIntervalBtreeTest { }; template < typename TestType > -struct BtreeTest : public BtreeTestHelper< TestType > { +struct BtreeTest : public BtreeTestHelper< TestType >, public ::testing::Test { using T = TestType; using K = typename TestType::KeyType; using V = typename TestType::ValueType; + BtreeTest() : testing::Test() {} + void SetUp() override { BtreeTestHelper< TestType >::SetUp(); this->m_bt = std::make_shared< typename T::BtreeType >(this->m_cfg); @@ -282,12 +283,12 @@ TYPED_TEST(BtreeTest, RandomRemoveRange) { } template < typename TestType > -struct BtreeConcurrentTest : public BtreeTestHelper< TestType > { +struct BtreeConcurrentTest : public BtreeTestHelper< TestType >, public ::testing::Test { using T = TestType; using K = typename TestType::KeyType; using V = typename TestType::ValueType; - BtreeConcurrentTest() { this->m_is_multi_threaded = true; } + BtreeConcurrentTest() : testing::Test() { this->m_is_multi_threaded = true; } void SetUp() override { LOGINFO("Starting iomgr with {} threads", SISL_OPTIONS["num_threads"].as< uint32_t >()); @@ -313,36 +314,10 @@ TYPED_TEST_SUITE(BtreeConcurrentTest, BtreeTypes); TYPED_TEST(BtreeConcurrentTest, ConcurrentAllOps) { // range put is not supported for non-extent keys std::vector< std::string > input_ops = {"put:20", "remove:20", "range_put:20", "range_remove:20", "query:20"}; - std::vector< std::pair< std::string, int > > ops; - if (SISL_OPTIONS.count("operation_list")) { input_ops = SISL_OPTIONS["operation_list"].as< std::vector< std::string > >(); } - int total = std::accumulate(input_ops.begin(), input_ops.end(), 0, [](int sum, const auto& str) { - std::vector< std::string > tokens; - boost::split(tokens, str, boost::is_any_of(":")); - if (tokens.size() == 2) { - try { - return sum + std::stoi(tokens[1]); - } catch (const std::exception&) { - // Invalid frequency, ignore this element - } - } - return sum; // Ignore malformed strings - }); - - std::transform(input_ops.begin(), input_ops.end(), std::back_inserter(ops), [total](const auto& str) { - std::vector< std::string > tokens; - boost::split(tokens, str, boost::is_any_of(":")); - if (tokens.size() == 2) { - try { - return std::make_pair(tokens[0], (int)(100.0 * std::stoi(tokens[1]) / total)); - } catch (const std::exception&) { - // Invalid frequency, ignore this element - } - } - return std::make_pair(std::string(), 0); - }); + auto ops = this->build_op_list(input_ops); this->multi_op_execute(ops); }