b-tree-plus-alpha
Loading...
Searching...
No Matches
permutation_container.hpp
1#pragma once
2#include "./permutation_item.hpp"
3
4namespace stool
5{
6 namespace bptree
7 {
14 {
15
16 stool::NaiveFLCVector<false> keys;
17 stool::NaiveFLCVector<false> pointers;
18
19 public:
20 static constexpr uint64_t ___PermutationLeafSize = 252;
22
29 {
30
31 public:
33 uint16_t _m_idx;
34
35 using iterator_category = std::bidirectional_iterator_tag;
36 using difference_type = std::ptrdiff_t;
38
39 PermutationItem operator*() const
40 {
41 return _m_deq->at(this->_m_idx);
42 }
43
44 PermutationIterator &operator++()
45 {
46 assert(this->_m_idx < this->_m_deq->size());
47
48 ++this->_m_idx;
49 return *this;
50 }
51
52 PermutationIterator operator++(int)
53 {
55
56 ++(*this);
57 return temp;
58 }
59
60 PermutationIterator &operator--()
61 {
62 --this->_m_idx;
63 return *this;
64 }
65
66 PermutationIterator operator--(int)
67 {
69 --(*this);
70 return temp;
71 }
72 // ランダムアクセス演算子(i + n)
73 PermutationIterator operator+(difference_type n) const
74 {
75 int16_t sum = (int16_t)this->_m_idx + (int16_t)n;
76 assert((int64_t)sum < (int64_t)this->_m_deq->size());
77
78 return PermutationIterator(this->_m_deq, sum);
79 }
80
81 // ランダムアクセス演算子(i - n)
82 PermutationIterator operator-(difference_type n) const
83 {
84 int16_t sum = (int16_t)this->_m_idx - (int16_t)n;
85 return PermutationIterator(this->_m_deq, sum);
86 }
87
88 // イテレータ同士の差(i - j)
89 difference_type operator-(const PermutationIterator &other) const
90 {
91 return (int16_t)this->_m_idx - (int16_t)other._m_idx;
92 }
93 /*
94 void change_element_without_changing_psum(PermutationItem item)
95 {
96 this->_m_deq->keys[this->_m_idx] = item.key;
97 this->_m_deq->pointers.set_value(this->_m_idx, item.pointer);
98 //this->_m_deq->pointers[this->_m_idx] = item.pointer;
99 }
100 */
101
102 bool operator==(const PermutationIterator &other) const { return _m_idx == other._m_idx; }
103 bool operator!=(const PermutationIterator &other) const { return _m_idx != other._m_idx; }
104 bool operator<(const PermutationIterator &other) const { return this->_m_idx < other._m_idx; }
105 bool operator>(const PermutationIterator &other) const { return this->_m_idx > other._m_idx; }
106 bool operator<=(const PermutationIterator &other) const { return this->_m_idx <= other._m_idx; }
107 bool operator>=(const PermutationIterator &other) const { return this->_m_idx >= other._m_idx; }
108 };
109
111 {
112 }
113
114 PermutationIterator begin() const
115 {
116 return PermutationIterator(const_cast<PermutationContainer *>(this), 0);
117 }
118 PermutationIterator end() const
119 {
120 return PermutationIterator(const_cast<PermutationContainer *>(this), this->size());
121 }
122
123 uint64_t size() const
124 {
125 return this->pointers.size();
126 }
127 uint64_t size_in_bytes(bool only_extra_bytes) const
128 {
129 if(only_extra_bytes){
130 return this->keys.size_in_bytes(true) + this->pointers.size_in_bytes(true);
131 }else{
132 return sizeof(PermutationContainer) + this->keys.size_in_bytes(true) + this->pointers.size_in_bytes(true);
133 }
134 }
135 uint64_t unused_size_in_bytes() const
136 {
137 return this->keys.unused_size_in_bytes() + this->pointers.unused_size_in_bytes();
138 }
139
140
141 PermutationItem at(uint64_t pos) const
142 {
143 assert(pos < this->keys.size());
144 assert(pos < this->pointers.size());
145
146 return PermutationItem(this->pointers.at(pos), this->keys[pos]);
147 }
148 void print() const
149 {
150 std::cout << this->to_string() << std::endl;
151 }
152
153 void clear()
154 {
155 this->keys.clear();
156 this->pointers.clear();
157
158 assert(this->keys.size() == this->pointers.size());
159 }
160 void swap(PermutationContainer &item)
161 {
162 assert(item.keys.size() == item.pointers.size());
163
164 this->keys.swap(item.keys);
165 this->pointers.swap(item.pointers);
166
167 assert(this->keys.size() == this->pointers.size());
168 }
169 static std::string name()
170 {
171 return "X";
172 }
173 uint64_t psum([[maybe_unused]] uint64_t i) const noexcept
174 {
175 return 0;
176 }
177 uint64_t psum() const noexcept
178 {
179 return 0;
180 }
181 int64_t search([[maybe_unused]] uint64_t x) const noexcept
182 {
183 return -1;
184 }
185 int64_t get_index(const PermutationItem &&item) const
186 {
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){
190 return i;
191 }
192 }
193 return -1;
194
195 /*
196 for (uint64_t pointer : this->pointers)
197 {
198 if (pointer == item.pointer && this->keys[i] == item.key)
199 {
200 return i;
201 }
202 i++;
203 }
204 */
205 }
206
207 std::string to_string() const
208 {
209 assert(this->keys.size() == this->pointers.size());
210
211 std::string s;
212 s.push_back('[');
213
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())
218 {
219 s += ", ";
220 }
221 }
222
223 s.push_back(']');
224 return s;
225 }
226
227 std::vector<PermutationItem> to_value_vector() const
228 {
229 throw std::runtime_error("PermutationContainer::NO IMP1");
230 }
231
232 void insert(uint64_t pos, PermutationItem value)
233 {
234 this->keys.insert(pos, value.key);
235 this->pointers.insert(pos, value.pointer);
236
237 assert(this->keys.size() == this->pointers.size());
238 }
239 void remove(uint64_t pos)
240 {
241 this->keys.remove(pos);
242 this->pointers.remove(pos);
243
244 assert(this->keys.size() == this->pointers.size());
245 }
246 void push_front(const std::vector<PermutationItem> &new_items)
247 {
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());
252
253 for (int64_t i = 0; i < (int64_t)new_items.size(); i++)
254 {
255 tmp_keys[i] = new_items[i].key;
256 tmp_pointers[i] = new_items[i].pointer;
257 }
258 this->keys.push_front(tmp_keys);
259 this->pointers.push_front(tmp_pointers);
260
261 /*
262 for (int64_t i = new_items.size() - 1; i >= 0; i--)
263 {
264 this->keys.push_front(new_items[i].key);
265 this->pointers.push_front(new_items[i].pointer);
266 }
267 */
268
269 assert(this->keys.size() == this->pointers.size());
270 }
271 void push_front(const PermutationItem &new_item)
272 {
273 this->keys.push_front(new_item.key);
274 this->pointers.push_front(new_item.pointer);
275
276 assert(this->keys.size() == this->pointers.size());
277 }
278
279 void push_back(const std::vector<PermutationItem> &new_items)
280 {
281 for (const PermutationItem &item : new_items)
282 {
283 this->keys.push_back(item.key);
284 this->pointers.push_back(item.pointer);
285 }
286
287 assert(this->keys.size() == this->pointers.size());
288 }
289 void push_back(PermutationItem value)
290 {
291 this->keys.push_back(value.key);
292 this->pointers.push_back(value.pointer);
293
294 assert(this->keys.size() == this->pointers.size());
295 }
296 PermutationItem pop_front()
297 {
298 uint64_t key = this->keys[0];
299 uint64_t pointer = this->pointers.head();
300 this->keys.pop_front();
301 this->pointers.pop_front();
302
303 assert(this->keys.size() == this->pointers.size());
304 return PermutationItem(pointer, key);
305 }
306
307 std::vector<PermutationItem> pop_front(uint64_t len)
308 {
309 std::vector<PermutationItem> r;
310 r.resize(len);
311
312 for (uint64_t i = 0; i < len; i++)
313 {
314 uint64_t key = this->keys[i];
315 uint64_t pointer = this->pointers[i];
316 r[i] = PermutationItem(pointer, key);
317 }
318 this->keys.pop_front(len);
319 this->pointers.pop_front(len);
320
321 assert(this->keys.size() == this->pointers.size());
322 return r;
323
324 }
325 PermutationItem pop_back()
326 {
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();
332
333 assert(this->keys.size() == this->pointers.size());
334 return PermutationItem(pointer, key);
335 }
336
337 std::vector<PermutationItem> pop_back(uint64_t len)
338 {
339 std::vector<PermutationItem> tmp1;
340 tmp1.resize(len);
341 int64_t k = len - 1;
342 while (k >= 0)
343 {
344 tmp1[k--] = this->pop_back();
345 }
346
347 assert(this->keys.size() == this->pointers.size());
348 return tmp1;
349 }
350 uint64_t reverse_psum([[maybe_unused]] uint64_t i) const
351 {
352 return 0;
353 }
354 uint64_t psum([[maybe_unused]] uint64_t i, [[maybe_unused]] uint64_t j) const
355 {
356 return 0;
357 }
358 uint8_t get_new_key(uint64_t pointer_to_linked_container) const
359 {
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;
365
366
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)
371 {
372 uint64_t idx = this->keys[i] / 64;
373 uint64_t geta = idx * 64;
374
375 occurrence_flag_array[idx] = occurrence_flag_array[idx] | (1LL << (63 - (this->keys[i] - geta)));
376 }
377
378 }
379
380 for (uint64_t i = 0; i < 4; i++)
381 {
382 if (occurrence_flag_array[i] != UINT64_MAX)
383 {
384 uint64_t code_len = stool::LSBByte::get_code_length(~occurrence_flag_array[i]);
385 return (64 * i) + (64 - code_len);
386 }
387 }
388 throw std::invalid_argument("Error(PermutationIterator::get_new_key)");
389 }
390
391 void update_linked_tree(uint64_t ith, uint64_t leaf_index_of_this_container, uint64_t previous_leaf_index, Tree &linked_tree)
392 {
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));
397 assert(idx != -1);
398 uint8_t new_key = container.get_new_key(leaf_index_of_this_container);
399 // std::cout << "##" << (uint64_t)this << "/" << previous_leaf_index << "/" << (int)item.key << " -> " << (uint64_t)new_key << "/" << leaf_index_of_this_container << std::endl;
400 // this->print();
401 // container.print();
402
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);
407
408 assert(this->keys.size() == this->pointers.size());
409 }
410 void set_value(uint64_t ith, const PermutationItem &&item)
411 {
412 assert(ith < this->size());
413 this->keys.set_value(ith, item.key);
414 this->pointers.set_value(ith, item.pointer);
415
416 assert(this->keys.size() == this->pointers.size());
417 }
418
419 static uint64_t get_byte_size(const PermutationContainer &item)
420 {
421 return NaiveFLCVector<false>::get_byte_size(item.keys) + NaiveFLCVector<false>::get_byte_size(item.pointers);
422 }
423
424 static uint64_t get_byte_size(const std::vector<PermutationContainer> &items)
425 {
426 uint64_t bytes = sizeof(uint64_t);
427 for (auto &it : items)
428 {
429 bytes += PermutationContainer::get_byte_size(it);
430 }
431 return bytes;
432 }
433
434 static void store_to_bytes(const PermutationContainer &item, std::vector<uint8_t> &output, uint64_t &pos)
435 {
436 NaiveFLCVector<false>::store_to_bytes(item.keys, output, pos);
437 NaiveFLCVector<false>::store_to_bytes(item.pointers, output, pos);
438 }
439 static void store_to_file(const PermutationContainer &item, std::ofstream &os)
440 {
441 NaiveFLCVector<false>::store_to_file(item.keys, os);
442 NaiveFLCVector<false>::store_to_file(item.pointers, os);
443 }
444
445 static void store_to_bytes(const std::vector<PermutationContainer> &items, std::vector<uint8_t> &output, uint64_t &pos)
446 {
447 uint64_t size = items.size();
448 std::memcpy(output.data() + pos, &size, sizeof(size));
449 pos += sizeof(size);
450
451 for (auto &it : items)
452 {
453 PermutationContainer::store_to_bytes(it, output, pos);
454 }
455 }
456 static void store_to_file(const std::vector<PermutationContainer> &items, std::ofstream &os)
457 {
458 uint64_t size = items.size();
459 os.write(reinterpret_cast<const char *>(&size), sizeof(size));
460 for (auto &it : items)
461 {
462 PermutationContainer::store_to_file(it, os);
463 }
464 }
465
466 static PermutationContainer load(const std::vector<uint8_t> &data, uint64_t &pos)
467 {
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);
471 r.keys.swap(tmp1);
472 r.pointers.swap(tmp2);
473
474 return r;
475 }
476 static PermutationContainer load(std::ifstream &ifs)
477 {
478 PermutationContainer r;
479 NaiveFLCVector<false> tmp1 = NaiveFLCVector<false>::load_from_file(ifs);
480 NaiveFLCVector<false> tmp2 = NaiveFLCVector<false>::load_from_file(ifs);
481 r.keys.swap(tmp1);
482 r.pointers.swap(tmp2);
483
484 return r;
485 }
486
487 static std::vector<PermutationContainer> load_vector(const std::vector<uint8_t> &data, uint64_t &pos)
488 {
489 uint64_t size;
490 std::memcpy(&size, data.data() + pos, sizeof(size));
491 pos += sizeof(size);
492
493 std::vector<PermutationContainer> r;
494 for (uint64_t i = 0; i < size; i++)
495 {
496 r.push_back(PermutationContainer::load(data, pos));
497 }
498 return r;
499 }
500 static std::vector<PermutationContainer> load_vector(std::ifstream &ifs)
501 {
502 uint64_t size = 0;
503 ifs.read(reinterpret_cast<char *>(&size), sizeof(size));
504
505 std::vector<PermutationContainer> r;
506 for (uint64_t i = 0; i < size; i++)
507 {
508 r.push_back(PermutationContainer::load(ifs));
509 }
510 return r;
511 }
512 };
513 }
514}
An implementation of B+-tree [Unchecked AI's Comment].
Definition bp_tree.hpp:24
uint64_t size() const
Return the number of values stored in this tree.
Definition bp_tree.hpp:316
The forward iterator of values stored in PermutationContainer.
Definition permutation_container.hpp:29
The container stored in the BPTree of DynamicPermutation [Unchecked AI's Comment].
Definition permutation_container.hpp:14
The value stored in the BPTree of DynamicPermutation [Unchecked AI's Comment].
Definition permutation_item.hpp:15