2#include "./permutation/bp_tree_template.hpp"
37 this->set_linked_tree();
45 this->pi_tree = std::move(other.pi_tree);
46 this->inverse_pi_tree = std::move(other.inverse_pi_tree);
47 this->set_linked_tree();
75 this->pi_tree = std::move(other.pi_tree);
76 this->inverse_pi_tree = std::move(other.inverse_pi_tree);
77 this->pi_tree.set_linked_tree(&this->inverse_pi_tree);
78 this->inverse_pi_tree.set_linked_tree(&this->pi_tree);
103 return this->inverse_pi_tree;
110 return this->pi_tree.get_max_degree_of_internal_node();
117 return this->pi_tree.size();
124 return this->pi_tree.size_in_bytes() + this->inverse_pi_tree.size_in_bytes();
141 uint64_t idx1 = this->pi_tree.compute_path_from_root_to_leaf(i);
142 const std::vector<NodePointer> &path =
const_cast<std::vector<NodePointer> &
>(this->pi_tree.get_temporary_path());
143 return this->
access(path, idx1);
153 uint64_t idx1 = this->inverse_pi_tree.compute_path_from_root_to_leaf(i);
154 const std::vector<NodePointer> &path =
const_cast<std::vector<NodePointer> &
>(this->inverse_pi_tree.get_temporary_path());
156 assert(path.size() > 0);
157 const NodePointer &leaf_pointer = path[path.size() - 1];
158 uint64_t leaf_index = leaf_pointer.get_leaf_container_index();
163 uint64_t idx2 = leaf2.get_index(
PermutationItem(leaf_index, item.key));
165 return this->pi_tree.get_value_index(item.pointer, idx2);
179 std::stringstream ss;
181 ss << stool::ConverterToString::to_integer_string(vec);
190 std::vector<uint64_t> r;
192 for (uint64_t i = 0; i <
size; i++)
194 r.push_back(this->
access(i));
204 std::vector<uint64_t> r;
206 for (uint64_t i = 0; i <
size; i++)
224 this->pi_tree.set_linked_tree(
nullptr);
225 this->inverse_pi_tree.set_linked_tree(
nullptr);
226 this->pi_tree.clear();
227 this->inverse_pi_tree.clear();
228 this->pi_tree.set_linked_tree(&this->inverse_pi_tree);
229 this->inverse_pi_tree.set_linked_tree(&this->pi_tree);
236 this->pi_tree.swap(item.pi_tree,
false);
237 this->inverse_pi_tree.swap(item.inverse_pi_tree,
false);
244 void insert(int64_t pi_index_p, int64_t inverse_pi_index_q)
246 assert(pi_index_p <= (int64_t)this->pi_tree.size());
247 assert(inverse_pi_index_q <= (int64_t)this->inverse_pi_tree.size());
249 uint64_t _size1 = this->inverse_pi_tree.get_leaf_container_vector_size();
250 uint64_t _size2 = this->pi_tree.get_leaf_container_vector_size();
252 this->pi_tree.insert(pi_index_p,
PermutationItem(_size1 + 1, UINT8_MAX), 0);
253 this->inverse_pi_tree.insert(inverse_pi_index_q,
PermutationItem(_size2 + 1, UINT8_MAX), 0);
256 uint64_t value_idx1 = this->pi_tree.compute_path_from_root_to_leaf(pi_index_p);
257 uint64_t value_idx2 = this->inverse_pi_tree.compute_path_from_root_to_leaf(inverse_pi_index_q);
258 const std::vector<NodePointer> &path1 = this->pi_tree.get_temporary_path();
259 const std::vector<NodePointer> &path2 = this->inverse_pi_tree.get_temporary_path();
261 uint64_t idx1 = path1[path1.size() - 1].get_leaf_container_index();
262 uint64_t idx2 = path2[path2.size() - 1].get_leaf_container_index();
265 uint64_t key = cont1.get_new_key(idx2);
276 uint64_t idx1 = this->pi_tree.compute_path_from_root_to_leaf(pi_index_p);
277 const std::vector<NodePointer> &path =
const_cast<std::vector<NodePointer> &
>(this->pi_tree.get_temporary_path());
278 uint64_t inverse_pi_index_q = this->
access(path, idx1);
279 this->pi_tree.remove_using_path(path, idx1);
280 assert(inverse_pi_index_q < this->inverse_pi_tree.size());
281 this->inverse_pi_tree.remove(inverse_pi_index_q);
282 assert(this->pi_tree.size() == this->inverse_pi_tree.size());
291 int64_t inverse_pi_index_q = this->
access(from_p);
294 this->
insert(to_x + 1, inverse_pi_index_q);
297 else if (from_p > to_x)
300 this->
insert(to_x, inverse_pi_index_q);
309 this->pi_tree.sort_leaf_containers();
310 this->inverse_pi_tree.sort_leaf_containers();
318 template <
typename PI_ITERATOR_BEGIN,
typename PI_ITERATOR_END>
319 void build(PI_ITERATOR_BEGIN beg, [[maybe_unused]] PI_ITERATOR_END end, uint64_t pi_size,
int message_paragraph = stool::Message::SHOW_MESSAGE)
322 if (message_paragraph >= 0 && pi_size > 0)
324 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Constructing Dynamic Permutation... " <<
"(input size = " << pi_size <<
")" << std::endl;
326 std::chrono::system_clock::time_point st1, st2;
327 st1 = std::chrono::system_clock::now();
333 this->pi_tree.set_linked_tree(
nullptr);
334 this->inverse_pi_tree.set_linked_tree(
nullptr);
337 default_item.key = 0;
338 default_item.pointer = 0;
339 this->pi_tree.resize(pi_size, default_item);
340 this->inverse_pi_tree.resize(pi_size, default_item);
344 this->pi_tree.set_linked_tree(&this->inverse_pi_tree);
345 this->inverse_pi_tree.set_linked_tree(&this->pi_tree);
347 uint64_t message_counter = 10000;
348 uint64_t processed_node_counter = 0;
350 [[maybe_unused]] uint64_t i = 0;
351 for (
auto it = this->pi_tree.get_postorder_iterator_begin(); it != this->pi_tree.get_postorder_iterator_end(); ++it)
354 processed_node_counter++;
355 if (message_paragraph >= 0 && message_counter > 10000)
358 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"Processing... [" << (processed_node_counter / 1000) <<
"KB] \r" << std::flush;
364 uint64_t pi_leaf_idx = (*it).get_leaf_container_index();
366 std::unordered_map<uint64_t, uint64_t> mapper;
367 for (uint64_t j = 0; j < leaf.size(); j++)
369 uint64_t idx = this->inverse_pi_tree.compute_path_from_root_to_leaf(*beg);
371 const auto &path = this->inverse_pi_tree.get_temporary_path();
372 uint64_t inv_leaf_idx = path[path.size() - 1].get_leaf_container_index();
376 auto f = mapper.find(inv_leaf_idx);
377 if (f == mapper.end())
379 mapper[inv_leaf_idx] = 0;
381 uint64_t key = mapper[inv_leaf_idx];
385 mapper[inv_leaf_idx] = key + 1;
391 st2 = std::chrono::system_clock::now();
393 if (message_paragraph >= 0 && pi_size > 0)
395 uint64_t sec_time = std::chrono::duration_cast<std::chrono::seconds>(st2 - st1).count();
396 uint64_t ms_time = std::chrono::duration_cast<std::chrono::milliseconds>(st2 - st1).count();
397 uint64_t per_time = ((double)ms_time / (
double)pi_size) * 1000000;
398 std::cout << std::endl;
400 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"[END], the number of nodes = " << processed_node_counter <<
", Elapsed Time: " << sec_time <<
" sec (" << per_time <<
" ms/MB)" << std::endl;
416 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Performance Information (DynamicPermutation)[" << std::endl;
417 this->pi_tree.print_information_about_performance(message_paragraph + 1);
418 this->inverse_pi_tree.print_information_about_performance(message_paragraph + 1);
419 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"]" << std::endl;
427 std::vector<std::string> log1 = this->pi_tree.get_memory_usage_info(message_paragraph + 1);
428 std::vector<std::string> log2 = this->inverse_pi_tree.get_memory_usage_info(message_paragraph + 1);
430 std::vector<std::string> r;
431 r.push_back(
"=Dynamic Permutation: " + std::to_string(this->
size_in_bytes()) +
" bytes ( " + std::to_string(this->
size_in_bytes() / this->
size()) +
" bytes per element) = ");
432 for (std::string &s : log1)
436 for (std::string &s : log2)
450 for (std::string &s : log)
452 std::cout << s << std::endl;
461 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Statistics(DynamicPermutation):" << std::endl;
462 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"The size of permutation: " << this->
size() << std::endl;
463 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"Estimated memory usage: " << this->
size_in_bytes() <<
" bytes" << std::endl;
464 this->pi_tree.print_statistics(message_paragraph + 1);
465 this->inverse_pi_tree.print_statistics(message_paragraph + 1);
466 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"[END]" << std::endl;
472 void print_content(
int message_paragraph = stool::Message::SHOW_MESSAGE)
const
474 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"Content(DynamicPermutation):" << std::endl;
476 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"PI: \t" << stool::ConverterToString::to_integer_string(pi_vector) << std::endl;
478 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) <<
"Inverse PI: \t" << stool::ConverterToString::to_integer_string(inverse_pi_vector) << std::endl;
479 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"[END]" << std::endl;
485 void print_trees(
int message_paragraph = stool::Message::SHOW_MESSAGE)
const
487 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"========= DP ========" << std::endl;
488 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"PI: " << std::endl;
490 stool::DebugPrinter::print_integers(pi_vec, stool::Message::get_paragraph_string(message_paragraph) +
"pi_vector");
491 this->pi_tree.print_tree();
492 this->pi_tree.print_leaves();
493 std::cout << std::endl;
494 std::cout <<
"Inv_PI: " << std::endl;
496 stool::DebugPrinter::print_integers(inv_pi_vec, stool::Message::get_paragraph_string(message_paragraph) +
"inverse_pi_vector");
497 this->inverse_pi_tree.print_tree();
498 this->inverse_pi_tree.print_internal_nodes();
499 this->inverse_pi_tree.print_leaves();
500 std::cout << stool::Message::get_paragraph_string(message_paragraph) <<
"=====================" << std::endl;
508 assert(this->pi_tree.get_linked_tree() == &this->inverse_pi_tree);
509 assert(this->inverse_pi_tree.get_linked_tree() == &this->pi_tree);
524 Tree pi_tree = Tree::load_from_bytes(data, pos);
525 Tree inverse_pi_tree = Tree::load_from_bytes(data, pos);
526 r.pi_tree.swap(pi_tree,
false);
527 r.inverse_pi_tree.swap(inverse_pi_tree,
false);
537 Tree pi_tree = Tree::load_from_file(ifs);
538 Tree inverse_pi_tree = Tree::load_from_file(ifs);
539 r.pi_tree.swap(pi_tree,
false);
540 r.inverse_pi_tree.swap(inverse_pi_tree,
false);
549 item.pi_tree.sort_leaf_containers();
550 item.inverse_pi_tree.sort_leaf_containers();
551 Tree::store_to_bytes(item.pi_tree, output, pos);
552 Tree::store_to_bytes(item.inverse_pi_tree, output, pos);
559 Tree::store_to_file(item.pi_tree, os);
560 Tree::store_to_file(item.inverse_pi_tree, os);
566 int64_t
access(
const std::vector<NodePointer> &path, uint64_t position_to_leaf_index)
const
568 const NodePointer &leaf_pointer = path[path.size() - 1];
570 uint64_t leaf_index = leaf_pointer.get_leaf_container_index();
575 uint64_t idx2 = leaf2.get_index(
PermutationItem(leaf_index, item.key));
577 uint64_t result = this->inverse_pi_tree.get_value_index(item.pointer, idx2);
581 void set_linked_tree(){
582 this->pi_tree.set_linked_tree(&this->inverse_pi_tree);
583 this->inverse_pi_tree.set_linked_tree(&this->pi_tree);
The iterator of a post-order traversal on BPTree [Unchecked AI's Comment].
Definition bp_postorder_iterator.hpp:13