Skip to content

Commit

Permalink
fix: add new if display for debug
Browse files Browse the repository at this point in the history
  • Loading branch information
thawk105 committed Mar 11, 2024
1 parent 6d52765 commit d94bc9f
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 0 deletions.
161 changes: 161 additions & 0 deletions include/interface_display.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/**
* @file interface_display.h
*/

#pragma once

#include <sstream>

#include "border_node.h"
#include "interior_node.h"
#include "kvs.h"
#include "log.h"
#include "permutation.h"
#include "tree_instance.h"
#include "value.h"

#include "glog/logging.h"

namespace yakushima {

// forward declaration
static void display_node(std::stringstream& ss, base_node* n,
std::string key_prefix);

static void display_border(std::stringstream& ss, border_node* n,
std::string key_prefix) {

Check warning on line 26 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

performance-unnecessary-value-param

the parameter 'key_prefix' is copied for each invocation but only used as a const reference; consider making it a const reference
ss << "border node, " << n << "\n";
ss << "version_ptr " << n->get_version_ptr() << "\n";
ss << "((key,key_len),value):";
permutation perm{n->get_permutation().get_body()};
for (std::size_t i = 0; i < perm.get_cnk(); ++i) {
std::size_t index = perm.get_index_of_rank(i);
value* value_ptr{n->get_lv_at(index)->get_value()};
key_slice_type ks = n->get_key_slice_at(index);
key_length_type kl = n->get_key_length_at(index);
std::string key{""};

Check warning on line 36 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

readability-redundant-string-init

redundant string initialization
if (kl > 0) {
if (kl > sizeof(key_slice_type)) {
key = std::string(reinterpret_cast<char*>(&ks), sizeof(key_slice_type)); // NOLINT
} else {
key = std::string(reinterpret_cast<char*>(&ks), kl); // NOLINT
}
}
ss << "((" << key_prefix + key << ","
<< std::to_string(n->get_key_length_at(index) + key_prefix.size()) << "),";
if (kl > sizeof(key_slice_type)) {
ss << n->get_lv_at(index)->get_next_layer();
} else {
std::string value_str{""};

Check warning on line 49 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

readability-redundant-string-init

redundant string initialization
void* val_ptr = value::get_body(value_ptr);
auto val_len = value::get_len(value_ptr);
if (val_len <= sizeof(void*)) { // inline opt
if (val_len > 0) {
value_str = std::string(val_len, '0');
memcpy(value_str.data(), val_ptr, val_len);
}
} else { // not inline opt len > sizeof(void*)
value_str = std::string(reinterpret_cast<char*>(val_ptr),val_len);

Check warning on line 58 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

cppcoreguidelines-pro-type-reinterpret-cast

do not use reinterpret_cast
}
ss << value_str;
}
ss << "), ";
}
ss << "\n";

for (std::size_t i = 0; i < perm.get_cnk(); ++i) {
std::size_t index = perm.get_index_of_rank(i);
link_or_value* lv = n->get_lv_at(index);
base_node* next_layer = lv->get_next_layer();
if (n->get_key_length_at(index) > sizeof(key_slice_type)) {
key_slice_type ks = n->get_key_slice_at(index);
key_length_type kl = n->get_key_length_at(index);
std::string key{""};

Check warning on line 73 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

readability-redundant-string-init

redundant string initialization
if (kl > 0) {
if (kl > sizeof(key_slice_type)) {
key = std::string(reinterpret_cast<char*>(&ks), sizeof(key_slice_type)); // NOLINT
} else {
key = std::string(reinterpret_cast<char*>(&ks), kl); // NOLINT
}
}
display_node(ss, next_layer, key_prefix + key);
}
}
}

static void display_interior(std::stringstream& ss,
interior_node* n,
std::string key_prefix) {

Check warning on line 88 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

performance-unnecessary-value-param

the parameter 'key_prefix' is copied for each invocation but only used as a const reference; consider making it a const reference
ss << "interior node, " << n << "\n";
ss << "version_ptr " << n->get_version_ptr() << "\n";
for (std::size_t i = 0; i < n->get_n_keys(); ++i) {
key_slice_type ks = n->get_key_slice_at(i);
key_length_type kl = n->get_key_length_at(i);
std::string key{""};

Check warning on line 94 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

readability-redundant-string-init

redundant string initialization
if (kl > 0) {
key = std::string(reinterpret_cast<char*>(&ks), kl); // NOLINT
}
ss << n->get_child_at(i) << "," << key_prefix + key << ",";
}
ss << n->get_child_at(n->get_n_keys()) << "\n";
for (std::size_t i = 0; i <= n->get_n_keys(); ++i) {
display_node(ss, n->get_child_at(i), key_prefix);
}
}

static void display_node(std::stringstream& ss, base_node* n,
std::string key_prefix) {

Check warning on line 107 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

performance-unnecessary-value-param

the parameter 'key_prefix' is copied for each invocation but only used as a const reference; consider making it a const reference
auto* ver = n->get_version_ptr();
auto verb = ver->get_stable_version();
if (verb.get_border()) {
display_border(ss, dynamic_cast<border_node*>(n), key_prefix);
} else {
display_interior(ss, dynamic_cast<interior_node*>(n), key_prefix);
}
}

static void display_tree_instance(std::stringstream& ss, tree_instance* ti) {
auto* n = ti->load_root_ptr();
if (n == nullptr) {
ss << "null\n";
return;
}
display_node(ss, n, "");
}

// begin - forward declaration
[[maybe_unused]] static status list_storages(
std::vector<std::pair<std::string, tree_instance*>>& out); // NOLINT
// end - forward declaration

[[maybe_unused]] static void display_body() {
std::vector<std::pair<std::string, tree_instance*>> st_list{};

auto rc = list_storages(st_list);

if (rc != status::OK) { return; }
std::stringstream ss;
ss << log_location_prefix
<< "display() start. \nlist storages(key,tree_instance*): ";
for (auto&& elem : st_list) {
ss << "(" << elem.first << "," << elem.second << "), ";
}
ss << "\n";


for (auto&& elem : st_list) {
ss << "about (" << elem.first << "," << elem.second << ")\n";
display_tree_instance(ss, elem.second);
}

LOG(INFO) << ss.str();
return;

Check warning on line 152 in include/interface_display.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

readability-redundant-control-flow

redundant return statement at the end of a function with a void return type
}

[[maybe_unused]] static void display() {
yakushima_log_entry << "display";
display_body();
yakushima_log_exit << "display";
}

} // namespace yakushima
6 changes: 6 additions & 0 deletions include/kvs.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <tuple>

#include "base_node.h"
#include "interface_display.h"
#include "interface_destroy.h"
#include "interface_get.h"
#include "interface_helper.h"
Expand All @@ -30,6 +31,11 @@ namespace yakushima {
*/
[[maybe_unused]] static void fin(); // NOLINT

/**
* @brief Display tree information. This is not thread safe.
*/
[[maybe_unused]] static void display(); // NOLINT

/**
* @brief release all heap objects and clean up.
* @pre This function is called by single thread.
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ else ()
"get/*.cpp"
"scan/*.cpp"
"delete/*.cpp"
"display/*.cpp"
"delete_get_put_scan/*.cpp"
"delete_put/*.cpp"
"tsurugi_issue/*.cpp"
Expand Down
94 changes: 94 additions & 0 deletions test/display/display_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* @file scan_basic_usage_test.cpp
*/

#include <array>
#include <mutex>

#include "kvs.h"

// yakushima/test/include
#include "test_tool.h"

#include "glog/logging.h"
#include "gtest/gtest.h"

using namespace yakushima;

namespace yakushima::testing {

class display_test : public ::testing::Test {
public:
static void call_once_f() {
google::InitGoogleLogging("yakushima-test-display-display_test");
// FLAGS_stderrthreshold = 0;
}

void SetUp() override { init(); }

void TearDown() override { fin(); }

private:
static inline std::once_flag init_; // NOLINT
};

TEST_F(display_test, simple) { // NOLINT
// prepare
// create storage
std::string st1{"test1"};
ASSERT_OK(create_storage(st1));
std::string st2{"test2"};
ASSERT_OK(create_storage(st2));
std::string st3{"test3"};
ASSERT_OK(create_storage(st3));
std::string st4{"test4"};
ASSERT_OK(create_storage(st4));
Token t{};
ASSERT_OK(enter(t));

// put key value
std::string k("k1");
std::string v{"v1"};
yakushima::node_version64* nvp_for_put{};
char* tmp_created_value_ptr{};

// test1: 1 border 1 entry
ASSERT_OK(put(t, st1, k, v.data(), v.size(), &tmp_created_value_ptr,
static_cast<value_align_type>(alignof(char)), true,
&nvp_for_put));

// test2: 1 border 2 entry
k = "k2";
v = "v2"; // inline opt
ASSERT_OK(put(t, st2, k, v.data(), v.size(), &tmp_created_value_ptr,
static_cast<value_align_type>(alignof(char)), true,
&nvp_for_put));
k = "k3";
v = "123456789"; // not inline opt
ASSERT_OK(put(t, st2, k, v.data(), v.size(), &tmp_created_value_ptr,
static_cast<value_align_type>(alignof(char)), true,
&nvp_for_put));

// test3: multi layer 2 border
k = "12345678a";
v = "v";
ASSERT_OK(put(t, st3, k, v.data(), v.size(), &tmp_created_value_ptr,
static_cast<value_align_type>(alignof(char)), true,
&nvp_for_put));

// test4: 1 interior 2 border
for (std::size_t i = 0; i < 20; ++i) {
k = std::to_string(i);
ASSERT_OK(put(t, st4, k, v.data(), v.size(), &tmp_created_value_ptr,
static_cast<value_align_type>(alignof(char)), true,
&nvp_for_put));
}

// test
display();

// cleanup
ASSERT_OK(leave(t));
}

} // namespace yakushima::testing

0 comments on commit d94bc9f

Please sign in to comment.