Also includes minor stylistic cleanups.
Signed-off-by: Samuel Just <sjust@redhat.com>
namespace crimson::os::seastore {
-enum class omap_root_state_t : uint8_t {
- INITIAL = 0,
- MUTATED = 1,
- NONE = 0xFF
-};
-
-struct omap_root_t {
- depth_t depth = 0;
- omap_root_state_t state;
- laddr_t omap_root_laddr;
- omap_root_t(depth_t dep, laddr_t laddr)
- : depth(dep),
- omap_root_laddr(laddr) { state = omap_root_state_t::INITIAL; }
-};
-
struct list_keys_result_t {
std::vector<std::string> keys;
std::optional<std::string> next; // if return std::nullopt, means list all keys in omap tree.
* @param Transaction &t, current transaction
* @param string &key, omap string key
* @param string &value, mapped value corresponding key
- * @retval mutation_result_t, status should be success.
*/
using omap_set_key_ertr = base_ertr;
- using omap_set_key_ret = omap_set_key_ertr::future<bool>;
+ using omap_set_key_ret = omap_set_key_ertr::future<>;
virtual omap_set_key_ret omap_set_key(omap_root_t &omap_root, Transaction &t,
const std::string &key, const std::string &value) = 0;
* @param omap_root_t &omap_root, omap btree root information
* @param Transaction &t, current transaction
* @param string &key, omap string key
- * @retval remove success return true, else return false.
*/
using omap_rm_key_ertr = base_ertr;
- using omap_rm_key_ret = omap_rm_key_ertr::future<bool>;
+ using omap_rm_key_ret = omap_rm_key_ertr::future<>;
virtual omap_rm_key_ret omap_rm_key(omap_root_t &omap_root, Transaction &t,
const std::string &key) = 0;
}
BtreeOMapManager::get_root_ret
-BtreeOMapManager::get_omap_root(const omap_root_t &omap_root, Transaction &t)
+BtreeOMapManager::get_omap_root(omap_context_t oc, const omap_root_t &omap_root)
{
- assert(omap_root.omap_root_laddr != L_ADDR_NULL);
- laddr_t laddr = omap_root.omap_root_laddr;
- return omap_load_extent(get_omap_context(t), laddr, omap_root.depth);
+ assert(omap_root.get_location() != L_ADDR_NULL);
+ laddr_t laddr = omap_root.get_location();
+ return omap_load_extent(oc, laddr, omap_root.get_depth());
}
BtreeOMapManager::handle_root_split_ret
-BtreeOMapManager::handle_root_split(omap_root_t &omap_root, omap_context_t oc,
- OMapNode::mutation_result_t mresult)
+BtreeOMapManager::handle_root_split(
+ omap_context_t oc,
+ omap_root_t &omap_root,
+ OMapNode::mutation_result_t mresult)
{
return oc.tm.alloc_extent<OMapInnerNode>(oc.t, L_ADDR_MIN, OMAP_BLOCK_SIZE)
- .safe_then([&omap_root, mresult](auto&& nroot) {
+ .safe_then([&omap_root, mresult](auto&& nroot) -> handle_root_split_ret {
auto [left, right, pivot] = *(mresult.split_tuple);
omap_node_meta_t meta{omap_root.depth + 1};
nroot->set_meta(meta);
"", nroot->maybe_get_delta_buffer());
nroot->journal_inner_insert(nroot->iter_begin() + 1, right->get_laddr(),
pivot, nroot->maybe_get_delta_buffer());
- omap_root.omap_root_laddr = nroot->get_laddr();
- omap_root.depth += 1;
- omap_root.state = omap_root_state_t::MUTATED;
- return handle_root_split_ertr::make_ready_future<bool>(true);
+ omap_root.update(nroot->get_laddr(), omap_root.depth += 1);
+ return seastar::now();
});
}
BtreeOMapManager::handle_root_merge_ret
-BtreeOMapManager::handle_root_merge(omap_root_t &omap_root, omap_context_t oc,
- OMapNode::mutation_result_t mresult)
+BtreeOMapManager::handle_root_merge(
+ omap_context_t oc,
+ omap_root_t &omap_root,
+ OMapNode::mutation_result_t mresult)
{
auto root = *(mresult.need_merge);
auto iter = root->cast<OMapInnerNode>()->iter_begin();
- omap_root.omap_root_laddr = iter->get_node_key().laddr;
- omap_root.depth -= 1;
- omap_root.state = omap_root_state_t::MUTATED;
+ omap_root.update(
+ iter->get_node_key().laddr,
+ omap_root.depth -= 1);
return oc.tm.dec_ref(oc.t, root->get_laddr()
- ).safe_then([] (auto &&ret) {
- return handle_root_merge_ertr::make_ready_future<bool>(true);
+ ).safe_then([](auto &&ret) -> handle_root_merge_ret {
+ return seastar::now();
}).handle_error(
handle_root_merge_ertr::pass_further{},
crimson::ct_error::assert_all{
);
}
-
BtreeOMapManager::omap_get_value_ret
BtreeOMapManager::omap_get_value(const omap_root_t &omap_root, Transaction &t,
const std::string &key)
{
logger().debug("{}: {}", __func__, key);
- return get_omap_root(omap_root, t).safe_then([this, &t, &key](auto&& extent) {
+ return get_omap_root(
+ get_omap_context(t),
+ omap_root
+ ).safe_then([this, &t, &key](auto&& extent) {
return extent->get_value(get_omap_context(t), key);
}).safe_then([](auto &&e) {
logger().debug("{}: {} -> {}", __func__, e.first, e.second);
const std::string &key, const std::string &value)
{
logger().debug("{}: {} -> {}", __func__, key, value);
- return get_omap_root(omap_root, t).safe_then([this, &t, &key, &value](auto root) {
+ return get_omap_root(
+ get_omap_context(t),
+ omap_root
+ ).safe_then([this, &t, &key, &value](auto root) {
return root->insert(get_omap_context(t), key, value);
- }).safe_then([this, &omap_root, &t](auto mresult) {
+ }).safe_then([this, &omap_root, &t](auto mresult) -> omap_set_key_ret {
if (mresult.status == mutation_status_t::SUCCESS)
- return omap_set_key_ertr::make_ready_future<bool>(true);
+ return seastar::now();
else if (mresult.status == mutation_status_t::WAS_SPLIT)
- return handle_root_split(omap_root, get_omap_context(t), mresult);
+ return handle_root_split(get_omap_context(t), omap_root, mresult);
else
- return omap_set_key_ertr::make_ready_future<bool>(false);
+ return seastar::now();
});
}
BtreeOMapManager::omap_rm_key(omap_root_t &omap_root, Transaction &t, const std::string &key)
{
logger().debug("{}: {}", __func__, key);
- return get_omap_root(omap_root, t).safe_then([this, &t, &key](auto root) {
+ return get_omap_root(
+ get_omap_context(t),
+ omap_root
+ ).safe_then([this, &t, &key](auto root) {
return root->rm_key(get_omap_context(t), key);
- }).safe_then([this, &omap_root, &t](auto mresult) {
- if (mresult.status == mutation_status_t::SUCCESS)
- return omap_rm_key_ertr::make_ready_future<bool>(true);
- else if (mresult.status == mutation_status_t::WAS_SPLIT)
- return handle_root_split(omap_root, get_omap_context(t), mresult);
- else if (mresult.status == mutation_status_t::NEED_MERGE) {
+ }).safe_then([this, &omap_root, &t](auto mresult) -> omap_rm_key_ret {
+ if (mresult.status == mutation_status_t::SUCCESS) {
+ return seastar::now();
+ } else if (mresult.status == mutation_status_t::WAS_SPLIT) {
+ return handle_root_split(get_omap_context(t), omap_root, mresult);
+ } else if (mresult.status == mutation_status_t::NEED_MERGE) {
auto root = *(mresult.need_merge);
- if (root->get_node_size() == 1 && omap_root.depth != 1)
- return handle_root_merge(omap_root, get_omap_context(t), mresult);
- else
- return omap_rm_key_ertr::make_ready_future<bool>(true);
+ if (root->get_node_size() == 1 && omap_root.depth != 1) {
+ return handle_root_merge(get_omap_context(t), omap_root, mresult);
+ } else {
+ return seastar::now();
+ }
+ } else {
+ return seastar::now();
}
- else
- return omap_rm_key_ertr::make_ready_future<bool>(false);
});
}
std::string &start, size_t max_result_size)
{
logger().debug("{}", __func__);
- return get_omap_root(omap_root, t).safe_then([this, &t, &start,
+ return get_omap_root(
+ get_omap_context(t),
+ omap_root
+ ).safe_then([this, &t, &start,
max_result_size] (auto extent) {
return extent->list_keys(get_omap_context(t), start, max_result_size)
.safe_then([](auto &&result) {
std::string &start, size_t max_result_size)
{
logger().debug("{}", __func__);
- return get_omap_root(omap_root, t).safe_then([this, &t, &start, max_result_size]
+ return get_omap_root(
+ get_omap_context(t),
+ omap_root
+ ).safe_then([this, &t, &start, max_result_size]
(auto extent) {
return extent->list(get_omap_context(t), start, max_result_size)
.safe_then([](auto &&result) {
BtreeOMapManager::omap_clear(omap_root_t &omap_root, Transaction &t)
{
logger().debug("{}", __func__);
- return get_omap_root(omap_root, t).safe_then([this, &t](auto extent) {
+ return get_omap_root(
+ get_omap_context(t),
+ omap_root
+ ).safe_then([this, &t](auto extent) {
return extent->clear(get_omap_context(t));
}).safe_then([this, &omap_root, &t] {
- return tm.dec_ref(t, omap_root.omap_root_laddr).safe_then([&omap_root] (auto ret) {
- omap_root.state = omap_root_state_t::MUTATED;
- omap_root.depth = 0;
- omap_root.omap_root_laddr = L_ADDR_NULL;
+ return tm.dec_ref(
+ t, omap_root.get_location()
+ ).safe_then([&omap_root] (auto ret) {
+ omap_root.update(
+ L_ADDR_NULL,
+ 0);
return omap_clear_ertr::now();
});
}).handle_error(
class BtreeOMapManager : public OMapManager {
TransactionManager &tm;
- omap_context_t get_omap_context(Transaction &t) {
+ omap_context_t get_omap_context(
+ Transaction &t) {
return omap_context_t{tm, t};
}
*/
using get_root_ertr = base_ertr;
using get_root_ret = get_root_ertr::future<OMapNodeRef>;
- get_root_ret get_omap_root(const omap_root_t &omap_root, Transaction &t);
+ get_root_ret get_omap_root(
+ omap_context_t c,
+ const omap_root_t &omap_root);
/* handle_root_split
*
- * root has been splitted and need update omap_root_t
+ * root has been split and needs to update omap_root_t
*/
using handle_root_split_ertr = base_ertr;
- using handle_root_split_ret = handle_root_split_ertr::future<bool>;
- handle_root_split_ret handle_root_split(omap_root_t &omap_root, omap_context_t oc,
- OMapNode:: mutation_result_t mresult);
+ using handle_root_split_ret = handle_root_split_ertr::future<>;
+ handle_root_split_ret handle_root_split(
+ omap_context_t c,
+ omap_root_t &omap_root,
+ OMapNode::mutation_result_t mresult);
/* handle_root_merge
*
* root node has only one item and it is not leaf node, need remove a layer
*/
using handle_root_merge_ertr = base_ertr;
- using handle_root_merge_ret = handle_root_merge_ertr::future<bool>;
- handle_root_merge_ret handle_root_merge(omap_root_t &omap_root, omap_context_t oc,
- OMapNode:: mutation_result_t mresult);
+ using handle_root_merge_ret = handle_root_merge_ertr::future<>;
+ handle_root_merge_ret handle_root_merge(
+ omap_context_t oc,
+ omap_root_t &omap_root,
+ OMapNode:: mutation_result_t mresult);
public:
explicit BtreeOMapManager(TransactionManager &tm);
std::vector<delta_info_t> deltas;
};
+struct omap_root_t {
+ laddr_t addr = L_ADDR_NULL;
+ depth_t depth = 0;
+ bool mutated = false;
+
+ omap_root_t(laddr_t addr, depth_t depth)
+ : addr(addr),
+ depth(depth) {}
+
+ omap_root_t(const omap_root_t &o) = default;
+ omap_root_t(omap_root_t &&o) = default;
+ omap_root_t &operator=(const omap_root_t &o) = default;
+ omap_root_t &operator=(omap_root_t &&o) = default;
+
+ bool is_null() const {
+ return addr == L_ADDR_NULL;
+ }
+
+ bool must_update() const {
+ return mutated;
+ }
+
+ void update(laddr_t _addr, depth_t _depth) {
+ mutated = true;
+ addr = _addr;
+ depth = _depth;
+ }
+
+ laddr_t get_location() const {
+ return addr;
+ }
+
+ depth_t get_depth() const {
+ return depth;
+ }
+};
+
+class __attribute__((packed)) omap_root_le_t {
+ laddr_le_t addr = laddr_le_t(L_ADDR_NULL);
+ depth_le_t depth = init_depth_le(0);
+
+public:
+ omap_root_le_t() = default;
+
+ omap_root_le_t(laddr_t addr, depth_t depth)
+ : addr(addr), depth(init_depth_le(depth)) {}
+
+ omap_root_le_t(const omap_root_le_t &o) = default;
+ omap_root_le_t(omap_root_le_t &&o) = default;
+ omap_root_le_t &operator=(const omap_root_le_t &o) = default;
+ omap_root_le_t &operator=(omap_root_le_t &&o) = default;
+
+ void update(const omap_root_t &nroot) {
+ addr = nroot.get_location();
+ depth = init_depth_le(nroot.get_depth());
+ }
+
+ omap_root_t get() const {
+ return omap_root_t(addr, depth);
+ }
+};
+
/**
* lba_root_t
*/
using test_omap_t = std::map<std::string, std::string>;
test_omap_t test_omap_mappings;
- bool set_key(
+ void set_key(
omap_root_t &omap_root,
Transaction &t,
string &key,
string &val) {
- auto ret = omap_manager->omap_set_key(omap_root, t, key, val).unsafe_get0();
- EXPECT_EQ(ret, true);
+ omap_manager->omap_set_key(omap_root, t, key, val).unsafe_get0();
test_omap_mappings[key] = val;
- return ret;
}
std::pair<string, string> get_value(
return ret;
}
- bool rm_key(
+ void rm_key(
omap_root_t &omap_root,
Transaction &t,
const string &key) {
- auto ret = omap_manager->omap_rm_key(omap_root, t, key).unsafe_get0();
- EXPECT_EQ(ret, true);
+ omap_manager->omap_rm_key(omap_root, t, key).unsafe_get0();
test_omap_mappings.erase(test_omap_mappings.find(key));
- return ret;
}
list_keys_result_t list_keys(
omap_root_t &omap_root,
Transaction &t) {
omap_manager->omap_clear(omap_root, t).unsafe_get0();
- EXPECT_EQ(omap_root.omap_root_laddr, L_ADDR_NULL);
+ EXPECT_EQ(omap_root.get_location(), L_ADDR_NULL);
}
void check_mappings(omap_root_t &omap_root, Transaction &t) {
TEST_F(omap_manager_test_t, basic)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
{
auto t = tm->create_transaction();
logger().debug("first transaction");
- [[maybe_unused]] auto setret = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
[[maybe_unused]] auto getret = get_value(omap_root, *t, key);
tm->submit_transaction(std::move(t)).unsafe_get();
}
auto t = tm->create_transaction();
logger().debug("second transaction");
[[maybe_unused]] auto getret = get_value(omap_root, *t, key);
- [[maybe_unused]] auto rmret = rm_key(omap_root, *t, key);
+ rm_key(omap_root, *t, key);
[[maybe_unused]] auto getret2 = get_value(omap_root, *t, key);
EXPECT_EQ(getret2.second, "");
tm->submit_transaction(std::move(t)).unsafe_get();
TEST_F(omap_manager_test_t, force_leafnode_split)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
for (unsigned j = 0; j < 10; ++j) {
string key(rand_string(str, rand() % STR_LEN));
string val(rand_string(str, rand() % STR_LEN));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
if ((i % 20 == 0) && (j == 5)) {
check_mappings(omap_root, *t);
}
TEST_F(omap_manager_test_t, force_leafnode_split_merge)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
for (unsigned j = 0; j < 5; ++j) {
string key(rand_string(str, rand() % STR_LEN));
string val(rand_string(str, rand() % STR_LEN));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
if ((i % 10 == 0) && (j == 3)) {
check_mappings(omap_root, *t);
}
int i = 0;
for (auto &e: test_omap_mappings) {
if (i % 3 != 0) {
- [[maybe_unused]] auto rmref= rm_key(omap_root, *t, e.first);
+ rm_key(omap_root, *t, e.first);
}
if (i % 10 == 0) {
TEST_F(omap_manager_test_t, force_leafnode_split_merge_fullandbalanced)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
for (unsigned j = 0; j < 5; ++j) {
string key(rand_string(str, rand() % STR_LEN));
string val(rand_string(str, rand() % STR_LEN));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
if ((i % 10 == 0) && (j == 3)) {
check_mappings(omap_root, *t);
}
for (auto &e: test_omap_mappings) {
if (30 < i && i < 100) {
auto val = e;
- [[maybe_unused]] auto rmref= rm_key(omap_root, *t, e.first);
+ rm_key(omap_root, *t, e.first);
}
if (i % 10 == 0) {
TEST_F(omap_manager_test_t, force_split_listkeys_list_clear)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
for (unsigned j = 0; j < 10; ++j) {
string key(rand_string(str, rand() % STR_LEN));
string val(rand_string(str, rand() % STR_LEN));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
if (i == 10)
temp = key;
if ((i % 20 == 0) && (j == 5)) {
TEST_F(omap_manager_test_t, internal_force_split)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
for (unsigned j = 0; j < 80; ++j) {
string key(rand_string(str, rand() % STR_LEN));
string val(rand_string(str, rand() % STR_LEN));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
if ((i % 2 == 0) && (j % 50 == 0)) {
check_mappings(omap_root, *t);
}
TEST_F(omap_manager_test_t, internal_force_merge_fullandbalanced)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
for (unsigned j = 0; j < 80; ++j) {
string key(rand_string(str, rand() % STR_LEN));
string val(rand_string(str, rand() % STR_LEN));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
if ((i % 2 == 0) && (j % 50 == 0)) {
check_mappings(omap_root, *t);
}
int i = 0;
for (auto &e: test_omap_mappings) {
auto val = e;
- [[maybe_unused]] auto rmref= rm_key(omap_root, *t, e.first);
+ rm_key(omap_root, *t, e.first);
if (i % 10 == 0) {
logger().debug("submitting transaction i= {}", i);
TEST_F(omap_manager_test_t, replay)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
for (unsigned j = 0; j < 80; ++j) {
string key(rand_string(str, rand() % STR_LEN));
string val(rand_string(str, rand() % STR_LEN));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
if ((i % 2 == 0) && (j % 50 == 0)) {
check_mappings(omap_root, *t);
}
int i = 0;
for (auto &e: test_omap_mappings) {
auto val = e;
- [[maybe_unused]] auto rmref= rm_key(omap_root, *t, e.first);
+ rm_key(omap_root, *t, e.first);
if (i % 10 == 0) {
logger().debug("submitting transaction i= {}", i);
TEST_F(omap_manager_test_t, internal_force_split_to_root)
{
run_async([this] {
- omap_root_t omap_root(0, L_ADDR_NULL);
+ omap_root_t omap_root(L_ADDR_NULL, 0);
{
auto t = tm->create_transaction();
omap_root = omap_manager->initialize_omap(*t).unsafe_get0();
for (unsigned j = 0; j < 8; ++j) {
string key(rand_string(str, STR_LEN));
string val(rand_string(str, STR_LEN));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
}
logger().debug("submitting transaction i = {}", i);
tm->submit_transaction(std::move(t)).unsafe_get();
for (unsigned j = 0; j < 8; ++j) {
string key(rand_string(str_2, STR_LEN_2));
string val(rand_string(str_2, STR_LEN_2));
- [[maybe_unused]] auto addref = set_key(omap_root, *t, key, val);
+ set_key(omap_root, *t, key, val);
}
logger().debug("submitting transaction last");
tm->submit_transaction(std::move(t)).unsafe_get();