using future = ertr::future<ValueT>;
TreeBuilder(KVPool& kvs, NodeExtentManagerURef&& nm)
- : kvs{kvs}, ref_t{make_transaction()}, t{*ref_t}, tree{std::move(nm)} {}
+ : kvs{kvs}, tree{std::move(nm)} {}
- future<> bootstrap() {
+ future<> bootstrap(Transaction& t) {
return tree.mkfs(t);
}
- future<> run() {
+ future<> insert(Transaction& t) {
std::ostringstream oss;
#ifndef NDEBUG
oss << "debug on, ";
oss << "track off";
}
kv_iter = kvs.random_begin();
+ auto cursors = seastar::make_lw_shared<std::vector<Btree::Cursor>>();
logger().warn("start inserting {} kvs ({}) ...", kvs.size(), oss.str());
auto start_time = mono_clock::now();
- return crimson::do_until([this]() -> future<bool> {
+ return crimson::do_until([&t, this, cursors]() -> future<bool> {
if (kv_iter.is_end()) {
return ertr::make_ready_future<bool>(true);
}
auto [key, p_value] = kv_iter.get_kv();
logger().debug("[{}] {} -> {}", kv_iter.index(), key_hobj_t{key}, *p_value);
- return tree.insert(t, key, *p_value).safe_then([this](auto ret) {
+ return tree.insert(t, key, *p_value
+ ).safe_then([&t, this, cursors](auto ret) {
auto& [cursor, success] = ret;
assert(success == true);
if constexpr (TRACK) {
- cursors.emplace_back(cursor);
+ cursors->emplace_back(cursor);
}
#ifndef NDEBUG
auto [key, p_value] = kv_iter.get_kv();
return ertr::make_ready_future<bool>(false);
#endif
});
- }).safe_then([this, start_time] {
+ }).safe_then([&t, this, start_time, cursors] {
std::chrono::duration<double> duration = mono_clock::now() - start_time;
logger().warn("Insert done! {}s", duration.count());
- return tree.get_stats_slow(t);
- }).safe_then([this](auto stats) {
- logger().warn("{}", stats);
- if (!cursors.empty()) {
+ if (!cursors->empty()) {
logger().info("Verifing tracked cursors ...");
kv_iter = kvs.random_begin();
return seastar::do_with(
- cursors.begin(), [this](auto& c_iter) {
- return crimson::do_until([this, &c_iter]() -> future<bool> {
+ cursors->begin(), [&t, this, cursors](auto& c_iter) {
+ return crimson::do_until([&t, this, &c_iter, cursors]() -> future<bool> {
if (kv_iter.is_end()) {
logger().info("Verify done!");
return ertr::make_ready_future<bool>(true);
}
- assert(c_iter != cursors.end());
+ assert(c_iter != cursors->end());
auto [k, v] = kv_iter.get_kv();
// validate values in tree keep intact
return tree.lower_bound(t, k).safe_then([this, &c_iter](auto cursor) {
});
}
+ future<> get_stats(Transaction& t) {
+ return tree.get_stats_slow(t
+ ).safe_then([this](auto stats) {
+ logger().warn("{}", stats);
+ });
+ }
+
private:
static seastar::logger& logger() {
return crimson::get_logger(ceph_subsys_filestore);
}
KVPool& kvs;
- TransactionRef ref_t;
- Transaction& t;
Btree tree;
KVPool::iterator_t kv_iter;
- std::vector<Btree::Cursor> cursors;
};
}
});
}
-struct d_seastore_tree_test_t :
+struct d_seastore_tm_test_t :
public seastar_test_suite_t, TMTestState {
- KVPool kvs;
- std::unique_ptr<TreeBuilder<true>> tree;
-
- d_seastore_tree_test_t()
- : kvs{{8, 11, 64, 256, 301, 320},
- {8, 16, 128, 512, 576, 640},
- {0, 32}, {0, 10}, {0, 4}} {}
-
seastar::future<> set_up_fut() override final {
- return tm_setup().then([this] {
- tree = std::make_unique<TreeBuilder<true>>(kvs,
-#if 0
- NodeExtentManager::create_dummy(IS_DUMMY_SYNC)
-#else
- NodeExtentManager::create_seastore(*tm)
-#endif
- );
- return tree->bootstrap();
- }).handle_error(
- crimson::ct_error::all_same_way([] {
- ASSERT_FALSE("Unable to initiate tree");
- })
- );
+ return tm_setup();
}
-
seastar::future<> tear_down_fut() override final {
- tree.reset();
return tm_teardown();
}
};
-TEST_F(d_seastore_tree_test_t, 6_random_insert_leaf_node)
+TEST_F(d_seastore_tm_test_t, 6_random_insert_leaf_node)
{
- run([this] {
- return tree->run().handle_error(
- crimson::ct_error::all_same_way([] {
- ASSERT_FALSE("Test failed");
- })
+ run_async([this] {
+ constexpr bool TRACK_CURSORS = true;
+ KVPool kvs{{8, 11, 64, 256, 301, 320},
+ {8, 16, 128, 512, 576, 640},
+ {0, 32}, {0, 10}, {0, 4}};
+ auto tree = std::make_unique<TreeBuilder<TRACK_CURSORS>>(kvs,
+#if 0
+ NodeExtentManager::create_dummy(IS_DUMMY_SYNC)
+#else
+ NodeExtentManager::create_seastore(*tm)
+#endif
);
+ {
+ auto t = tm->create_transaction();
+ tree->bootstrap(*t).unsafe_get();
+ tm->submit_transaction(std::move(t)).unsafe_get();
+ }
+ {
+ auto t = tm->create_transaction();
+ tree->insert(*t).unsafe_get();
+ tm->submit_transaction(std::move(t)).unsafe_get();
+ }
+ {
+ auto t = tm->create_transaction();
+ tree->get_stats(*t).unsafe_get();
+ tm->submit_transaction(std::move(t)).unsafe_get();
+ }
+ tree.reset();
});
}
PerfTree(bool is_dummy) : is_dummy{is_dummy} {}
seastar::future<> run(KVPool& kvs) {
- return start(kvs).then([this] {
- return tree->run().handle_error(
- crimson::ct_error::all_same_way([] {
- ceph_abort("runtime error");
- })
- );
+ return tm_setup().then([this, &kvs] {
+ return seastar::async([this, &kvs] {
+ auto tree = std::make_unique<TreeBuilder<TRACK>>(kvs,
+ (is_dummy ? NodeExtentManager::create_dummy(true)
+ : NodeExtentManager::create_seastore(*tm)));
+ {
+ auto t = tm->create_transaction();
+ tree->bootstrap(*t).unsafe_get();
+ tm->submit_transaction(std::move(t)).unsafe_get();
+ }
+ {
+ auto t = tm->create_transaction();
+ tree->insert(*t).unsafe_get();
+ tm->submit_transaction(std::move(t)).unsafe_get();
+ }
+ {
+ auto t = tm->create_transaction();
+ tree->get_stats(*t).unsafe_get();
+ tm->submit_transaction(std::move(t)).unsafe_get();
+ }
+ tree.reset();
+ });
}).then([this] {
- return stop();
+ return tm_teardown();
});
}
private:
- seastar::future<> start(KVPool& kvs) {
- if (is_dummy) {
- tree = std::make_unique<TreeBuilder<TRACK>>(
- kvs, NodeExtentManager::create_dummy(true));
- return tree->bootstrap().handle_error(
- crimson::ct_error::all_same_way([] {
- ceph_abort("Unable to mkfs");
- })
- );
- } else {
- return tm_setup().then([this, &kvs] {
- tree = std::make_unique<TreeBuilder<TRACK>>(
- kvs, NodeExtentManager::create_seastore(*tm));
- return tree->bootstrap();
- }).handle_error(
- crimson::ct_error::all_same_way([] {
- ceph_abort("Unable to mkfs");
- })
- );
- }
- }
-
- seastar::future<> stop() {
- tree.reset();
- if (is_dummy) {
- return seastar::now();
- } else {
- return tm_teardown();
- }
- }
-
bool is_dummy;
- std::unique_ptr<TreeBuilder<TRACK>> tree;
};
template <bool TRACK>
seastar::future<> run(const bpo::variables_map& config) {
- return seastar::async([&config]{
+ return seastar::async([&config] {
auto backend = config["backend"].as<std::string>();
bool is_dummy;
if (backend == "dummy") {