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