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->psum_on_count_deque();
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);
633 uint64_t sum = parent->psum_on_count_deque(idx-1);
639 parent = node->get_parent();
646 throw std::runtime_error(
"BPTree::get_value_index(): this function is not supported.");
657 return this->leaf_container_vec[leaf_index];
669 return this->leaf_container_vec[leaf_index];
689 if (this->root_is_leaf_)
691 std::vector<VALUE> r;
692 this->leaf_container_vec[(uint64_t)this->root].to_values(r);
698 std::vector<VALUE> r;
699 BPFunctions::to_value_vector(*this->root, r, this->leaf_container_vec);
705 std::vector<VALUE> r;
719 bool verify_sub()
const {
724 NodePointer pt = *it;
727 assert(pt.get_leaf_container_index() < this->leaf_container_vec.size());
728 uint64_t
size = this->leaf_container_vec[pt.get_leaf_container_index()].size();
729 if (this->root_is_leaf_ && pt.get_leaf_container_index() == (uint64_t)this->root)
744 Node *_node = pt.get_node();
745 b = b && BPFunctions::verify(*_node, this->leaf_container_vec, MAX_DEGREE, this->root == pt.get_node());
750 if (p != this->
size())
752 throw std::logic_error(
"Error(BPTree::verify)");
756 void verify_sum_deque(Node *node)
const {
757 if(node->is_parent_of_leaves()){
758 uint64_t true_sum = 0;
759 auto &children = node->get_children();
760 for(uint64_t i = 0; i < children.size(); i++){
761 uint64_t
id = (uint64_t)children[i];
762 true_sum += this->leaf_container_vec[id].psum();
764 if(true_sum != node->psum_on_sum_deque()){
765 throw std::runtime_error(
"Error: verify_sum_deque");
768 uint64_t true_sum = 0;
769 auto &children = node->get_children();
770 for(uint64_t i = 0; i < children.size(); i++){
771 Node *child = children[i];
772 this->verify_sum_deque(child);
773 true_sum += child->psum_on_sum_deque();
776 if(true_sum != node->psum_on_sum_deque()){
777 throw std::runtime_error(
"Error: verify_sum_deque");
789 bool b1 = this->verify_sub();
791 if(!this->root_is_leaf_ && this->
size() > 0){
792 this->verify_sum_deque(this->root);
807 std::vector<std::string> tree;
810 if (this->root_is_leaf_)
812 tree.push_back(this->leaf_container_vec[(uint64_t)this->root].to_string());
816 BPFunctions::get_tree_string(*this->root, tree, this->leaf_container_vec);
821 tree.push_back(
"[]");
824 for (int64_t i = tree.size() - 1; i >= 0; i--)
826 std::cout << tree[i] << std::endl;
844 void print_info(
int message_paragraph = stool::Message::SHOW_MESSAGE)
const
846 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"========= BPTREE =========" << std::endl;
847 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Height: " << this->height_ << std::endl;
856 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;
861 pt.get_node()->print_info(message_paragraph+1);
866 if (USE_PARENT_FIELD)
868 std::vector<uint64_t> r;
869 for (
Node *x : this->parent_vec)
871 r.push_back((uint64_t)x);
873 stool::DebugPrinter::print_integers(r);
875 std::cout <<
"==========================" << std::endl;
891 std::cout <<
"leaf_index: " << pt.get_leaf_container_index() <<
", " << this->leaf_container_vec[pt.get_leaf_container_index()].to_string() << std::endl;
896 void print_internal_nodes()
const{
897 std::cout <<
"INTERNAL NODES: " << std::endl;
900 NodePointer pt = *it;
903 Node *node = (Node *)pt.get_node();
904 std::cout <<
" " << node->to_string() << std::endl;
918 std::cout <<
"============ LEAVES ============" << std::endl;
919 for (uint64_t i = 0; i < this->leaf_container_vec.size(); i++)
921 std::cout <<
"leaf_container_vec[" << i <<
"] = " << this->leaf_container_vec[i].to_string() << std::endl;
923 std::cout <<
"============ LEAVES[END] ============" << std::endl;
930 uint64_t
size_in_bytes([[maybe_unused]]
bool only_extra_bytes =
false)
const
932 uint64_t _max_degree = MAX_DEGREE;
933 uint64_t _max_count_of_values_in_leaf = LEAF_CONTAINER_MAX_SIZE;
934 uint64_t _size =
sizeof(_max_degree) +
sizeof(_max_count_of_values_in_leaf) + LEAF_CONTAINER::get_byte_size(this->leaf_container_vec);
945 uint64_t counter = 0;
964 uint64_t counter = 0;
990 sum1 += pt.get_node()->size_in_bytes();
991 sum1 +=
sizeof(
Node *);
1003 return sizeof(std::stack<uint64_t>) + (this->unused_leaf_container_indexes.size() *
sizeof(uint64_t));
1012 return sizeof(std::vector<uint64_t>) + (this->leaf_container_vec.capacity() *
sizeof(LEAF_CONTAINER));
1022 for (
const LEAF_CONTAINER &leaf : this->leaf_container_vec)
1024 sum2 += leaf.size_in_bytes(
true);
1029 uint64_t get_leaf_container_unused_memory()
const
1032 for (
const LEAF_CONTAINER &leaf : this->leaf_container_vec)
1034 sum2 += leaf.unused_size_in_bytes();
1047 for (
Node *node : this->unused_node_pointers)
1049 sum6 += node->size_in_bytes();
1052 sum6 += (
sizeof(
Node *) * this->unused_node_pointers.capacity()) +
sizeof(std::vector<Node *>);
1062 return (
sizeof(
Node *) * this->parent_vec.capacity()) +
sizeof(std::vector<Node *>);
1072 std::vector<std::string> log;
1077 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 =");
1078 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Max Degree of Internal Node: " + std::to_string(MAX_DEGREE));
1079 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Max Count of Values in Leaf: " + std::to_string(LEAF_CONTAINER_MAX_SIZE));
1082 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Internal Nodes: " + std::to_string(this->
get_internal_node_memory()) +
" bytes");
1084 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Ununsed Node Pointers: " + std::to_string(this->
get_unused_node_pointers_memory()) +
" bytes");
1085 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()) +
")");
1087 uint64_t value_count = this->
size();
1089 uint64_t leaf_total_unused_memory = this->get_leaf_container_unused_memory();
1091 double byte_per_value = value_count > 0 ? (double)leaf_total_memory / (
double)value_count : 0;
1092 double unused_byte_per_value = value_count > 0 ? (double)leaf_total_unused_memory / (
double)value_count : 0;
1094 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()) +
")");
1095 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)");
1097 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
" Parent Vector : " + std::to_string(this->
get_parent_vector_memory()) +
" bytes");
1098 log.push_back(stool::Message::get_paragraph_string(message_paragraph) +
"==");
1111 for (std::string &s : log)
1113 std::cout << s << std::endl;
1135 Node *current_node = this->root;
1136 bool is_leaf = this->root_is_leaf_;
1140 output_path.push_back(NodePointer::build_internal_node_pointer(this->root, -1));
1144 output_path.push_back(NodePointer::build_leaf_pointer((uint64_t)this->root, -1));
1149 is_leaf = current_node->is_parent_of_leaves();
1150 current_node = current_node->get_child(0);
1153 output_path.push_back(NodePointer::build_internal_node_pointer(current_node, 0));
1157 output_path.push_back(NodePointer::build_leaf_pointer((uint64_t)current_node, 0));
1173 Node *current_node = this->root;
1174 bool is_leaf = this->root_is_leaf_;
1178 output_path.push_back(NodePointer::build_internal_node_pointer(this->root, -1));
1182 output_path.push_back(NodePointer::build_leaf_pointer((uint64_t)this->root, -1));
1187 is_leaf = current_node->is_parent_of_leaves();
1188 uint64_t idx = current_node->get_degree() - 1;
1189 current_node = current_node->get_child(idx);
1192 output_path.push_back(NodePointer::build_internal_node_pointer(current_node, idx));
1196 output_path.push_back(NodePointer::build_leaf_pointer((uint64_t)current_node, idx));
1211 std::vector<NodePointer> &path =
const_cast<std::vector<NodePointer> &
>(this->tmp_path);
1229 if (output_path.size() != this->height_)
1231 output_path.resize(this->height_);
1238 Node *current_node = this->root;
1239 uint64_t current_i = i;
1240 bool is_leaf = this->root_is_leaf_;
1244 output_path[y++] = is_leaf ? NodePointer::build_leaf_pointer((uint64_t)this->root, -1) : NodePointer::build_internal_node_pointer(this->root, -1);
1250 assert(current_i <= current_node->psum_on_count_deque());
1253 std::pair<int64_t, uint64_t> result = BPFunctions::access_child_index_by_value_index(*current_node, current_i);
1258 if (result.first != -1)
1260 is_leaf = current_node->is_parent_of_leaves();
1261 current_node = current_node->get_child(result.first);
1262 current_i = result.second;
1263 output_path[y++] = is_leaf ? NodePointer::build_leaf_pointer((uint64_t)current_node, result.first) : NodePointer::build_internal_node_pointer(current_node, result.first);
1267 throw std::runtime_error(
"Error: get_path_from_root_to_leaf2(1)");
1274 assert(output_path.size() == y);
1297 void defragmentation()
1299 std::vector<uint64_t> tmp;
1300 while (this->unused_leaf_container_indexes.size() > 0)
1302 tmp.push_back(this->unused_leaf_container_indexes.top());
1303 this->unused_leaf_container_indexes.pop();
1306 std::sort(tmp.begin(), tmp.end(), [](
const uint64_t &lhs,
const uint64_t &rhs)
1307 { return lhs > rhs; });
1309 std::vector<std::pair<Node *, uint64_t>> tmp_nodes;
1311 std::unordered_set<uint64_t> checker2;
1313 std::unordered_set<uint64_t> checker1;
1314 for (uint64_t p : tmp)
1319 for (int64_t i = this->leaf_container_vec.size() - 1; i >= 0; --i)
1321 auto xs = checker1.find(i);
1322 if (xs == checker1.end())
1326 if (checker2.size() > tmp.size())
1335 NodePointer pt = *it;
1336 if (!pt.is_leaf() && pt.get_node()->is_parent_of_leaves())
1338 Node *node = pt.get_node();
1339 for (int64_t i = 0; i < node->children_count(); i++)
1341 uint64_t x = (uint64_t)node->get_child(i);
1342 auto xs = checker2.find(x);
1343 if (xs != checker2.end())
1345 tmp_nodes.push_back(std::pair<Node *, uint64_t>(node, i));
1350 assert(tmp_nodes.size() == checker2.size());
1353 std::sort(tmp_nodes.begin(), tmp_nodes.end(), [](
const std::pair<Node *, uint64_t> &lhs,
const std::pair<Node *, uint64_t> &rhs)
1355 uint64_t x = (uint64_t)lhs.first->get_child(lhs.second);
1356 uint64_t y = (uint64_t)rhs.first->get_child(rhs.second);
1360 while (tmp.size() > 0 && tmp_nodes.size() > 0)
1362 std::pair<Node *, uint64_t> top = tmp_nodes[tmp_nodes.size() - 1];
1363 uint64_t idx = (uint64_t)top.first->get_child(top.second);
1364 uint64_t x = tmp[tmp.size() - 1];
1367 top.first->move_container_index(top.second, x, this->leaf_container_vec);
1368 tmp_nodes.pop_back();
1378 this->leaf_container_vec.resize(this->leaf_container_vec.size() - k);
1391 void clear_unused_node_pointers()
1393 for (uint64_t i = 0; i < this->unused_node_pointers.size(); i++)
1395 delete this->unused_node_pointers[i];
1397 this->unused_node_pointers.clear();
1398 this->unused_node_pointers.shrink_to_fit();
1406 void create_root_leaf(VALUE value)
1408 uint64_t p = this->get_new_container_index();
1409 this->leaf_container_vec[p].push_back(value);
1410 this->root = (Node *)p;
1411 this->root_is_leaf_ =
true;
1413 if (USE_PARENT_FIELD)
1415 this->parent_vec[p] =
nullptr;
1430 void remove_empty_leaf(uint64_t idx, Node *parent, int64_t child_index)
1432 if (parent !=
nullptr)
1434 parent->remove_child(child_index);
1436 if (USE_PARENT_FIELD)
1438 this->parent_vec[idx] =
nullptr;
1441 this->unused_leaf_container_indexes.push(idx);
1442 this->leaf_container_vec[idx].clear();
1457 void remove_empty_node(Node *node, Node *parent, int64_t child_index)
1460 if (parent !=
nullptr)
1462 parent->remove_child(child_index);
1467 if (this->root == node)
1469 this->root =
nullptr;
1473 if (this->unused_node_pointers.size() <= 4096)
1475 this->unused_node_pointers.push_back(node);
1489 uint64_t get_new_container_index()
1491 if (this->unused_leaf_container_indexes.size() == 0)
1493 this->leaf_container_vec.push_back(LEAF_CONTAINER());
1494 if (USE_PARENT_FIELD)
1496 this->parent_vec.push_back(
nullptr);
1498 this->unused_leaf_container_indexes.push(this->leaf_container_vec.size() - 1);
1500 assert(this->unused_leaf_container_indexes.size() > 0);
1501 uint64_t idx = this->unused_leaf_container_indexes.top();
1502 this->unused_leaf_container_indexes.pop();
1513 Node *get_new_node_pointer()
1515 Node *new_node =
nullptr;
1516 if (this->unused_node_pointers.size() > 0)
1518 new_node = this->unused_node_pointers[this->unused_node_pointers.size() - 1];
1519 this->unused_node_pointers.pop_back();
1523 new_node =
new Node();
1540 void split_process(
const std::vector<NodePointer> &path, uint64_t t)
1542 const NodePointer &top = path[t];
1544 Node *node = top.get_node();
1545 Node *_new_right_node =
nullptr;
1546 uint64_t parent_edge_index = 0;
1549 _new_right_node = this->get_new_node_pointer();
1550 _new_right_node->initialize(top.get_node()->is_parent_of_leaves(), this->leaf_container_vec);
1554 _new_right_node = (Node *)this->get_new_container_index();
1557 Node *_parent =
nullptr;
1560 _parent = path[t - 1].get_node();
1561 _parent->insert_child(top.get_parent_edge_index() + 1, _new_right_node, 0, 0);
1562 parent_edge_index = top.get_parent_edge_index();
1566 _parent = this->get_new_node_pointer();
1569 _parent->initialize((uint64_t)node, (uint64_t)_new_right_node, this->leaf_container_vec);
1573 _parent->initialize(node, _new_right_node, this->leaf_container_vec);
1575 parent_edge_index = 0;
1578 this->root = _parent;
1579 this->root_is_leaf_ =
false;
1584 if (USE_PARENT_FIELD)
1588 this->parent_vec[(uint64_t)node] = _parent;
1592 node->set_parent(_parent);
1596 if (USE_PARENT_FIELD)
1600 this->parent_vec[(uint64_t)_new_right_node] = _parent;
1604 _new_right_node->set_parent(_parent);
1608 this->
split_node(node, _new_right_node, top.is_leaf(), _parent, parent_edge_index, this->parent_vec);
1621 uint64_t balance_for_insertion(
const std::vector<NodePointer> &path,
bool superLeftPushMode =
false)
1623 uint64_t split_counter = 0;
1624 for (int64_t t = path.size() - 1; t >= 0; --t)
1626 const NodePointer &top = path[t];
1627 uint64_t degree = top.get_degree(this->leaf_container_vec);
1628 uint64_t threshold = top.is_leaf() ? LEAF_CONTAINER_MAX_SIZE : MAX_DEGREE;
1629 uint64_t LR_threshold = threshold;
1630 if(superLeftPushMode){
1631 LR_threshold = (threshold * 3) / 4;
1634 if (degree > threshold)
1640 Node *parent = path[t - 1].get_node();
1641 uint64_t parent_edge_index = top.get_parent_edge_index();
1642 Node *leftSibling = parent_edge_index > 0 ? parent->get_child(parent_edge_index - 1) :
nullptr;
1643 Node *rightSibling = parent_edge_index + 1 < parent->children_count() ? parent->get_child(parent_edge_index + 1) :
nullptr;
1644 uint64_t leftSiblingDegree = UINT64_MAX;
1645 if (parent_edge_index > 0)
1647 leftSiblingDegree = top.is_leaf() ? this->leaf_container_vec[(uint64_t)leftSibling].
size() : leftSibling->get_degree();
1652 uint64_t rightSiblingDegree = UINT64_MAX;
1653 if (parent_edge_index + 1 < parent->children_count())
1655 rightSiblingDegree = top.is_leaf() ? this->leaf_container_vec[(uint64_t)rightSibling].
size() : rightSibling->get_degree();
1659 if (leftSiblingDegree < LR_threshold || rightSiblingDegree < LR_threshold)
1661 if (leftSiblingDegree < LR_threshold)
1663 if (superLeftPushMode)
1665 uint64_t diff = LR_threshold - leftSiblingDegree;
1666 this->
move_values_left(leftSibling, top.get_node(), diff, top.is_leaf(), parent, parent_edge_index);
1670 this->
move_values_left(leftSibling, top.get_node(), 1, top.is_leaf(), parent, parent_edge_index);
1675 this->
move_values_right(top.get_node(), rightSibling, 1, top.is_leaf(), parent, parent_edge_index);
1681 this->split_process(path, t);
1687 this->split_process(path, t);
1696 return split_counter;
1709 uint64_t balance_for_removal(
const std::vector<NodePointer> &path)
1713 uint64_t merge_counter = 0;
1715 for (int64_t t = path.size() - 1; t >= 0; --t)
1717 const NodePointer &top = path[t];
1718 uint64_t max_size = top.is_leaf() ? LEAF_CONTAINER_MAX_SIZE : MAX_DEGREE;
1719 uint64_t threshold = max_size / 2;
1721 uint64_t degree = top.get_degree(this->leaf_container_vec);
1722 if (degree >= threshold)
1730 Node *parent = path[t - 1].get_node();
1731 uint64_t parent_edge_index = top.get_parent_edge_index();
1732 Node *leftSibling = parent_edge_index > 0 ? parent->get_child(parent_edge_index - 1) :
nullptr;
1733 Node *rightSibling = parent_edge_index + 1 < parent->children_count() ? parent->get_child(parent_edge_index + 1) :
nullptr;
1734 uint64_t leftSiblingDegree = 0;
1735 if (parent_edge_index > 0)
1737 leftSiblingDegree = top.is_leaf() ? this->leaf_container_vec[(uint64_t)leftSibling].
size() : leftSibling->get_degree();
1740 uint64_t rightSiblingDegree = 0;
1741 if (parent_edge_index + 1 < parent->children_count())
1743 rightSiblingDegree = top.is_leaf() ? this->leaf_container_vec[(uint64_t)rightSibling].
size() : rightSibling->get_degree();
1746 if (leftSiblingDegree != 0 || rightSiblingDegree != 0)
1748 if (leftSiblingDegree > threshold)
1750 this->
move_values_right(leftSibling, top.get_node(), 1, top.is_leaf(), parent, parent_edge_index - 1);
1753 else if (rightSiblingDegree > threshold)
1755 this->
move_values_left(top.get_node(), rightSibling, 1, top.is_leaf(), parent, parent_edge_index + 1);
1760 assert(leftSiblingDegree == threshold || rightSiblingDegree == threshold);
1761 if (leftSiblingDegree == threshold)
1763 this->
move_values_left(leftSibling, top.get_node(), degree, top.is_leaf(), parent, parent_edge_index);
1766 this->remove_empty_leaf(top.get_leaf_container_index(), parent, parent_edge_index);
1770 this->remove_empty_node(top.get_node(), parent, parent_edge_index);
1775 this->
move_values_right(top.get_node(), rightSibling, degree, top.is_leaf(), parent, parent_edge_index);
1778 this->remove_empty_leaf(top.get_leaf_container_index(), parent, parent_edge_index);
1782 this->remove_empty_node(top.get_node(), parent, parent_edge_index);
1790 throw std::logic_error(
"Error(BPTree::balance_for_removal(1))");
1798 throw std::logic_error(
"Error(BPTree::balance_for_removal(2))");
1800 else if (degree == 1)
1802 if (!this->root_is_leaf_)
1805 bool b = this->root->is_parent_of_leaves();
1806 Node *new_root = this->root->get_child(0);
1807 this->root->remove_child(0);
1808 this->remove_empty_node(this->root,
nullptr, -1);
1809 this->root = new_root;
1810 this->root_is_leaf_ = b;
1813 if (USE_PARENT_FIELD)
1817 this->parent_vec[(uint64_t)new_root] =
nullptr;
1821 new_root->set_parent(
nullptr);
1835 return merge_counter;
1853 std::vector<VALUE> r;
1870 std::vector<NodePointer> path;
1872 if (path.size() > 0)
1874 uint64_t leaf = path[path.size() - 1].get_leaf_container_index();
1875 this->leaf_container_vec[leaf].push_front(value);
1877 uint64_t sum = this->leaf_container_vec[leaf].psum(0);
1879 for (int64_t i = path.size() - 2; i >= 0; --i)
1881 Node *parent = path[i].get_node();
1882 uint64_t parent_edge_index = path[i + 1].get_parent_edge_index();
1883 parent->increment(parent_edge_index, 1, sum);
1885 this->balance_for_insertion(path,
true);
1889 this->create_root_leaf(value);
1906 uint64_t push_many_to_leaf(
const std::vector<VALUE> &values, uint64_t value_pos,
const std::vector<NodePointer> &path)
1909 uint64_t leaf = path[path.size() - 1].get_leaf_container_index();
1911 while ((value_pos + x) < values.size() && leaf_container_vec[leaf].size() <= this->get_max_count_of_values_in_leaf())
1914 this->leaf_container_vec[leaf].push_back(values[value_pos + x]);
1919 uint64_t sum = len > 0 ? this->leaf_container_vec[leaf].reverse_psum(len - 1) : 0;
1921 for (int64_t j = path.size() - 2; j >= 0; --j)
1923 Node *parent = path[j].get_node();
1924 uint64_t parent_edge_index = path[j + 1].get_parent_edge_index();
1925 assert(parent_edge_index < parent->children_count());
1927 parent->increment(parent_edge_index, len, sum);
1930 this->balance_for_insertion(path,
true);
1946 void push_back_to_internal_node(uint64_t leaf_index,
const std::vector<NodePointer> &path)
1948 Node *node = path[path.size() - 1].get_node();
1949 uint64_t child_count = this->leaf_container_vec[leaf_index].size();
1950 uint64_t child_sum = 0;
1951 if constexpr (USE_PSUM)
1953 child_sum = this->leaf_container_vec[leaf_index].psum();
1955 node->append_child(leaf_index, child_count, child_sum);
1957 for (int64_t j = path.size() - 2; j >= 0; --j)
1959 Node *parent = path[j].get_node();
1960 uint64_t parent_edge_index = path[j + 1].get_parent_edge_index();
1961 assert(parent_edge_index < parent->children_count());
1962 parent->increment(parent_edge_index, child_count, child_sum);
1965 this->balance_for_insertion(path,
true);
1981 std::vector<NodePointer> path;
1982 while (i < containers.size())
1986 if (path.size() > 1)
1988 uint64_t p = this->get_new_container_index();
1989 this->leaf_container_vec[p].swap(containers[i]);
1991 this->push_back_to_internal_node(p, path);
1997 std::vector<VALUE> tmp_values;
1998 containers[i].to_values(tmp_values);
2018 std::vector<NodePointer> path;
2021 while (i < values.size())
2025 if (path.size() > 0)
2027 i += this->push_many_to_leaf(values, i, path);
2031 this->create_root_leaf(values[i]);
2047 uint64_t
remove_using_path(
const std::vector<NodePointer> &path, uint64_t position_in_leaf_container)
2049 uint64_t merge_counter = 0;
2050 uint64_t x = path[path.size() - 1].get_leaf_container_index();
2051 int64_t delta = leaf_container_vec[x].psum(position_in_leaf_container, position_in_leaf_container);
2052 leaf_container_vec[x].remove(position_in_leaf_container);
2053 for (int64_t i = path.size() - 2; i >= 0; i--)
2055 Node *node = path[i].get_node();
2056 uint64_t child_index = path[i + 1].get_parent_edge_index();
2058 node->increment(child_index, -1, -delta);
2061 if (path.size() > 1)
2063 merge_counter += this->balance_for_removal(this->tmp_path);
2067 assert(path.size() == 1);
2068 if (leaf_container_vec[x].
size() == 0)
2070 this->remove_empty_leaf((uint64_t)this->root,
nullptr, -1);
2071 this->root =
nullptr;
2072 this->root_is_leaf_ =
false;
2076 return merge_counter;
2092 assert(pos < this->
size());
2093 this->remove_operation_counter++;
2096 this->merge_process_counter += this->
remove_using_path(this->tmp_path, position_to_remove);
2100 throw std::invalid_argument(
"Error in BPTree::remove(pos). This tree is empty. pos = " + std::to_string(pos));
2122 void insert(uint64_t pos, VALUE value, uint64_t sum_delta)
2124 if (pos < this->
size())
2128 assert(pos <= this->
size());
2132 if (position_to_insert != -1)
2134 uint64_t x = this->tmp_path[this->tmp_path.size() - 1].get_leaf_container_index();
2138 this->leaf_container_vec[x].insert(position_to_insert, value);
2140 for (int64_t i = this->tmp_path.size() - 2; i >= 0; i--)
2142 Node *node = this->tmp_path[i].get_node();
2143 uint64_t child_index = this->tmp_path[i + 1].get_parent_edge_index();
2145 assert(child_index < node->children_count());
2148 node->increment(child_index, 1, sum_delta);
2150 this->split_process_counter += this->balance_for_insertion(this->tmp_path);
2154 throw std::runtime_error(
"Error: insert");
2162 this->create_root_leaf(value);
2166 throw std::invalid_argument(
"Error(BPTree::insert)");
2172 assert(pos == this->
size());
2175 this->insert_operation_counter++;
2194 void resize(uint64_t _size, VALUE default_value)
2196 if (this->
size() < _size)
2199 std::vector<NodePointer> path;
2200 uint64_t diff = _size - this->
size();
2206 if (path.size() > 0)
2208 uint64_t leaf = path[path.size() - 1].get_leaf_container_index();
2212 this->leaf_container_vec[leaf].push_back(default_value);
2216 uint64_t sum = len > 0 ? this->leaf_container_vec[leaf].reverse_psum(len - 1) : 0;
2218 for (int64_t j = path.size() - 2; j >= 0; --j)
2220 Node *parent = path[j].get_node();
2221 uint64_t parent_edge_index = path[j + 1].get_parent_edge_index();
2222 parent->increment(parent_edge_index, len, sum);
2224 this->balance_for_insertion(path,
true);
2228 this->create_root_leaf(default_value);
2235 while (this->
size() > _size)
2249 this->linked_tree_ = _tree;
2259 return this->linked_tree_;
2286 uint64_t left_leaf = (uint64_t)left_node;
2287 uint64_t right_leaf = (uint64_t)right_node;
2288 assert(left_leaf < this->leaf_container_vec.size());
2289 assert(right_leaf < this->leaf_container_vec.size());
2291 if constexpr (USE_PSUM){
2292 if (parent !=
nullptr)
2294 assert(this->leaf_container_vec[left_leaf].
psum() == parent->access_sum_deque(parent_edge_index_of_left_node));
2295 int64_t sum = len != 0 ? this->leaf_container_vec[left_leaf].reverse_psum(len - 1) : 0;
2297 assert(sum <= (int64_t)this->leaf_container_vec[left_leaf].
psum());
2303 parent->decrement_on_sum_deque(parent_edge_index_of_left_node, sum);
2304 parent->increment_on_sum_deque(parent_edge_index_of_left_node + 1, sum);
2310 if (parent !=
nullptr)
2312 parent->decrement_on_count_deque(parent_edge_index_of_left_node, len);
2313 parent->increment_on_count_deque(parent_edge_index_of_left_node + 1, len);
2315 auto items = this->leaf_container_vec[left_leaf].pop_back(len);
2316 this->leaf_container_vec[right_leaf].push_front(items);
2320 BPFunctions::move_right(*left_node, *right_node, len, parent, parent_edge_index_of_left_node, this->parent_vec);
2340 uint64_t left_leaf = (uint64_t)left_node;
2341 uint64_t right_leaf = (uint64_t)right_node;
2342 assert(left_leaf < this->leaf_container_vec.size());
2344 if (USE_PSUM && parent !=
nullptr)
2346 uint64_t sum = len != 0 ? this->leaf_container_vec[right_leaf].psum(len - 1) : 0;
2347 parent->decrement_on_sum_deque(parent_edge_index_of_right_node, sum);
2348 parent->increment_on_sum_deque(parent_edge_index_of_right_node - 1, sum);
2351 if (parent !=
nullptr)
2353 parent->decrement_on_count_deque(parent_edge_index_of_right_node, len);
2354 parent->increment_on_count_deque(parent_edge_index_of_right_node - 1, len);
2356 auto items = this->leaf_container_vec[right_leaf].pop_front(len);
2357 this->leaf_container_vec[left_leaf].push_back(items);
2361 BPFunctions::move_left(*left_node, *right_node, len, parent, parent_edge_index_of_right_node, this->parent_vec);
2379 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)
2382 uint64_t degree = 0;
2385 degree = leaf_container_vec[(uint64_t)left_node].
size();
2386 assert((uint64_t)left_node < this->leaf_container_vec.size());
2387 assert((uint64_t)right_node < this->leaf_container_vec.size());
2392 degree = left_node->get_degree();
2394 uint64_t left_len = degree / 2;
2395 uint64_t right_len = degree - left_len;
2396 this->
move_values_right(left_node, right_node, right_len, is_leaf, parent, parent_edge_index_of_left_node);
2414 NodePointer &leaf_pointer = this->tmp_path[this->tmp_path.size() - 1];
2415 LEAF_CONTAINER &leaf = this->leaf_container_vec[leaf_pointer.get_leaf_container_index()];
2416 leaf.increment(pos, delta);
2417 for (int64_t i = this->tmp_path.size() - 2; i >= 0; --i)
2419 uint64_t idx = this->tmp_path[i + 1].get_parent_edge_index();
2420 Node *parent = this->tmp_path[i].get_node();
2421 parent->increment(idx, 0, delta);
2441 if (prev + 1 != (int64_t)(*it))
2454 void print_debug_info()
const{
2455 std::cout <<
"BPTree::print_debug_info()" << std::endl;
2463 std::cout <<
"BPTree::time_count: " << (double)BPTree::time_count / 1000000.0 <<
" ms" << std::endl;
2464 std::cout <<
"BPTree::time_count2: " << (double)bptree::time_count2 / 1000000.0 <<
" ms" << std::endl;
2475 void preprocess_for_the_exchange_of_two_leaves([[maybe_unused]] uint64_t leaf_index1, [[maybe_unused]] uint64_t leaf_index2)
2491 void exchange(stool::SimpleDeque16<Node *> &children1, uint64_t j, uint64_t leaf_index2)
2493 uint64_t leaf_index1 = (uint64_t)children1[j];
2494 assert(this->parent_vec[leaf_index1] !=
nullptr);
2496 if (leaf_index1 != leaf_index2)
2498 this->preprocess_for_the_exchange_of_two_leaves(leaf_index1, leaf_index2);
2500 if (this->parent_vec[leaf_index2] !=
nullptr)
2502 auto &children2 = this->parent_vec[leaf_index2]->get_children();
2503 uint64_t idx = this->parent_vec[leaf_index2]->get_index((Node *)leaf_index2);
2504 this->leaf_container_vec[leaf_index2].swap(this->leaf_container_vec[leaf_index1]);
2505 children1[j] = (Node *)leaf_index2;
2506 children2[idx] = (Node *)leaf_index1;
2510 this->leaf_container_vec[leaf_index2].swap(this->leaf_container_vec[leaf_index1]);
2511 children1[j] = (Node *)leaf_index2;
2514 Node *tmp_n = this->parent_vec[leaf_index1];
2515 this->parent_vec[leaf_index1] = this->parent_vec[leaf_index2];
2516 this->parent_vec[leaf_index2] = tmp_n;
2539 if (this->
size() == 0 || this->root_is_leaf_)
2546 if (!USE_PARENT_FIELD)
2548 this->parent_vec.resize(this->leaf_container_vec.size(),
nullptr);
2555 Node *node = np.get_node();
2556 if (node->is_parent_of_leaves())
2558 auto &children = node->get_children();
2559 for (
Node *v : children)
2561 uint64_t leaf = (uint64_t)v;
2562 this->parent_vec[leaf] = node;
2568 uint64_t counter = 0;
2575 Node *node = np.get_node();
2576 if (node->is_parent_of_leaves())
2578 uint64_t _size = node->children_count();
2579 auto &children1 = node->get_children();
2581 for (uint64_t j = 0; j < _size; j++)
2583 this->exchange(children1, j, counter);
2590 while (this->leaf_container_vec.size() > counter)
2592 this->leaf_container_vec.pop_back();
2593 this->parent_vec.pop_back();
2595 while (this->unused_leaf_container_indexes.size() > 0)
2597 this->unused_leaf_container_indexes.pop();
2600 if (!USE_PARENT_FIELD)
2602 std::vector<Node *> tmp;
2603 this->parent_vec.swap(tmp);
2606 if (this->root_is_leaf_)
2608 this->root = (
Node *)0;
2627 assert(nodes.size() > 0);
2628 std::vector<Node *> r;
2629 if (nodes.size() == 1)
2631 this->root = nodes[0];
2632 this->root_is_leaf_ =
false;
2633 this->height_ = current_height;
2635 else if (nodes.size() <= MAX_DEGREE)
2638 Node *root = this->get_new_node_pointer();
2639 root->initialize(
false, this->leaf_container_vec);
2640 for (uint64_t i = 0; i < nodes.size(); i++)
2642 if (USE_PARENT_FIELD)
2644 nodes[i]->set_parent(root);
2646 uint64_t count = nodes[i]->psum_on_count_deque();
2648 if constexpr (USE_PSUM)
2650 sum = nodes[i]->psum_on_sum_deque();
2652 root->append_child(nodes[i], count, sum);
2659 uint64_t counter = nodes.size();
2660 uint64_t threshold = MAX_DEGREE * 2;
2664 if (counter >= threshold)
2668 else if (counter > MAX_DEGREE)
2676 Node *node = this->get_new_node_pointer();
2677 node->initialize(
false, this->leaf_container_vec);
2679 for (uint64_t j = 0; j < d; j++)
2681 if (USE_PARENT_FIELD)
2683 nodes[i]->set_parent(node);
2685 uint64_t count = nodes[i]->psum_on_count_deque();
2687 if constexpr (USE_PSUM)
2689 sum = nodes[i]->psum_on_sum_deque();
2691 node->append_child(nodes[i], count, sum);
2712 std::vector<Node *> r;
2714 if (this->leaf_container_vec.size() == 0)
2716 this->root =
nullptr;
2717 this->root_is_leaf_ =
false;
2720 else if (this->leaf_container_vec.size() == 1)
2722 this->root = (
Node *)0;
2723 this->root_is_leaf_ =
true;
2726 else if (this->leaf_container_vec.size() <= MAX_DEGREE)
2728 Node *root = this->get_new_node_pointer();
2729 root->initialize(
true, this->leaf_container_vec);
2730 for (uint64_t i = 0; i < this->leaf_container_vec.size(); i++)
2733 if constexpr (USE_PSUM)
2735 psum += this->leaf_container_vec[i].psum();
2737 if (USE_PARENT_FIELD)
2739 this->parent_vec[i] = root;
2742 root->append_child((
Node *)i, this->leaf_container_vec[i].size(),
psum);
2750 uint64_t counter = this->leaf_container_vec.size();
2751 uint64_t threshold = MAX_DEGREE * 2;
2755 if (counter >= threshold)
2759 else if (counter > MAX_DEGREE)
2767 Node *node = this->get_new_node_pointer();
2768 node->initialize(
true, this->leaf_container_vec);
2770 for (uint64_t j = 0; j < d; j++)
2773 if constexpr (USE_PSUM)
2775 psum += this->leaf_container_vec[i].psum();
2777 if (USE_PARENT_FIELD)
2779 this->parent_vec[i] = node;
2781 node->append_child((
Node *)i, this->leaf_container_vec[i].size(),
psum);
2803 if (_values.size() == 0)
2806 else if (_values.size() <= LEAF_CONTAINER_MAX_SIZE)
2808 uint64_t leaf_index = this->get_new_container_index();
2810 while (i < _values.size())
2812 this->leaf_container_vec[leaf_index].push_back(_values[i]);
2818 uint64_t threshold = LEAF_CONTAINER_MAX_SIZE * 2;
2819 uint64_t counter = _values.size();
2821 while (i < _values.size())
2824 if (counter >= threshold)
2826 d = LEAF_CONTAINER_MAX_SIZE;
2828 else if (counter > LEAF_CONTAINER_MAX_SIZE)
2830 d = LEAF_CONTAINER_MAX_SIZE / 2;
2836 assert(counter >= (LEAF_CONTAINER_MAX_SIZE / 2));
2838 uint64_t leaf_index = this->get_new_container_index();
2839 for (uint64_t j = 0; j < d; j++)
2841 this->leaf_container_vec[leaf_index].push_back(_values[i]);
2858 void build(
const std::vector<VALUE> &_values)
2864 uint64_t current_height = 2;
2865 while (layer.size() > 0)
2869 layer.swap(next_layer);
2887 this->leaf_container_vec.swap(_leaf_containers);
2888 if (USE_PARENT_FIELD)
2890 this->parent_vec.resize(this->leaf_container_vec.size(),
nullptr);
2894 uint64_t current_height = 2;
2895 while (layer.size() > 0)
2898 layer.swap(next_layer);
2920 uint64_t _max_degree = MAX_DEGREE;
2921 uint64_t _max_count_of_values_in_leaf = LEAF_CONTAINER_MAX_SIZE;
2923 uint64_t _size =
sizeof(_max_degree) +
sizeof(_max_count_of_values_in_leaf) + LEAF_CONTAINER::get_byte_size(bp.leaf_container_vec);
2924 if (pos + _size > output.size())
2926 output.resize(pos + _size);
2929 std::memcpy(output.data() + pos, &_max_degree,
sizeof(uint64_t));
2930 pos +=
sizeof(uint64_t);
2931 std::memcpy(output.data() + pos, &_max_count_of_values_in_leaf,
sizeof(uint64_t));
2932 pos +=
sizeof(uint64_t);
2934 LEAF_CONTAINER::store_to_bytes(bp.leaf_container_vec, output, pos);
2951 uint64_t _max_degree = MAX_DEGREE;
2952 uint64_t _max_count_of_values_in_leaf = LEAF_CONTAINER_MAX_SIZE;
2954 os.write((
const char *)(&_max_degree),
sizeof(uint64_t));
2955 os.write((
const char *)(&_max_count_of_values_in_leaf),
sizeof(uint64_t));
2956 LEAF_CONTAINER::store_to_file(bp.leaf_container_vec, os);
2971 uint64_t _max_degree;
2972 uint64_t _max_count_of_values_in_leaf;
2974 std::memcpy(&_max_degree, data.data() + pos,
sizeof(uint64_t));
2975 pos +=
sizeof(uint64_t);
2976 std::memcpy(&_max_count_of_values_in_leaf, data.data() + pos,
sizeof(uint64_t));
2977 pos +=
sizeof(uint64_t);
2979 auto tmp = LEAF_CONTAINER::load_vector(data, pos);
2996 uint64_t _max_degree;
2997 uint64_t _max_count_of_values_in_leaf;
2998 ifs.read((
char *)(&_max_degree),
sizeof(uint64_t));
2999 ifs.read((
char *)(&_max_count_of_values_in_leaf),
sizeof(uint64_t));
3001 auto tmp = LEAF_CONTAINER::load_vector(ifs);
3006 void print_information_about_performance(
int message_paragraph = stool::Message::SHOW_MESSAGE)
const{
3007 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Performance Information (BPTree)[" << std::endl;
3008 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of insertion operations: " << this->insert_operation_counter << std::endl;
3009 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of split process in insertion operations: " << this->split_process_counter << std::endl;
3010 if(this->insert_operation_counter > 0){
3011 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;
3014 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of removal operations: " << this->remove_operation_counter << std::endl;
3015 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"The number of merge process in removal operations: " << this->merge_process_counter << std::endl;
3016 if(this->remove_operation_counter > 0){
3017 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;
3020 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"]" << std::endl;
3040 uint64_t internal_node_count = 0;
3041 uint64_t leaf_count = 0;
3042 uint64_t total_degree_of_internal_node = 0;
3049 internal_node_count++;
3050 total_degree_of_internal_node += np.get_node()->children_count();
3058 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Statistics(BPTree):" << std::endl;
3059 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of internal nodes: " << internal_node_count << std::endl;
3060 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of used leaf containers: " << leaf_count << std::endl;
3061 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The height of this tree: " << this->height_ << std::endl;
3062 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of stored values: " << this->
size() << std::endl;
3064 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The max degree of internal node (parameter): " << MAX_DEGREE << std::endl;
3065 if (internal_node_count > 0)
3067 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;
3069 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The max count of values in leaf (parameter): " << LEAF_CONTAINER_MAX_SIZE << std::endl;
3070 if (this->
size() > 0)
3072 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The average count of values in leaf (parameter): " << (this->
size() / leaf_count) << std::endl;
3075 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of unused nodes: " << this->unused_node_pointers.size() << std::endl;
3076 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of unused leaf containers: " << this->unused_leaf_container_indexes.size() << std::endl;
3077 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The number of stored parent pointers: " << this->parent_vec.size() << std::endl;
3080 uint64_t num = this->
size();
3081 if(USE_PARENT_FIELD){
3082 total_memory_usage += this->parent_vec.size() *
sizeof(
Node *);
3084 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;
3085 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"[END]" << std::endl;