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