36 std::vector<LEAF_CONTAINER> leaf_container_vec;
37 std::vector<Node *> parent_vec;
38 std::stack<uint64_t> unused_leaf_container_indexes;
39 std::vector<Node *> unused_node_pointers;
40 std::vector<NodePointer> tmp_path;
47 BPTree *linked_tree_ =
nullptr;
48 double density_threshold = 0.5;
49 uint64_t density1 = 0;
51 bool root_is_leaf_ =
false;
53 uint64_t split_process_counter = 0;
54 uint64_t insert_operation_counter = 0;
55 uint64_t merge_process_counter = 0;
56 uint64_t remove_operation_counter = 0;
70 this->leaf_container_vec = std::move(other.leaf_container_vec);
71 this->parent_vec = std::move(other.parent_vec);
72 this->unused_leaf_container_indexes = std::move(other.unused_leaf_container_indexes);
73 this->unused_node_pointers = std::move(other.unused_node_pointers);
74 this->tmp_path = std::move(other.tmp_path);
78 this->root = other.root;
79 this->linked_tree_ = other.linked_tree_;
80 this->density_threshold = other.density_threshold;
81 this->density1 = other.density1;
82 this->height_ = other.height_;
83 this->root_is_leaf_ = other.root_is_leaf_;
85 other.leaf_container_vec.clear();
86 other.parent_vec.clear();
87 other.unused_node_pointers.clear();
88 other.tmp_path.clear();
89 while (other.unused_leaf_container_indexes.size() > 0)
91 other.unused_leaf_container_indexes.pop();
95 other.linked_tree_ =
nullptr;
97 other.root_is_leaf_ =
false;
105 this->leaf_container_vec = std::move(other.leaf_container_vec);
106 this->parent_vec = std::move(other.parent_vec);
107 this->unused_leaf_container_indexes = std::move(other.unused_leaf_container_indexes);
108 this->unused_node_pointers = std::move(other.unused_node_pointers);
109 this->tmp_path = std::move(other.tmp_path);
113 this->root = other.root;
114 this->linked_tree_ = other.linked_tree_;
115 this->density_threshold = other.density_threshold;
116 this->density1 = other.density1;
117 this->height_ = other.height_;
118 this->root_is_leaf_ = other.root_is_leaf_;
120 other.leaf_container_vec.clear();
121 other.parent_vec.clear();
122 other.unused_node_pointers.clear();
123 other.tmp_path.clear();
124 while (other.unused_leaf_container_indexes.size() > 0)
126 other.unused_leaf_container_indexes.pop();
129 other.root =
nullptr;
130 other.linked_tree_ =
nullptr;
132 other.root_is_leaf_ =
false;
152 uint64_t __max_degree_of_internal_node = MAX_DEGREE;
153 uint64_t __max_count_of_values_in_leaf = LEAF_CONTAINER_MAX_SIZE;
154 if (__max_degree_of_internal_node < 4)
156 throw std::runtime_error(
"Error: BPTree::initialize(__max_degree_of_internal_node, __max_count_of_values_in_leaf). The __max_degree_of_internal_node must be larger than 3.");
158 if (__max_count_of_values_in_leaf < 4)
160 throw std::runtime_error(
"Error: BPTree::initialize(__max_degree_of_internal_node, __max_count_of_values_in_leaf). The __max_count_of_values_in_leaf must be larger than 3.");
166 this->root =
nullptr;
167 this->root_is_leaf_ =
false;
180 this->leaf_container_vec.swap(_tree.leaf_container_vec);
181 this->parent_vec.swap(_tree.parent_vec);
182 this->unused_node_pointers.swap(_tree.unused_node_pointers);
183 this->unused_leaf_container_indexes.swap(_tree.unused_leaf_container_indexes);
184 this->tmp_path.swap(_tree.tmp_path);
187 std::swap(this->root, _tree.root);
188 if (swap_linked_tree)
190 std::swap(this->linked_tree_, _tree.linked_tree_);
192 std::swap(this->density_threshold, _tree.density_threshold);
193 std::swap(this->density1, _tree.density1);
194 std::swap(this->height_, _tree.height_);
195 std::swap(this->root_is_leaf_, _tree.root_is_leaf_);
205 this->
swap(_tree,
true);
221 std::stack<Node *> nodes;
222 if (!this->
empty() && !this->root_is_leaf_)
224 nodes.push(this->root);
226 while (nodes.size() > 0)
228 Node *top = nodes.top();
230 if (!top->is_parent_of_leaves())
232 const stool::SimpleDeque16<Node *> &children = top->get_children();
233 for (
Node *child : children)
240 this->root =
nullptr;
241 this->root_is_leaf_ =
false;
244 while (unused_node_pointers.size() > 0)
246 Node *top = unused_node_pointers[unused_node_pointers.size() - 1];
248 unused_node_pointers.pop_back();
251 this->leaf_container_vec.resize(0);
252 this->parent_vec.resize(0);
254 while (this->unused_leaf_container_indexes.size() > 0)
256 this->unused_leaf_container_indexes.pop();
272 return this->tmp_path;
283 uint64_t get_split_process_counter()
const
285 return this->split_process_counter;
288 uint64_t capacity()
const{
292 double get_value_density()
const{
293 return (
double) this->
size() / (double) this->capacity();
302 return LEAF_CONTAINER_MAX_SIZE;
310 return this->height_;
324 if (this->root_is_leaf_)
326 return this->leaf_container_vec[(uint64_t)this->root].
size();
330 return this->root->get_value_count();
339 return this->leaf_container_vec.size() - this->unused_leaf_container_indexes.size();
347 return this->leaf_container_vec.size();
374 if (this->root_is_leaf_)
465 return this->
height() == 0;
476 if (this->root_is_leaf_)
478 return this->leaf_container_vec[(uint64_t)this->root].
psum();
482 return BPFunctions::psum(*this->root);
496 uint64_t
psum(uint64_t i)
const
498 if (i >= this->
size())
500 throw std::invalid_argument(
"Error: BPTree::psum(i). The i must be less than the size of the tree.");
502 assert(!this->
empty());
505 if (this->root_is_leaf_)
507 return this->leaf_container_vec[(uint64_t)this->root].
psum(i);
511 return BPFunctions::psum(*this->root, i, this->leaf_container_vec);
516 throw std::runtime_error(
"Error:psum(i)");
529 if (this->root_is_leaf_)
531 return this->leaf_container_vec[(uint64_t)this->root].
select0(i);
535 return BPFunctions::select0(*this->root, i, this->leaf_container_vec);
553 if (this->root_is_leaf_)
555 return this->leaf_container_vec[(uint64_t)this->root].
search(sum);
559 return BPFunctions::search(*this->root, sum, this->leaf_container_vec);
567 inline static uint64_t time_count = 0;
574 VALUE
at(uint64_t pos)
const
578 assert(pos < this->
size());
579 std::vector<NodePointer> path;
583 assert(this->tmp_path.size() > 0);
585 uint64_t leaf = this->tmp_path[this->tmp_path.size() - 1].get_leaf_container_index();
588 auto st3 = std::chrono::system_clock::now();
590 uint64_t result = this->leaf_container_vec[leaf].at(idx);
593 auto st4 = std::chrono::system_clock::now();
594 time_count2 += std::chrono::duration_cast<std::chrono::nanoseconds>(st4 - st3).count();
601 throw std::invalid_argument(
"Error: BPTree::at()");
610 uint64_t
get_value_index(uint64_t leaf_index, uint64_t position_in_leaf_container)
const
612 if (USE_PARENT_FIELD)
614 assert(leaf_index < this->parent_vec.size());
615 Node *parent = this->parent_vec[leaf_index];
616 uint64_t dist = position_in_leaf_container;
618 if (parent ==
nullptr)
626 while (parent !=
nullptr)
629 int64_t idx = parent->get_index(node);
632 const auto &deq = parent->get_value_count_deque();
634 uint64_t sum = deq.psum(idx-1);
640 parent = node->get_parent();
647 throw std::runtime_error(
"BPTree::get_value_index(): this function is not supported.");
658 return this->leaf_container_vec[leaf_index];
670 return this->leaf_container_vec[leaf_index];
690 if (this->root_is_leaf_)
692 std::vector<VALUE> r;
693 this->leaf_container_vec[(uint64_t)this->root].to_values(r);
699 std::vector<VALUE> r;
700 BPFunctions::to_value_vector(*this->root, r, this->leaf_container_vec);
706 std::vector<VALUE> r;
720 bool verify_sub()
const {
725 NodePointer pt = *it;
728 assert(pt.get_leaf_container_index() < this->leaf_container_vec.size());
729 uint64_t
size = this->leaf_container_vec[pt.get_leaf_container_index()].size();
730 if (this->root_is_leaf_ && pt.get_leaf_container_index() == (uint64_t)this->root)
745 Node *_node = pt.get_node();
746 b = b && BPFunctions::verify(*_node, this->leaf_container_vec, MAX_DEGREE, this->root == pt.get_node());
751 if (p != this->
size())
753 throw std::logic_error(
"Error(BPTree::verify)");
757 void verify_sum_deque(Node *node)
const {
758 if(node->is_parent_of_leaves()){
759 uint64_t true_sum = 0;
760 auto &children = node->get_children();
761 for(uint64_t i = 0; i < children.size(); i++){
762 uint64_t
id = (uint64_t)children[i];
763 true_sum += this->leaf_container_vec[id].psum();
765 if(true_sum != node->get_value_sum()){
766 throw std::runtime_error(
"Error: verify_sum_deque");
769 uint64_t true_sum = 0;
770 auto &children = node->get_children();
771 for(uint64_t i = 0; i < children.size(); i++){
772 Node *child = children[i];
773 this->verify_sum_deque(child);
774 true_sum += child->get_value_sum();
777 if(true_sum != node->get_value_sum()){
778 throw std::runtime_error(
"Error: verify_sum_deque");
790 bool b1 = this->verify_sub();
792 if(!this->root_is_leaf_ && this->
size() > 0){
793 this->verify_sum_deque(this->root);
808 std::vector<std::string> tree;
811 if (this->root_is_leaf_)
813 tree.push_back(this->leaf_container_vec[(uint64_t)this->root].to_string());
817 BPFunctions::get_tree_string(*this->root, tree, this->leaf_container_vec);
822 tree.push_back(
"[]");
825 for (int64_t i = tree.size() - 1; i >= 0; i--)
827 std::cout << tree[i] << std::endl;
845 void print_info(
int message_paragraph = stool::Message::SHOW_MESSAGE)
const
847 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"========= BPTREE =========" << std::endl;
848 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Height: " << this->height_ << std::endl;
857 std::cout << stool::Message::get_paragraph_string(message_paragraph+1) <<
"Leaf: id = " << pt.get_leaf_container_index() <<
", content = " << this->leaf_container_vec[pt.get_leaf_container_index()].to_string() << std::endl;
862 pt.get_node()->print_info(message_paragraph+1);
867 if (USE_PARENT_FIELD)
869 std::vector<uint64_t> r;
870 for (
Node *x : this->parent_vec)
872 r.push_back((uint64_t)x);
874 stool::Printer::print(r);
876 std::cout <<
"==========================" << std::endl;
892 std::cout <<
"leaf_index: " << pt.get_leaf_container_index() <<
", " << this->leaf_container_vec[pt.get_leaf_container_index()].to_string() << std::endl;
897 void print_internal_nodes()
const{
898 std::cout <<
"INTERNAL NODES: " << std::endl;
901 NodePointer pt = *it;
904 Node *node = (Node *)pt.get_node();
905 std::cout <<
" " << node->to_string() << std::endl;
919 std::cout <<
"============ LEAVES ============" << std::endl;
920 for (uint64_t i = 0; i < this->leaf_container_vec.size(); i++)
922 std::cout <<
"leaf_container_vec[" << i <<
"] = " << this->leaf_container_vec[i].to_string() << std::endl;
924 std::cout <<
"============ LEAVES[END] ============" << std::endl;
943 uint64_t counter = 0;
962 uint64_t counter = 0;
988 sum1 += pt.get_node()->size_in_bytes();
989 sum1 +=
sizeof(
Node *);
1001 return sizeof(std::stack<uint64_t>) + (this->unused_leaf_container_indexes.size() *
sizeof(uint64_t));
1010 return sizeof(std::vector<uint64_t>) + (this->leaf_container_vec.capacity() *
sizeof(LEAF_CONTAINER));
1020 for (
const LEAF_CONTAINER &leaf : this->leaf_container_vec)
1022 sum2 += leaf.size_in_bytes(
true);
1027 uint64_t get_leaf_container_unused_memory()
const
1030 for (
const LEAF_CONTAINER &leaf : this->leaf_container_vec)
1032 sum2 += leaf.unused_size_in_bytes();
1045 for (
Node *node : this->unused_node_pointers)
1047 sum6 += node->size_in_bytes();
1050 sum6 += (
sizeof(
Node *) * this->unused_node_pointers.capacity()) +
sizeof(std::vector<Node *>);
1060 return (
sizeof(
Node *) * this->parent_vec.capacity()) +
sizeof(std::vector<Node *>);
1070 std::vector<std::string> log;
1075 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
"=BP Tree: " + std::to_string(
size_in_bytes) +
" bytes, " + std::to_string(
size) +
" values, " + std::to_string(bytes_per_value) +
" bytes per value =");
1076 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Max Degree of Internal Node: " + std::to_string(MAX_DEGREE));
1077 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Max Count of Values in Leaf: " + std::to_string(LEAF_CONTAINER_MAX_SIZE));
1080 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Internal Nodes: " + std::to_string(this->
get_internal_node_memory()) +
" bytes");
1082 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Ununsed Node Pointers: " + std::to_string(this->
get_unused_node_pointers_memory()) +
" bytes");
1083 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Leaf Vector: " + std::to_string(this->
get_leaf_container_vector_memory()) +
" bytes (vector capacity: " + std::to_string(this->leaf_container_vec.capacity()) +
")");
1085 uint64_t value_count = this->
size();
1087 uint64_t leaf_total_unused_memory = this->get_leaf_container_unused_memory();
1089 double byte_per_value = value_count > 0 ? (double)leaf_total_memory / (
double)value_count : 0;
1090 double unused_byte_per_value = value_count > 0 ? (double)leaf_total_unused_memory / (
double)value_count : 0;
1092 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Leaves : " + std::to_string(leaf_total_memory) +
" bytes (" + std::to_string(byte_per_value) +
" bytes per value, leaf count: " + std::to_string(this->leaf_container_vec.size()) +
")");
1093 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Unused memory for leaves : " + std::to_string(leaf_total_unused_memory) +
" bytes (" + std::to_string(unused_byte_per_value) +
" bytes per value)");
1095 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Parent Vector : " + std::to_string(this->
get_parent_vector_memory()) +
" bytes");
1096 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
"==");
1109 for (std::string &s : log)
1111 std::cout << s << std::endl;
1133 Node *current_node = this->root;
1134 bool is_leaf = this->root_is_leaf_;
1138 output_path.push_back(NodePointer::build_internal_node_pointer(this->root, -1));
1142 output_path.push_back(NodePointer::build_leaf_pointer((uint64_t)this->root, -1));
1147 is_leaf = current_node->is_parent_of_leaves();
1148 current_node = current_node->get_child(0);
1151 output_path.push_back(NodePointer::build_internal_node_pointer(current_node, 0));
1155 output_path.push_back(NodePointer::build_leaf_pointer((uint64_t)current_node, 0));
1171 Node *current_node = this->root;
1172 bool is_leaf = this->root_is_leaf_;
1176 output_path.push_back(NodePointer::build_internal_node_pointer(this->root, -1));
1180 output_path.push_back(NodePointer::build_leaf_pointer((uint64_t)this->root, -1));
1185 is_leaf = current_node->is_parent_of_leaves();
1186 uint64_t idx = current_node->get_degree() - 1;
1187 current_node = current_node->get_child(idx);
1190 output_path.push_back(NodePointer::build_internal_node_pointer(current_node, idx));
1194 output_path.push_back(NodePointer::build_leaf_pointer((uint64_t)current_node, idx));
1209 std::vector<NodePointer> &path =
const_cast<std::vector<NodePointer> &
>(this->tmp_path);
1227 if (output_path.size() != this->height_)
1229 output_path.resize(this->height_);
1236 Node *current_node = this->root;
1237 uint64_t current_i = i;
1238 bool is_leaf = this->root_is_leaf_;
1242 output_path[y++] = is_leaf ? NodePointer::build_leaf_pointer((uint64_t)this->root, -1) : NodePointer::build_internal_node_pointer(this->root, -1);
1248 assert(current_i <= current_node->get_value_count());
1251 std::pair<int64_t, uint64_t> result = BPFunctions::access_child_index_by_value_index(*current_node, current_i);
1256 if (result.first != -1)
1258 is_leaf = current_node->is_parent_of_leaves();
1259 current_node = current_node->get_child(result.first);
1260 current_i = result.second;
1261 output_path[y++] = is_leaf ? NodePointer::build_leaf_pointer((uint64_t)current_node, result.first) : NodePointer::build_internal_node_pointer(current_node, result.first);
1265 throw std::runtime_error(
"Error: get_path_from_root_to_leaf2(1)");
1272 assert(output_path.size() == y);
1295 void defragmentation()
1297 std::vector<uint64_t> tmp;
1298 while (this->unused_leaf_container_indexes.size() > 0)
1300 tmp.push_back(this->unused_leaf_container_indexes.top());
1301 this->unused_leaf_container_indexes.pop();
1304 std::sort(tmp.begin(), tmp.end(), [](
const uint64_t &lhs,
const uint64_t &rhs)
1305 { return lhs > rhs; });
1307 std::vector<std::pair<Node *, uint64_t>> tmp_nodes;
1309 std::unordered_set<uint64_t> checker2;
1311 std::unordered_set<uint64_t> checker1;
1312 for (uint64_t p : tmp)
1317 for (int64_t i = this->leaf_container_vec.size() - 1; i >= 0; --i)
1319 auto xs = checker1.find(i);
1320 if (xs == checker1.end())
1324 if (checker2.size() > tmp.size())
1333 NodePointer pt = *it;
1334 if (!pt.is_leaf() && pt.get_node()->is_parent_of_leaves())
1336 Node *node = pt.get_node();
1337 for (int64_t i = 0; i < node->children_count(); i++)
1339 uint64_t x = (uint64_t)node->get_child(i);
1340 auto xs = checker2.find(x);
1341 if (xs != checker2.end())
1343 tmp_nodes.push_back(std::pair<Node *, uint64_t>(node, i));
1348 assert(tmp_nodes.size() == checker2.size());
1351 std::sort(tmp_nodes.begin(), tmp_nodes.end(), [](
const std::pair<Node *, uint64_t> &lhs,
const std::pair<Node *, uint64_t> &rhs)
1353 uint64_t x = (uint64_t)lhs.first->get_child(lhs.second);
1354 uint64_t y = (uint64_t)rhs.first->get_child(rhs.second);
1358 while (tmp.size() > 0 && tmp_nodes.size() > 0)
1360 std::pair<Node *, uint64_t> top = tmp_nodes[tmp_nodes.size() - 1];
1361 uint64_t idx = (uint64_t)top.first->get_child(top.second);
1362 uint64_t x = tmp[tmp.size() - 1];
1365 top.first->move_container_index(top.second, x, this->leaf_container_vec);
1366 tmp_nodes.pop_back();
1376 this->leaf_container_vec.resize(this->leaf_container_vec.size() - k);
1389 void clear_unused_node_pointers()
1391 for (uint64_t i = 0; i < this->unused_node_pointers.size(); i++)
1393 delete this->unused_node_pointers[i];
1395 this->unused_node_pointers.clear();
1396 this->unused_node_pointers.shrink_to_fit();
1404 void create_root_leaf(VALUE value)
1406 uint64_t p = this->get_new_container_index();
1407 this->leaf_container_vec[p].push_back(value);
1408 this->root = (Node *)p;
1409 this->root_is_leaf_ =
true;
1411 if (USE_PARENT_FIELD)
1413 this->parent_vec[p] =
nullptr;
1428 void remove_empty_leaf(uint64_t idx, Node *parent, int64_t child_index)
1430 if (parent !=
nullptr)
1432 parent->remove_child(child_index);
1434 if (USE_PARENT_FIELD)
1436 this->parent_vec[idx] =
nullptr;
1439 this->unused_leaf_container_indexes.push(idx);
1440 this->leaf_container_vec[idx].clear();
1455 void remove_empty_node(Node *node, Node *parent, int64_t child_index)
1458 if (parent !=
nullptr)
1460 parent->remove_child(child_index);
1465 if (this->root == node)
1467 this->root =
nullptr;
1471 if (this->unused_node_pointers.size() <= 4096)
1473 this->unused_node_pointers.push_back(node);
1487 uint64_t get_new_container_index()
1489 if (this->unused_leaf_container_indexes.size() == 0)
1491 this->leaf_container_vec.push_back(LEAF_CONTAINER());
1492 if (USE_PARENT_FIELD)
1494 this->parent_vec.push_back(
nullptr);
1496 this->unused_leaf_container_indexes.push(this->leaf_container_vec.size() - 1);
1498 assert(this->unused_leaf_container_indexes.size() > 0);
1499 uint64_t idx = this->unused_leaf_container_indexes.top();
1500 this->unused_leaf_container_indexes.pop();
1511 Node *get_new_node_pointer()
1513 Node *new_node =
nullptr;
1514 if (this->unused_node_pointers.size() > 0)
1516 new_node = this->unused_node_pointers[this->unused_node_pointers.size() - 1];
1517 this->unused_node_pointers.pop_back();
1521 new_node =
new Node();
1538 void split_process(
const std::vector<NodePointer> &path, uint64_t t)
1540 const NodePointer &top = path[t];
1542 Node *node = top.get_node();
1543 Node *_new_right_node =
nullptr;
1544 uint64_t parent_edge_index = 0;
1547 _new_right_node = this->get_new_node_pointer();
1548 _new_right_node->initialize(top.get_node()->is_parent_of_leaves(), this->leaf_container_vec);
1552 _new_right_node = (Node *)this->get_new_container_index();
1555 Node *_parent =
nullptr;
1558 _parent = path[t - 1].get_node();
1559 _parent->insert_child(top.get_parent_edge_index() + 1, _new_right_node, 0, 0);
1560 parent_edge_index = top.get_parent_edge_index();
1564 _parent = this->get_new_node_pointer();
1567 _parent->initialize((uint64_t)node, (uint64_t)_new_right_node, this->leaf_container_vec);
1571 _parent->initialize(node, _new_right_node, this->leaf_container_vec);
1573 parent_edge_index = 0;
1576 this->root = _parent;
1577 this->root_is_leaf_ =
false;
1582 if (USE_PARENT_FIELD)
1586 this->parent_vec[(uint64_t)node] = _parent;
1590 node->set_parent(_parent);
1594 if (USE_PARENT_FIELD)
1598 this->parent_vec[(uint64_t)_new_right_node] = _parent;
1602 _new_right_node->set_parent(_parent);
1606 this->
split_node(node, _new_right_node, top.is_leaf(), _parent, parent_edge_index, this->parent_vec);
1619 uint64_t balance_for_insertion(
const std::vector<NodePointer> &path,
bool superLeftPushMode =
false)
1621 uint64_t split_counter = 0;
1622 for (int64_t t = path.size() - 1; t >= 0; --t)
1624 const NodePointer &top = path[t];
1625 uint64_t degree = top.get_degree(this->leaf_container_vec);
1626 uint64_t threshold = top.is_leaf() ? LEAF_CONTAINER_MAX_SIZE : MAX_DEGREE;
1627 uint64_t LR_threshold = threshold;
1628 if(superLeftPushMode){
1629 LR_threshold = (threshold * 3) / 4;
1632 if (degree > threshold)
1638 Node *parent = path[t - 1].get_node();
1639 uint64_t parent_edge_index = top.get_parent_edge_index();
1640 Node *leftSibling = parent_edge_index > 0 ? parent->get_child(parent_edge_index - 1) :
nullptr;
1641 Node *rightSibling = parent_edge_index + 1 < parent->children_count() ? parent->get_child(parent_edge_index + 1) :
nullptr;
1642 uint64_t leftSiblingDegree = UINT64_MAX;
1643 if (parent_edge_index > 0)
1645 leftSiblingDegree = top.is_leaf() ? this->leaf_container_vec[(uint64_t)leftSibling].
size() : leftSibling->get_degree();
1650 uint64_t rightSiblingDegree = UINT64_MAX;
1651 if (parent_edge_index + 1 < parent->children_count())
1653 rightSiblingDegree = top.is_leaf() ? this->leaf_container_vec[(uint64_t)rightSibling].
size() : rightSibling->get_degree();
1657 if (leftSiblingDegree < LR_threshold || rightSiblingDegree < LR_threshold)
1659 if (leftSiblingDegree < LR_threshold)
1661 if (superLeftPushMode)
1663 uint64_t diff = LR_threshold - leftSiblingDegree;
1664 this->
move_values_left(leftSibling, top.get_node(), diff, top.is_leaf(), parent, parent_edge_index);
1668 this->
move_values_left(leftSibling, top.get_node(), 1, top.is_leaf(), parent, parent_edge_index);
1673 this->
move_values_right(top.get_node(), rightSibling, 1, top.is_leaf(), parent, parent_edge_index);
1679 this->split_process(path, t);
1685 this->split_process(path, t);
1694 return split_counter;
1707 uint64_t balance_for_removal(
const std::vector<NodePointer> &path)
1711 uint64_t merge_counter = 0;
1713 for (int64_t t = path.size() - 1; t >= 0; --t)
1715 const NodePointer &top = path[t];
1716 uint64_t max_size = top.is_leaf() ? LEAF_CONTAINER_MAX_SIZE : MAX_DEGREE;
1717 uint64_t threshold = max_size / 2;
1719 uint64_t degree = top.get_degree(this->leaf_container_vec);
1720 if (degree >= threshold)
1728 Node *parent = path[t - 1].get_node();
1729 uint64_t parent_edge_index = top.get_parent_edge_index();
1730 Node *leftSibling = parent_edge_index > 0 ? parent->get_child(parent_edge_index - 1) :
nullptr;
1731 Node *rightSibling = parent_edge_index + 1 < parent->children_count() ? parent->get_child(parent_edge_index + 1) :
nullptr;
1732 uint64_t leftSiblingDegree = 0;
1733 if (parent_edge_index > 0)
1735 leftSiblingDegree = top.is_leaf() ? this->leaf_container_vec[(uint64_t)leftSibling].
size() : leftSibling->get_degree();
1738 uint64_t rightSiblingDegree = 0;
1739 if (parent_edge_index + 1 < parent->children_count())
1741 rightSiblingDegree = top.is_leaf() ? this->leaf_container_vec[(uint64_t)rightSibling].
size() : rightSibling->get_degree();
1744 if (leftSiblingDegree != 0 || rightSiblingDegree != 0)
1746 if (leftSiblingDegree > threshold)
1748 this->
move_values_right(leftSibling, top.get_node(), 1, top.is_leaf(), parent, parent_edge_index - 1);
1751 else if (rightSiblingDegree > threshold)
1753 this->
move_values_left(top.get_node(), rightSibling, 1, top.is_leaf(), parent, parent_edge_index + 1);
1758 assert(leftSiblingDegree == threshold || rightSiblingDegree == threshold);
1759 if (leftSiblingDegree == threshold)
1761 this->
move_values_left(leftSibling, top.get_node(), degree, top.is_leaf(), parent, parent_edge_index);
1764 this->remove_empty_leaf(top.get_leaf_container_index(), parent, parent_edge_index);
1768 this->remove_empty_node(top.get_node(), parent, parent_edge_index);
1773 this->
move_values_right(top.get_node(), rightSibling, degree, top.is_leaf(), parent, parent_edge_index);
1776 this->remove_empty_leaf(top.get_leaf_container_index(), parent, parent_edge_index);
1780 this->remove_empty_node(top.get_node(), parent, parent_edge_index);
1788 throw std::logic_error(
"Error(BPTree::balance_for_removal(1))");
1796 throw std::logic_error(
"Error(BPTree::balance_for_removal(2))");
1798 else if (degree == 1)
1800 if (!this->root_is_leaf_)
1803 bool b = this->root->is_parent_of_leaves();
1804 Node *new_root = this->root->get_child(0);
1805 this->root->remove_child(0);
1806 this->remove_empty_node(this->root,
nullptr, -1);
1807 this->root = new_root;
1808 this->root_is_leaf_ = b;
1811 if (USE_PARENT_FIELD)
1815 this->parent_vec[(uint64_t)new_root] =
nullptr;
1819 new_root->set_parent(
nullptr);
1833 return merge_counter;
1851 std::vector<VALUE> r;
1868 std::vector<NodePointer> path;
1870 if (path.size() > 0)
1872 uint64_t leaf = path[path.size() - 1].get_leaf_container_index();
1873 this->leaf_container_vec[leaf].push_front(value);
1875 uint64_t sum = this->leaf_container_vec[leaf].psum(0);
1877 for (int64_t i = path.size() - 2; i >= 0; --i)
1879 Node *parent = path[i].get_node();
1880 uint64_t parent_edge_index = path[i + 1].get_parent_edge_index();
1881 parent->increment(parent_edge_index, 1, sum);
1883 this->balance_for_insertion(path,
true);
1887 this->create_root_leaf(value);
1904 uint64_t push_many_to_leaf(
const std::vector<VALUE> &values, uint64_t value_pos,
const std::vector<NodePointer> &path)
1907 uint64_t leaf = path[path.size() - 1].get_leaf_container_index();
1909 while ((value_pos + x) < values.size() && leaf_container_vec[leaf].size() <= this->get_max_count_of_values_in_leaf())
1912 this->leaf_container_vec[leaf].push_back(values[value_pos + x]);
1917 uint64_t sum = len > 0 ? this->leaf_container_vec[leaf].reverse_psum(len - 1) : 0;
1919 for (int64_t j = path.size() - 2; j >= 0; --j)
1921 Node *parent = path[j].get_node();
1922 uint64_t parent_edge_index = path[j + 1].get_parent_edge_index();
1923 assert(parent_edge_index < parent->children_count());
1925 parent->increment(parent_edge_index, len, sum);
1928 this->balance_for_insertion(path,
true);
1944 void push_back_to_internal_node(uint64_t leaf_index,
const std::vector<NodePointer> &path)
1946 Node *node = path[path.size() - 1].get_node();
1947 uint64_t child_count = this->leaf_container_vec[leaf_index].size();
1948 uint64_t child_sum = 0;
1951 child_sum = this->leaf_container_vec[leaf_index].psum();
1953 node->append_child(leaf_index, child_count, child_sum);
1955 for (int64_t j = path.size() - 2; j >= 0; --j)
1957 Node *parent = path[j].get_node();
1958 uint64_t parent_edge_index = path[j + 1].get_parent_edge_index();
1959 assert(parent_edge_index < parent->children_count());
1960 parent->increment(parent_edge_index, child_count, child_sum);
1963 this->balance_for_insertion(path,
true);
1979 std::vector<NodePointer> path;
1980 while (i < containers.size())
1984 if (path.size() > 1)
1986 uint64_t p = this->get_new_container_index();
1987 this->leaf_container_vec[p].swap(containers[i]);
1989 this->push_back_to_internal_node(p, path);
1995 std::vector<VALUE> tmp_values;
1996 containers[i].to_values(tmp_values);
2016 std::vector<NodePointer> path;
2019 while (i < values.size())
2023 if (path.size() > 0)
2025 i += this->push_many_to_leaf(values, i, path);
2029 this->create_root_leaf(values[i]);
2045 uint64_t
remove_using_path(
const std::vector<NodePointer> &path, uint64_t position_in_leaf_container)
2047 uint64_t merge_counter = 0;
2048 uint64_t x = path[path.size() - 1].get_leaf_container_index();
2049 int64_t delta = leaf_container_vec[x].psum(position_in_leaf_container, position_in_leaf_container);
2050 leaf_container_vec[x].remove(position_in_leaf_container);
2051 for (int64_t i = path.size() - 2; i >= 0; i--)
2053 Node *node = path[i].get_node();
2054 uint64_t child_index = path[i + 1].get_parent_edge_index();
2056 node->increment(child_index, -1, -delta);
2059 if (path.size() > 1)
2061 merge_counter += this->balance_for_removal(this->tmp_path);
2065 assert(path.size() == 1);
2066 if (leaf_container_vec[x].
size() == 0)
2068 this->remove_empty_leaf((uint64_t)this->root,
nullptr, -1);
2069 this->root =
nullptr;
2070 this->root_is_leaf_ =
false;
2074 return merge_counter;
2090 assert(pos < this->
size());
2091 this->remove_operation_counter++;
2094 this->merge_process_counter += this->
remove_using_path(this->tmp_path, position_to_remove);
2098 throw std::invalid_argument(
"Error in BPTree::remove(pos). This tree is empty. pos = " + std::to_string(pos));
2120 void insert(uint64_t pos, VALUE value, uint64_t sum_delta)
2122 if (pos < this->
size())
2126 assert(pos <= this->
size());
2130 if (position_to_insert != -1)
2132 uint64_t x = this->tmp_path[this->tmp_path.size() - 1].get_leaf_container_index();
2136 this->leaf_container_vec[x].insert(position_to_insert, value);
2138 for (int64_t i = this->tmp_path.size() - 2; i >= 0; i--)
2140 Node *node = this->tmp_path[i].get_node();
2141 uint64_t child_index = this->tmp_path[i + 1].get_parent_edge_index();
2144 node->increment(child_index, 1, sum_delta);
2146 this->split_process_counter += this->balance_for_insertion(this->tmp_path);
2150 throw std::runtime_error(
"Error: insert");
2158 this->create_root_leaf(value);
2162 throw std::invalid_argument(
"Error(BPTree::insert)");
2168 assert(pos == this->
size());
2171 this->insert_operation_counter++;
2190 void resize(uint64_t _size, VALUE default_value)
2192 if (this->
size() < _size)
2195 std::vector<NodePointer> path;
2196 uint64_t diff = _size - this->
size();
2202 if (path.size() > 0)
2204 uint64_t leaf = path[path.size() - 1].get_leaf_container_index();
2208 this->leaf_container_vec[leaf].push_back(default_value);
2212 uint64_t sum = len > 0 ? this->leaf_container_vec[leaf].reverse_psum(len - 1) : 0;
2214 for (int64_t j = path.size() - 2; j >= 0; --j)
2216 Node *parent = path[j].get_node();
2217 uint64_t parent_edge_index = path[j + 1].get_parent_edge_index();
2218 parent->increment(parent_edge_index, len, sum);
2220 this->balance_for_insertion(path,
true);
2224 this->create_root_leaf(default_value);
2231 while (this->
size() > _size)
2245 this->linked_tree_ = _tree;
2255 return this->linked_tree_;
2282 uint64_t left_leaf = (uint64_t)left_node;
2283 uint64_t right_leaf = (uint64_t)right_node;
2284 assert(left_leaf < this->leaf_container_vec.size());
2285 assert(right_leaf < this->leaf_container_vec.size());
2287 if constexpr (USE_PSUM){
2288 if (parent !=
nullptr)
2290 assert(this->leaf_container_vec[left_leaf].
psum() == parent->get_value_sum_deque().at(parent_edge_index_of_left_node));
2291 int64_t sum = len != 0 ? this->leaf_container_vec[left_leaf].reverse_psum(len - 1) : 0;
2293 assert(sum <= (int64_t)this->leaf_container_vec[left_leaf].
psum());
2300 parent->__increment_a_value_of_sum_deque(parent_edge_index_of_left_node, -sum);
2301 parent->__increment_a_value_of_sum_deque(parent_edge_index_of_left_node + 1, sum);
2307 if (parent !=
nullptr)
2309 auto &parent_count_deq = parent->get_value_count_deque();
2310 parent_count_deq.decrement(parent_edge_index_of_left_node, len);
2311 parent_count_deq.increment(parent_edge_index_of_left_node + 1, len);
2313 auto items = this->leaf_container_vec[left_leaf].pop_back(len);
2314 this->leaf_container_vec[right_leaf].push_front(items);
2318 BPFunctions::move_right(*left_node, *right_node, len, parent, parent_edge_index_of_left_node, this->parent_vec);
2338 uint64_t left_leaf = (uint64_t)left_node;
2339 uint64_t right_leaf = (uint64_t)right_node;
2340 assert(left_leaf < this->leaf_container_vec.size());
2342 if (USE_PSUM && parent !=
nullptr)
2344 uint64_t sum = len != 0 ? this->leaf_container_vec[right_leaf].psum(len - 1) : 0;
2345 parent->__increment_a_value_of_sum_deque(parent_edge_index_of_right_node, -sum);
2346 parent->__increment_a_value_of_sum_deque(parent_edge_index_of_right_node - 1, sum);
2349 if (parent !=
nullptr)
2351 auto &parent_count_deq = parent->get_value_count_deque();
2352 parent_count_deq.decrement(parent_edge_index_of_right_node, len);
2353 parent_count_deq.increment(parent_edge_index_of_right_node - 1, len);
2355 auto items = this->leaf_container_vec[right_leaf].pop_front(len);
2356 this->leaf_container_vec[left_leaf].push_back(items);
2360 BPFunctions::move_left(*left_node, *right_node, len, parent, parent_edge_index_of_right_node, this->parent_vec);
2378 void split_node(
Node *left_node,
Node *right_node,
bool is_leaf,
Node *parent, int64_t parent_edge_index_of_left_node, [[maybe_unused]] std::vector<Node *> &parent_vec)
2381 uint64_t degree = 0;
2384 degree = leaf_container_vec[(uint64_t)left_node].
size();
2385 assert((uint64_t)left_node < this->leaf_container_vec.size());
2386 assert((uint64_t)right_node < this->leaf_container_vec.size());
2391 degree = left_node->get_degree();
2393 uint64_t left_len = degree / 2;
2394 uint64_t right_len = degree - left_len;
2395 this->
move_values_right(left_node, right_node, right_len, is_leaf, parent, parent_edge_index_of_left_node);
2413 NodePointer &leaf_pointer = this->tmp_path[this->tmp_path.size() - 1];
2414 LEAF_CONTAINER &leaf = this->leaf_container_vec[leaf_pointer.get_leaf_container_index()];
2415 leaf.increment(pos, delta);
2416 for (int64_t i = this->tmp_path.size() - 2; i >= 0; --i)
2418 uint64_t idx = this->tmp_path[i + 1].get_parent_edge_index();
2419 Node *parent = this->tmp_path[i].get_node();
2420 parent->increment(idx, 0, delta);
2440 if (prev + 1 != (int64_t)(*it))
2453 void print_debug_info()
const{
2454 std::cout <<
"BPTree::print_debug_info()" << std::endl;
2462 std::cout <<
"BPTree::time_count: " << (double)BPTree::time_count / 1000000.0 <<
" ms" << std::endl;
2463 std::cout <<
"BPTree::time_count2: " << (double)bptree::time_count2 / 1000000.0 <<
" ms" << std::endl;
2474 void preprocess_for_the_exchange_of_two_leaves([[maybe_unused]] uint64_t leaf_index1, [[maybe_unused]] uint64_t leaf_index2)
2490 void exchange(stool::SimpleDeque16<Node *> &children1, uint64_t j, uint64_t leaf_index2)
2492 uint64_t leaf_index1 = (uint64_t)children1[j];
2493 assert(this->parent_vec[leaf_index1] !=
nullptr);
2495 if (leaf_index1 != leaf_index2)
2497 this->preprocess_for_the_exchange_of_two_leaves(leaf_index1, leaf_index2);
2499 if (this->parent_vec[leaf_index2] !=
nullptr)
2501 auto &children2 = this->parent_vec[leaf_index2]->get_children();
2502 uint64_t idx = this->parent_vec[leaf_index2]->get_index((Node *)leaf_index2);
2503 this->leaf_container_vec[leaf_index2].swap(this->leaf_container_vec[leaf_index1]);
2504 children1[j] = (Node *)leaf_index2;
2505 children2[idx] = (Node *)leaf_index1;
2509 this->leaf_container_vec[leaf_index2].swap(this->leaf_container_vec[leaf_index1]);
2510 children1[j] = (Node *)leaf_index2;
2513 Node *tmp_n = this->parent_vec[leaf_index1];
2514 this->parent_vec[leaf_index1] = this->parent_vec[leaf_index2];
2515 this->parent_vec[leaf_index2] = tmp_n;
2538 if (this->
size() == 0 || this->root_is_leaf_)
2545 if (!USE_PARENT_FIELD)
2547 this->parent_vec.resize(this->leaf_container_vec.size(),
nullptr);
2554 Node *node = np.get_node();
2555 if (node->is_parent_of_leaves())
2557 auto &children = node->get_children();
2558 for (
Node *v : children)
2560 uint64_t leaf = (uint64_t)v;
2561 this->parent_vec[leaf] = node;
2567 uint64_t counter = 0;
2574 Node *node = np.get_node();
2575 if (node->is_parent_of_leaves())
2577 uint64_t _size = node->children_count();
2578 auto &children1 = node->get_children();
2580 for (uint64_t j = 0; j < _size; j++)
2582 this->exchange(children1, j, counter);
2589 while (this->leaf_container_vec.size() > counter)
2591 this->leaf_container_vec.pop_back();
2592 this->parent_vec.pop_back();
2594 while (this->unused_leaf_container_indexes.size() > 0)
2596 this->unused_leaf_container_indexes.pop();
2599 if (!USE_PARENT_FIELD)
2601 std::vector<Node *> tmp;
2602 this->parent_vec.swap(tmp);
2605 if (this->root_is_leaf_)
2607 this->root = (
Node *)0;
2626 assert(nodes.size() > 0);
2627 std::vector<Node *> r;
2628 if (nodes.size() == 1)
2630 this->root = nodes[0];
2631 this->root_is_leaf_ =
false;
2632 this->height_ = current_height;
2634 else if (nodes.size() <= MAX_DEGREE)
2637 Node *root = this->get_new_node_pointer();
2638 root->initialize(
false, this->leaf_container_vec);
2639 for (uint64_t i = 0; i < nodes.size(); i++)
2641 if (USE_PARENT_FIELD)
2643 nodes[i]->set_parent(root);
2645 uint64_t count = nodes[i]->get_value_count();
2649 sum = nodes[i]->get_value_sum();
2651 root->append_child(nodes[i], count, sum);
2658 uint64_t counter = nodes.size();
2659 uint64_t threshold = MAX_DEGREE * 2;
2663 if (counter >= threshold)
2667 else if (counter > MAX_DEGREE)
2675 Node *node = this->get_new_node_pointer();
2676 node->initialize(
false, this->leaf_container_vec);
2678 for (uint64_t j = 0; j < d; j++)
2680 if (USE_PARENT_FIELD)
2682 nodes[i]->set_parent(node);
2684 uint64_t count = nodes[i]->get_value_count();
2688 sum = nodes[i]->get_value_sum();
2690 node->append_child(nodes[i], count, sum);
2711 std::vector<Node *> r;
2713 if (this->leaf_container_vec.size() == 0)
2715 this->root =
nullptr;
2716 this->root_is_leaf_ =
false;
2719 else if (this->leaf_container_vec.size() == 1)
2721 this->root = (
Node *)0;
2722 this->root_is_leaf_ =
true;
2725 else if (this->leaf_container_vec.size() <= MAX_DEGREE)
2727 Node *root = this->get_new_node_pointer();
2728 root->initialize(
true, this->leaf_container_vec);
2729 for (uint64_t i = 0; i < this->leaf_container_vec.size(); i++)
2734 psum += this->leaf_container_vec[i].psum();
2736 if (USE_PARENT_FIELD)
2738 this->parent_vec[i] = root;
2741 root->append_child((
Node *)i, this->leaf_container_vec[i].
size(),
psum);
2749 uint64_t counter = this->leaf_container_vec.size();
2750 uint64_t threshold = MAX_DEGREE * 2;
2754 if (counter >= threshold)
2758 else if (counter > MAX_DEGREE)
2766 Node *node = this->get_new_node_pointer();
2767 node->initialize(
true, this->leaf_container_vec);
2769 for (uint64_t j = 0; j < d; j++)
2774 psum += this->leaf_container_vec[i].psum();
2776 if (USE_PARENT_FIELD)
2778 this->parent_vec[i] = node;
2780 node->append_child((
Node *)i, this->leaf_container_vec[i].
size(),
psum);
2802 if (_values.size() == 0)
2805 else if (_values.size() <= LEAF_CONTAINER_MAX_SIZE)
2807 uint64_t leaf_index = this->get_new_container_index();
2809 while (i < _values.size())
2811 this->leaf_container_vec[leaf_index].push_back(_values[i]);
2817 uint64_t threshold = LEAF_CONTAINER_MAX_SIZE * 2;
2818 uint64_t counter = _values.size();
2820 while (i < _values.size())
2823 if (counter >= threshold)
2825 d = LEAF_CONTAINER_MAX_SIZE;
2827 else if (counter > LEAF_CONTAINER_MAX_SIZE)
2829 d = LEAF_CONTAINER_MAX_SIZE / 2;
2835 assert(counter >= (LEAF_CONTAINER_MAX_SIZE / 2));
2837 uint64_t leaf_index = this->get_new_container_index();
2838 for (uint64_t j = 0; j < d; j++)
2840 this->leaf_container_vec[leaf_index].push_back(_values[i]);
2857 void build(
const std::vector<VALUE> &_values)
2863 uint64_t current_height = 2;
2864 while (layer.size() > 0)
2868 layer.swap(next_layer);
2886 this->leaf_container_vec.swap(_leaf_containers);
2887 if (USE_PARENT_FIELD)
2889 this->parent_vec.resize(this->leaf_container_vec.size(),
nullptr);
2893 uint64_t current_height = 2;
2894 while (layer.size() > 0)
2897 layer.swap(next_layer);
2912 void save(std::vector<uint8_t> &output, uint64_t &pos)
2919 uint64_t _max_degree = MAX_DEGREE;
2920 uint64_t _max_count_of_values_in_leaf = LEAF_CONTAINER_MAX_SIZE;
2922 uint64_t _size =
sizeof(_max_degree) +
sizeof(_max_count_of_values_in_leaf) + LEAF_CONTAINER::get_byte_size(this->leaf_container_vec);
2923 if (pos + _size > output.size())
2925 output.resize(pos + _size);
2928 std::memcpy(output.data() + pos, &_max_degree,
sizeof(uint64_t));
2929 pos +=
sizeof(uint64_t);
2930 std::memcpy(output.data() + pos, &_max_count_of_values_in_leaf,
sizeof(uint64_t));
2931 pos +=
sizeof(uint64_t);
2933 LEAF_CONTAINER::save(this->leaf_container_vec, output, pos);
2950 uint64_t _max_degree = MAX_DEGREE;
2951 uint64_t _max_count_of_values_in_leaf = LEAF_CONTAINER_MAX_SIZE;
2953 os.write((
const char *)(&_max_degree),
sizeof(uint64_t));
2954 os.write((
const char *)(&_max_count_of_values_in_leaf),
sizeof(uint64_t));
2955 LEAF_CONTAINER::save(this->leaf_container_vec, os);
2970 uint64_t _max_degree;
2971 uint64_t _max_count_of_values_in_leaf;
2973 std::memcpy(&_max_degree, data.data() + pos,
sizeof(uint64_t));
2974 pos +=
sizeof(uint64_t);
2975 std::memcpy(&_max_count_of_values_in_leaf, data.data() + pos,
sizeof(uint64_t));
2976 pos +=
sizeof(uint64_t);
2978 auto tmp = LEAF_CONTAINER::load_vector(data, pos);
2995 uint64_t _max_degree;
2996 uint64_t _max_count_of_values_in_leaf;
2997 ifs.read((
char *)(&_max_degree),
sizeof(uint64_t));
2998 ifs.read((
char *)(&_max_count_of_values_in_leaf),
sizeof(uint64_t));
3000 auto tmp = LEAF_CONTAINER::load_vector(ifs);
3005 void print_information_about_performance(
int message_paragraph = stool::Message::SHOW_MESSAGE)
const{
3006 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Performance Information (BPTree)[" << std::endl;
3007 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of insertion operations: " << this->insert_operation_counter << std::endl;
3008 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of split process in insertion operations: " << this->split_process_counter << std::endl;
3009 if(this->insert_operation_counter > 0){
3010 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of split process per insertion: " << (double)this->split_process_counter / (
double)this->insert_operation_counter << std::endl;
3013 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of removal operations: " << this->remove_operation_counter << std::endl;
3014 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of merge process in removal operations: " << this->merge_process_counter << std::endl;
3015 if(this->remove_operation_counter > 0){
3016 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of merge process per removal: " << (double)this->merge_process_counter / (
double)this->remove_operation_counter << std::endl;
3019 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"]" << std::endl;
3039 uint64_t internal_node_count = 0;
3040 uint64_t leaf_count = 0;
3041 uint64_t total_degree_of_internal_node = 0;
3048 internal_node_count++;
3049 total_degree_of_internal_node += np.get_node()->children_count();
3057 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Statistics(BPTree):" << std::endl;
3058 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of internal nodes: " << internal_node_count << std::endl;
3059 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of used leaf containers: " << leaf_count << std::endl;
3060 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The height of this tree: " << this->height_ << std::endl;
3061 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of stored values: " << this->
size() << std::endl;
3063 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The max degree of internal node (parameter): " << MAX_DEGREE << std::endl;
3064 if (internal_node_count > 0)
3066 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The average degree of internal node: " << (total_degree_of_internal_node / internal_node_count) << std::endl;
3068 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The max count of values in leaf (parameter): " << LEAF_CONTAINER_MAX_SIZE << std::endl;
3069 if (this->
size() > 0)
3071 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The average count of values in leaf (parameter): " << (this->
size() / leaf_count) << std::endl;
3074 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of unused nodes: " << this->unused_node_pointers.size() << std::endl;
3075 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of unused leaf containers: " << this->unused_leaf_container_indexes.size() << std::endl;
3076 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of stored parent pointers: " << this->parent_vec.size() << std::endl;
3079 uint64_t num = this->
size();
3080 if(USE_PARENT_FIELD){
3081 total_memory_usage += this->parent_vec.size() *
sizeof(
Node *);
3083 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"Estimated memory usage: " << total_memory_usage <<
" bytes (Avg: " << (total_memory_usage / num) <<
" bytes)" << std::endl;
3084 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"[END]" << std::endl;