16 stool::NaiveFLCVector<false> keys;
17 stool::NaiveFLCVector<false> pointers;
20 static constexpr uint64_t ___PermutationLeafSize = 252;
35 using iterator_category = std::bidirectional_iterator_tag;
36 using difference_type = std::ptrdiff_t;
41 return _m_deq->at(this->_m_idx);
114 PermutationIterator begin()
const
118 PermutationIterator end()
const
120 return PermutationIterator(
const_cast<PermutationContainer *
>(
this), this->size());
123 uint64_t size()
const
125 return this->pointers.size();
127 uint64_t size_in_bytes(
bool only_extra_bytes)
const
129 if(only_extra_bytes){
130 return this->keys.size_in_bytes(
true) + this->pointers.size_in_bytes(
true);
132 return sizeof(PermutationContainer) + this->keys.size_in_bytes(
true) + this->pointers.size_in_bytes(
true);
135 uint64_t unused_size_in_bytes()
const
137 return this->keys.unused_size_in_bytes() + this->pointers.unused_size_in_bytes();
141 PermutationItem at(uint64_t pos)
const
143 assert(pos < this->keys.size());
144 assert(pos < this->pointers.size());
146 return PermutationItem(this->pointers.at(pos), this->keys[pos]);
150 std::cout << this->to_string() << std::endl;
156 this->pointers.clear();
158 assert(this->keys.size() == this->pointers.size());
160 void swap(PermutationContainer &item)
162 assert(item.keys.size() == item.pointers.size());
164 this->keys.swap(item.keys);
165 this->pointers.swap(item.pointers);
167 assert(this->keys.size() == this->pointers.size());
169 static std::string name()
173 uint64_t psum([[maybe_unused]] uint64_t i)
const noexcept
177 uint64_t psum() const noexcept
181 int64_t search([[maybe_unused]] uint64_t x)
const noexcept
185 int64_t get_index(
const PermutationItem &&item)
const
187 int64_t size = this->pointers.
size();
188 for(int64_t i = 0; i < size; i++){
189 if(this->pointers[i] == item.pointer && this->keys[i] == item.key){
207 std::string to_string()
const
209 assert(this->keys.size() == this->pointers.size());
214 int64_t size = this->pointers.size();
215 for(int64_t i = 0; i < size; i++){
216 s +=
"(" + std::to_string(this->pointers[i]) +
", " + std::to_string(this->keys[i]) +
")";
217 if (i + 1 < (int64_t)this->size())
227 std::vector<PermutationItem> to_value_vector()
const
229 throw std::runtime_error(
"PermutationContainer::NO IMP1");
232 void insert(uint64_t pos, PermutationItem value)
234 this->keys.insert(pos, value.key);
235 this->pointers.insert(pos, value.pointer);
237 assert(this->keys.size() == this->pointers.size());
239 void remove(uint64_t pos)
241 this->keys.remove(pos);
242 this->pointers.remove(pos);
244 assert(this->keys.size() == this->pointers.size());
246 void push_front(
const std::vector<PermutationItem> &new_items)
248 std::vector<uint64_t> tmp_keys;
249 std::vector<uint64_t> tmp_pointers;
250 tmp_keys.resize(new_items.size());
251 tmp_pointers.resize(new_items.size());
253 for (int64_t i = 0; i < (int64_t)new_items.size(); i++)
255 tmp_keys[i] = new_items[i].key;
256 tmp_pointers[i] = new_items[i].pointer;
258 this->keys.push_front(tmp_keys);
259 this->pointers.push_front(tmp_pointers);
269 assert(this->keys.size() == this->pointers.size());
271 void push_front(
const PermutationItem &new_item)
273 this->keys.push_front(new_item.key);
274 this->pointers.push_front(new_item.pointer);
276 assert(this->keys.size() == this->pointers.size());
279 void push_back(
const std::vector<PermutationItem> &new_items)
281 for (
const PermutationItem &item : new_items)
283 this->keys.push_back(item.key);
284 this->pointers.push_back(item.pointer);
287 assert(this->keys.size() == this->pointers.size());
289 void push_back(PermutationItem value)
291 this->keys.push_back(value.key);
292 this->pointers.push_back(value.pointer);
294 assert(this->keys.size() == this->pointers.size());
296 PermutationItem pop_front()
298 uint64_t key = this->keys[0];
299 uint64_t pointer = this->pointers.head();
300 this->keys.pop_front();
301 this->pointers.pop_front();
303 assert(this->keys.size() == this->pointers.size());
304 return PermutationItem(pointer, key);
307 std::vector<PermutationItem> pop_front(uint64_t len)
309 std::vector<PermutationItem> r;
312 for (uint64_t i = 0; i < len; i++)
314 uint64_t key = this->keys[i];
315 uint64_t pointer = this->pointers[i];
316 r[i] = PermutationItem(pointer, key);
318 this->keys.pop_front(len);
319 this->pointers.pop_front(len);
321 assert(this->keys.size() == this->pointers.size());
325 PermutationItem pop_back()
327 assert(this->keys.size() > 0 && this->pointers.size() > 0);
328 uint64_t key = this->keys[this->keys.size() - 1];
329 uint64_t pointer = this->pointers.tail();
330 this->keys.pop_back();
331 this->pointers.pop_back();
333 assert(this->keys.size() == this->pointers.size());
334 return PermutationItem(pointer, key);
337 std::vector<PermutationItem> pop_back(uint64_t len)
339 std::vector<PermutationItem> tmp1;
344 tmp1[k--] = this->pop_back();
347 assert(this->keys.size() == this->pointers.size());
350 uint64_t reverse_psum([[maybe_unused]] uint64_t i)
const
354 uint64_t psum([[maybe_unused]] uint64_t i, [[maybe_unused]] uint64_t j)
const
358 uint8_t get_new_key(uint64_t pointer_to_linked_container)
const
360 std::array<uint64_t, 4> occurrence_flag_array;
361 occurrence_flag_array[0] = 0;
362 occurrence_flag_array[1] = 0;
363 occurrence_flag_array[2] = 0;
364 occurrence_flag_array[3] = 0;
367 int64_t size = this->pointers.size();
368 for(int64_t i = 0; i < size; i++){
369 uint64_t pointer = this->pointers[i];
370 if (pointer == pointer_to_linked_container)
372 uint64_t idx = this->keys[i] / 64;
373 uint64_t geta = idx * 64;
375 occurrence_flag_array[idx] = occurrence_flag_array[idx] | (1LL << (63 - (this->keys[i] - geta)));
380 for (uint64_t i = 0; i < 4; i++)
382 if (occurrence_flag_array[i] != UINT64_MAX)
384 uint64_t code_len = stool::LSBByte::get_code_length(~occurrence_flag_array[i]);
385 return (64 * i) + (64 - code_len);
388 throw std::invalid_argument(
"Error(PermutationIterator::get_new_key)");
391 void update_linked_tree(uint64_t ith, uint64_t leaf_index_of_this_container, uint64_t previous_leaf_index, Tree &linked_tree)
393 PermutationItem item = this->at(ith);
394 assert(item.pointer < linked_tree.get_leaf_container_vector_size());
395 PermutationContainer &container = linked_tree.get_leaf_container(item.pointer);
396 int64_t idx = container.get_index(PermutationItem(previous_leaf_index, item.key));
398 uint8_t new_key = container.get_new_key(leaf_index_of_this_container);
403 assert(idx < (int64_t)container.size());
404 container.pointers.set_value(idx, leaf_index_of_this_container);
405 container.keys.set_value(idx, new_key);
406 this->keys.set_value(ith, new_key);
408 assert(this->keys.size() == this->pointers.size());
410 void set_value(uint64_t ith,
const PermutationItem &&item)
412 assert(ith < this->size());
413 this->keys.set_value(ith, item.key);
414 this->pointers.set_value(ith, item.pointer);
416 assert(this->keys.size() == this->pointers.size());
419 static uint64_t get_byte_size(
const PermutationContainer &item)
421 return NaiveFLCVector<false>::get_byte_size(item.keys) + NaiveFLCVector<false>::get_byte_size(item.pointers);
424 static uint64_t get_byte_size(
const std::vector<PermutationContainer> &items)
426 uint64_t bytes =
sizeof(uint64_t);
427 for (
auto &it : items)
429 bytes += PermutationContainer::get_byte_size(it);
434 static void store_to_bytes(
const PermutationContainer &item, std::vector<uint8_t> &output, uint64_t &pos)
436 NaiveFLCVector<false>::store_to_bytes(item.keys, output, pos);
437 NaiveFLCVector<false>::store_to_bytes(item.pointers, output, pos);
439 static void store_to_file(
const PermutationContainer &item, std::ofstream &os)
441 NaiveFLCVector<false>::store_to_file(item.keys, os);
442 NaiveFLCVector<false>::store_to_file(item.pointers, os);
445 static void store_to_bytes(
const std::vector<PermutationContainer> &items, std::vector<uint8_t> &output, uint64_t &pos)
447 uint64_t size = items.size();
448 std::memcpy(output.data() + pos, &size,
sizeof(size));
451 for (
auto &it : items)
453 PermutationContainer::store_to_bytes(it, output, pos);
456 static void store_to_file(
const std::vector<PermutationContainer> &items, std::ofstream &os)
458 uint64_t size = items.size();
459 os.write(
reinterpret_cast<const char *
>(&size),
sizeof(size));
460 for (
auto &it : items)
462 PermutationContainer::store_to_file(it, os);
466 static PermutationContainer load(
const std::vector<uint8_t> &data, uint64_t &pos)
468 PermutationContainer r;
469 NaiveFLCVector<false> tmp1 = NaiveFLCVector<false>::load_from_bytes(data, pos);
470 NaiveFLCVector<false> tmp2 = NaiveFLCVector<false>::load_from_bytes(data, pos);
472 r.pointers.swap(tmp2);
476 static PermutationContainer load(std::ifstream &ifs)
478 PermutationContainer r;
479 NaiveFLCVector<false> tmp1 = NaiveFLCVector<false>::load_from_file(ifs);
480 NaiveFLCVector<false> tmp2 = NaiveFLCVector<false>::load_from_file(ifs);
482 r.pointers.swap(tmp2);
487 static std::vector<PermutationContainer> load_vector(
const std::vector<uint8_t> &data, uint64_t &pos)
490 std::memcpy(&size, data.data() + pos,
sizeof(size));
493 std::vector<PermutationContainer> r;
494 for (uint64_t i = 0; i < size; i++)
496 r.push_back(PermutationContainer::load(data, pos));
500 static std::vector<PermutationContainer> load_vector(std::ifstream &ifs)
503 ifs.read(
reinterpret_cast<char *
>(&size),
sizeof(size));
505 std::vector<PermutationContainer> r;
506 for (uint64_t i = 0; i < size; i++)
508 r.push_back(PermutationContainer::load(ifs));