CLRX  1
An unofficial OpenCL extensions designed for Radeon GPUs
DTree.h
Go to the documentation of this file.
1 /*
2  * CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3  * Copyright (C) 2014-2018 Mateusz Szpakowski
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
23 #ifndef __CLRX_DTREE_H__
24 #define __CLRX_DTREE_H__
25 
26 #include <CLRX/Config.h>
27 #include <algorithm>
28 #include <iterator>
29 #include <initializer_list>
30 #include <climits>
31 #include <cstddef>
32 #include <memory>
33 #include <CLRX/utils/Utilities.h>
34 
35 namespace CLRX
36 {
37 
39 template<typename T1, typename T2>
41 {
42  const T1& operator()(const std::pair<T1, T2>& v) const
43  { return v.first; }
44  T1& operator()(std::pair<T1, T2>& v) const
45  { return v.first; }
46 };
47 
49 template<typename T>
50 struct Identity
51 {
52  const T& operator()(const T& v) const
53  { return v; }
54  T& operator()(T& v) const
55  { return v; }
56 };
57 
59 
73 template<typename K, typename T = K, typename Comp = std::less<K>,
74  typename KeyOfVal = Identity<K>, typename AT = T>
75 class DTree: private Comp, KeyOfVal
76 {
77 public:
79  enum : cxbyte
80  {
81  NODE0 = 0,
84  NODEV
85  };
86 
87  // number of elements in Node1
88  static const cxuint maxNode1Size = 8;
89  static const cxuint maxNode1Shift = 3;
90  static const cxuint normalNode1Shift = 2;
91  static const cxuint maxNode1Depth = (sizeof(size_t)*8)>>1;
92 
93  static const cxuint maxNode0Capacity = 63;
94  static const cxuint normalNode0Capacity = maxNode0Capacity>>1;
95  static const cxuint minNode0Capacity = 20;
96  static const cxuint freePlacesShift = 1;
97  static const cxuint minFreePlacesShift = 3;
98 
99  static const cxuint maxNode0Size = ((maxNode0Capacity*1000 /
100  ((1<<minFreePlacesShift)+1))*(1<<minFreePlacesShift)) / 1000;
101  static const cxuint normalNode0Size = ((normalNode0Capacity*1000 /
102  ((1<<minFreePlacesShift)+1))*(1<<minFreePlacesShift)) / 1000;
103  static const cxuint minNode0Size = maxNode0Size / 3;
104 
105  // get maximal total size for node in depth level
106  static size_t maxTotalSize(cxuint level)
107  {
108  if (level == 0)
109  return maxNode0Size;
110  return size_t(maxNode0Size) << (normalNode1Shift * level);
111  }
112 
113  // get normal total size for node in depth level
114  static size_t normalTotalSize(cxuint level)
115  {
116  if (level == 0)
117  return normalNode0Size;
118  return size_t(normalNode0Size) << (normalNode1Shift * level - 1);
119  }
120 
121  // get minimal total size for node in depth level
122  static size_t minTotalSize(cxuint level)
123  {
124  if (level == 0)
125  return minNode0Size;
126  return (size_t(maxNode0Size) << (normalNode1Shift * level)) / 3;
127  }
128 
129  // parent pointer part size of array (heap)
130  static const int parentEntrySize = sizeof(void*) <= 8 ? 8 : sizeof(void*);
131 
132  struct NodeBase
133  {
134  cxbyte type;
135 
136  NodeBase(cxbyte _type) : type(_type)
137  { }
138  };
139 
140  struct Node1;
141  static const int parentEntryIndex = -int(parentEntrySize / sizeof(void*));
142 
143  // main node0 - holds elements
144  /* holds slighty greater array of the elements
145  * organized in linear ways with empty holes that holds copies of later elements
146  * array is ordered
147  */
148  struct Node0: NodeBase
149  {
150  cxbyte index; // index in Node1
151  cxbyte size; // size (number of elements)
152  cxbyte capacity; // capacity of array
153  cxbyte firstPos; // first position with element
154  uint64_t bitMask; // bitmask: 0 - hold element, 1 - free space
155  union {
156  AT* array; // array (internal)
157  T* arrayOut; // array out for iterator
158  };
159 
160  Node0(): NodeBase(NODE0), index(255), size(0), capacity(0),
161  firstPos(0), bitMask(0ULL), array(nullptr)
162  { }
163 
164  Node0(const Node0& node): NodeBase(NODE0),
165  index(node.index), size(node.size), capacity(node.capacity),
166  firstPos(node.firstPos), bitMask(node.bitMask), array(nullptr)
167  {
168  if (node.array != nullptr)
169  {
170  array = new AT[capacity];
171  std::copy(node.array, node.array+capacity, array);
172  }
173  }
174  Node0(Node0&& node) noexcept: NodeBase(NODE0),
175  index(node.index), size(node.size), capacity(node.capacity),
176  firstPos(node.firstPos), bitMask(node.bitMask), array(node.array)
177  {
178  node.array = nullptr;
179  }
180  ~Node0()
181  {
182  delete[] array;
183  }
184 
186  Node0& operator=(const Node0& node)
187  {
188  NodeBase::type = node.NodeBase::type;
189  index = node.index;
190  size = node.size;
191  capacity = node.capacity;
192  firstPos = node.firstPos;
193  bitMask = node.bitMask;
194  AT* newArray = nullptr;
195  if (node.array != nullptr)
196  {
197  newArray = new AT[capacity];
198  std::copy(node.array, node.array+capacity, newArray);
199  }
200  delete[] array;
201  array = newArray;
202  return *this;
203  }
204 
206  Node0& operator=(Node0&& node) noexcept
207  {
208  NodeBase::type = node.NodeBase::type;
209  index = node.index;
210  size = node.size;
211  capacity = node.capacity;
212  firstPos = node.firstPos;
213  bitMask = node.bitMask;
214  delete[] array;
215  array = node.array;
216  node.array = nullptr;
217  return *this;
218  }
219 
221  const Node1* parent() const
222  { return index!=255U ?
223  reinterpret_cast<Node1* const *>(this-index)[parentEntryIndex] : nullptr; }
224 
227  { return index!=255U ?
228  reinterpret_cast<Node1**>(this-index)[parentEntryIndex] : nullptr; }
229 
230  const AT& operator[](cxuint i) const
231  { return array[i]; }
232 
233  AT& operator[](cxuint i)
234  { return array[i]; }
235 
237  cxuint lower_boundFree(const K& k, const Comp& comp, const KeyOfVal& kofval) const
238  {
239  AT kt;
240  kofval(kt) = k;
241  cxuint index = std::lower_bound(array, array+capacity, kt,
242  [&comp, &kofval](const AT& v1, const AT& v2)
243  { return comp(kofval(v1), kofval(v2)); }) - array;
244  return index;
245  }
246 
248  cxuint lower_bound(const K& k, const Comp& comp, const KeyOfVal& kofval) const
249  {
250  AT kt;
251  kofval(kt) = k;
252  cxuint index = std::lower_bound(array, array+capacity, kt,
253  [&comp, &kofval](const AT& v1, const AT& v2)
254  { return comp(kofval(v1), kofval(v2)); }) - array;
255  for (; (bitMask & (1ULL<<index)) != 0; index++);
256  return index;
257  }
258 
260  cxuint upper_bound(const K& k, const Comp& comp, const KeyOfVal& kofval) const
261  {
262  AT kt;
263  kofval(kt) = k;
264  cxuint index = std::upper_bound(array, array+capacity, kt,
265  [&comp, &kofval](const T& v1, const T& v2)
266  { return comp(kofval(v1), kofval(v2)); }) - array;
267  for (; (bitMask & (1ULL<<index)) != 0; index++);
268  return index;
269  }
270 
272  cxuint find(const K& k, const Comp& comp, const KeyOfVal& kofval) const
273  {
274  cxuint index = lower_bound(k, comp, kofval);
275  if (index == capacity ||
276  // if not equal
277  comp(k, kofval(array[index])) || comp(kofval(array[index]), k))
278  return capacity; // not found
279  return index;
280  }
281 
283  static void organizeArray(AT& toFill,
284  cxuint& i, cxuint size, const AT* array, uint64_t inBitMask,
285  cxuint& k, cxuint newSize, AT* out, uint64_t& outBitMask,
286  cxuint& factor, cxuint finc)
287  {
288  while ((inBitMask & (1ULL<<i)) != 0)
289  i++; // skip free elem
290 
291  cxuint p0 = 0;
292  for (; p0 < size; k++, p0++)
293  {
294  toFill = out[k] = array[i];
295 
296  factor += finc;
297  if (factor >= newSize)
298  {
299  // add additional (empty) element
300  factor -= newSize;
301  k++;
302  out[k] = array[i];
303  outBitMask |= (1ULL<<k);
304  }
305 
306  i++;
307  while ((inBitMask & (1ULL<<i)) != 0)
308  i++; // skip free elem
309  }
310  }
311 
312  void setFromArray(cxuint size, const AT* input)
313  {
314  cxuint newCapacity = std::min(cxbyte(size + (size>>freePlacesShift)),
315  cxbyte(maxNode0Capacity));
316  AT* newArray = new AT[newCapacity];
317 
318  cxuint factor = 0;
319  // finc - factor increment for empty holes
320  const cxuint finc = newCapacity - size;
321  AT toFill = AT();
322  cxuint i = 0, k = 0;
323  uint64_t newBitMask = 0;
324  organizeArray(toFill, i, size, input, 0ULL, k, size, newArray,
325  newBitMask, factor, finc);
326  if (k < newCapacity)
327  {
328  newArray[k] = toFill;
329  newBitMask |= (1ULL<<k);
330  }
331 
332  delete[] array;
333  array = newArray;
334  this->size = size;
335  bitMask = newBitMask;
336  capacity = newCapacity;
337  firstPos = 0;
338  }
339 
340  void allocate(cxuint size)
341  {
342  capacity = std::min(cxbyte(size + (size>>freePlacesShift)),
343  cxbyte(maxNode0Capacity));
344  AT* newArray = new AT[capacity];
345  delete[] array;
346  array = newArray;
347  firstPos = 0;
348  bitMask = 0;
349  this->size = 0;
350  }
351 
352  void assignArray(AT& toFill, cxuint inSize, cxuint& index, cxuint& pos,
353  const AT* array, uint64_t inBitMask, size_t newSize,
354  cxuint& k, cxuint& factor)
355  {
356  cxuint finc = capacity - newSize;
357  cxuint remainingSize = std::min(cxuint(newSize-size), cxuint(inSize-pos));
358  organizeArray(toFill, index, remainingSize, array,
359  inBitMask, k, newSize, this->array, bitMask, factor, finc);
360  size += remainingSize;
361  pos += remainingSize;
362  }
363 
365  void merge(const Node0& node2)
366  {
367  cxuint newSize = size+node2.size;
368  cxuint newCapacity = std::min(
369  cxbyte(newSize + (newSize>>freePlacesShift)),
370  cxbyte(maxNode0Capacity));
371  AT* newArray = nullptr;
372  if (newCapacity != 0)
373  newArray = new AT[newCapacity];
374 
375  uint64_t newBitMask = 0ULL;
376  cxuint factor = 0;
377  // finc - factor increment for empty holes
378  const cxuint finc = newCapacity - newSize;
379  AT toFill = AT();
380  cxuint i = 0, j = 0, k = 0;
381 
382  organizeArray(toFill, i, size, array, bitMask, k, newSize, newArray,
383  newBitMask, factor, finc);
384 
385  organizeArray(toFill, j, node2.size, node2.array, node2.bitMask,
386  k, newSize, newArray, newBitMask, factor, finc);
387 
388  // fill a remaining free elements
389  if (k < newCapacity)
390  {
391  newArray[k] = toFill;
392  newBitMask |= (1ULL<<k);
393  }
394 
395  delete[] array;
396  array = newArray;
397  capacity = newCapacity;
398  size = newSize;
399  bitMask = newBitMask;
400  firstPos = 0;
401  }
402 
404  void split(Node0& node2)
405  {
406  cxuint newSize0 = (size+1)>>1;
407  cxuint newSize1 = size-newSize0;
408  cxuint newCapacity0 = std::min(
409  cxbyte(newSize0 + (newSize0>>freePlacesShift)),
410  cxbyte(maxNode0Capacity));
411  cxuint newCapacity1 = std::min(
412  cxbyte(newSize1 + (newSize1>>freePlacesShift)),
413  cxbyte(maxNode0Capacity));
414  std::unique_ptr<AT[]> newArray0 = nullptr;
415  std::unique_ptr<AT[]> newArray1 = nullptr;
416  if (newCapacity0 != 0)
417  newArray0.reset(new AT[newCapacity0]);
418  if (newCapacity1 != 0)
419  newArray1.reset(new AT[newCapacity1]);
420  uint64_t newBitMask0 = 0ULL;
421  uint64_t newBitMask1 = 0ULL;
422 
423  AT toFill = AT();
424  cxuint i = 0, k = 0;
425  cxuint factor = 0;
426  // finc - factor increment for empty holes
427  cxuint finc = newCapacity0 - newSize0;
428  // store first part to newArray0
429  organizeArray(toFill, i, newSize0, array, bitMask, k, newSize0,
430  newArray0.get(), newBitMask0, factor, finc);
431 
432  // fill a remaining free elements
433  if (k < newCapacity0)
434  {
435  newArray0[k] = toFill;
436  newBitMask0 |= (1ULL<<k);
437  }
438 
439  toFill = AT();
440  k = 0;
441  factor = 0;
442  // finc - factor increment for empty holes
443  finc = newCapacity1 - newSize1;
444  // store first part to newArray1
445  organizeArray(toFill, i, newSize1, array, bitMask,
446  k, newSize1, newArray1.get(), newBitMask1, factor, finc);
447 
448  // fill a remaining free elements
449  if (k < newCapacity1)
450  {
451  newArray1[k] = toFill;
452  newBitMask1 |= (1ULL<<k);
453  }
454 
455  delete[] array;
456  // store into this node (array0)
457  array = newArray0.release();
458  capacity = newCapacity0;
459  size = newSize0;
460  bitMask = newBitMask0;
461  firstPos = 0;
462  delete[] node2.array;
463  // store into node2 (array1)
464  node2.array = newArray1.release();
465  node2.capacity = newCapacity1;
466  node2.size = newSize1;
467  node2.bitMask = newBitMask1;
468  node2.firstPos = 0;
469  }
470 
472  void resize(cxint extraSize)
473  {
474  // reorganize array
475  cxuint newCapacity = std::min(
476  cxbyte(size+extraSize + ((size+extraSize)>>freePlacesShift)),
477  cxbyte(maxNode0Capacity));
478  AT* newArray = nullptr;
479  if (newCapacity != 0)
480  newArray = new AT[newCapacity];
481 
482  uint64_t newBitMask = 0ULL;
483  cxuint factor = 0;
484  const cxuint finc = newCapacity - size;
485 
486  AT toFill = AT();
487  cxuint i = 0, j = 0;
488 
489  organizeArray(toFill, i, size, array, bitMask, j, size, newArray,
490  newBitMask, factor, finc);
491  // fill a remaining free elements
492  if (j < newCapacity)
493  {
494  newArray[j] = toFill;
495  newBitMask |= (1ULL<<j);
496  }
497 
498  delete[] array;
499  array = newArray;
500  capacity = newCapacity;
501  bitMask = newBitMask;
502  firstPos = 0;
503  }
504 
506  std::pair<cxuint, bool> insert(const T& v, const Comp& comp,
507  const KeyOfVal& kofval)
508  {
509  cxuint idx = 255;
510  idx = lower_boundFree(kofval(v), comp, kofval);
511 
512  if (idx < capacity && (bitMask & (1ULL<<idx))==0 &&
513  !comp(kofval(v), kofval(array[idx])))
514  // is equal, then skip insertion
515  return std::make_pair(idx, false);
516 
517  cxuint minFreePlaces = ((size+1)>>minFreePlacesShift);
518  if ((size+1) + minFreePlaces > capacity)
519  {
520  resize(1);
521  idx = lower_boundFree(kofval(v), comp, kofval);
522  }
523 
524  if ((bitMask & (1ULL<<idx)) == 0)
525  {
526  // if this is not free element
527  const uint64_t leftMask = bitMask & ((1ULL<<idx)-1U);
528  const uint64_t rightMask = bitMask & ~((2ULL<<idx)-1U);
529 
530  // leftLen - number of elemnts in left side to first empty hole
531  // rightLen - number of elemnts in right side to first empty hole
532  cxuint leftLen = 255, rightLen = 255;
533  if (leftMask != 0)
534  leftLen = idx-(63-CLZ64(leftMask));
535  if (rightMask != 0)
536  rightLen = CTZ64(rightMask)-idx;
537 
538  if (leftLen >= rightLen)
539  {
540  // move right side (shorter)
541  cxuint k = idx + rightLen;
542  bitMask &= ~(1ULL<<k);
543  for (; k > idx; k--)
544  array[k] = array[k-1];
545  }
546  else
547  {
548  // move left side (shorter)
549  cxuint k = idx - leftLen;
550  bitMask &= ~(1ULL<<k);
551  for (; k < idx-1; k++)
552  array[k] = array[k+1];
553  idx--; // before element
554 
555  firstPos = 0;
556  while ((bitMask & (1U<<firstPos)) != 0)
557  firstPos++; // skip free places
558  }
559  array[idx] = v;
560  }
561  else
562  {
563  // if this is free place
564  array[idx] = v;
565  bitMask &= ~(1ULL<<idx);
566  }
567  size++;
568  firstPos = std::min(cxuint(firstPos), idx);
569  return std::make_pair(idx, true);
570  }
571 
573  bool erase(cxuint index)
574  {
575  if ((bitMask & (1ULL<<index)) != 0)
576  return false;
577  bitMask |= (1ULL<<index);
578  size--;
579 
580  cxuint maxFreePlaces = ((size+1)>>freePlacesShift);
581  if (size + maxFreePlaces < capacity)
582  resize(0);
583  else if (index == firstPos)
584  while ((bitMask & (1U<<firstPos)) != 0)
585  firstPos++; // skip free places
586  return true;
587  }
588 
590  bool erase(const K& k, const Comp& comp, const KeyOfVal& kofval)
591  {
592  cxuint index = lower_bound(k, comp, kofval);
593  if (index >= capacity || comp(k, kofval(array[index])))
594  return false; // if not found
595  return erase(index);
596  }
597  };
598 
600  struct Node1 : NodeBase
601  {
605  size_t totalSize;
606  K first;
607  union {
609  Node0* array;
611  };
612 
613  Node1(): NodeBase(NODE1), index(255), size(0), capacity(0), totalSize(0),
614  first(), array(nullptr)
615  { }
616 
618  void freeArray()
619  {
620  if (array != nullptr)
621  {
622  if (NodeBase::type == NODE1)
623  {
624  for (cxuint i = 0; i < capacity; i++)
625  array[i].~Node0();
626  delete[] (reinterpret_cast<cxbyte*>(array) - parentEntrySize);
627  }
628  else
629  {
630  for (cxuint i = 0; i < capacity; i++)
631  array1[i].~Node1();
632  delete[] (reinterpret_cast<cxbyte*>(array1) - parentEntrySize);
633  }
634  array1 = nullptr;
635  }
636  }
637 
638  // copy array helper - copy array from Node1 to this node
639  void copyArray(const Node1& node)
640  {
641  if (NodeBase::type == NODE1)
642  {
643  // if Node1 holds Node0's
644  if (node.array != nullptr)
645  {
646  cxbyte* arrayData = new cxbyte[parentEntrySize +
647  capacity*sizeof(Node0)];
648  freeArray();
649  array = reinterpret_cast<Node0*>(arrayData + parentEntrySize);
651  *reinterpret_cast<Node1**>(arrayData) = this;
652  for (cxuint i = 0; i < capacity; i++)
653  new (array+i)Node0();
654  std::copy(node.array, node.array+size, array);
655  }
656  }
657  else
658  {
659  // if Node1 holds Node1's
660  if (node.array1 != nullptr)
661  {
662  cxbyte* arrayData = new cxbyte[parentEntrySize +
663  capacity*sizeof(Node1)];
664  freeArray();
665  array1 = reinterpret_cast<Node1*>(arrayData + parentEntrySize);
667  *reinterpret_cast<Node1**>(arrayData) = this;
668  for (cxuint i = 0; i < capacity; i++)
669  new (array1+i)Node1();
670  std::copy(node.array1, node.array1+size, array1);
671  }
672  }
673  }
674 
675  Node1(const Node1& node): NodeBase(node.type), index(node.index),
676  size(node.size), capacity(node.capacity),
677  totalSize(node.totalSize), first(node.first), array(nullptr)
678  {
679  copyArray(node);
680  }
681 
682  Node1(Node1&& node) noexcept: NodeBase(node.type), index(node.index),
683  size(node.size), capacity(node.capacity),
684  totalSize(node.totalSize), first(node.first), array(node.array)
685  {
686  if (array != nullptr)
687  reinterpret_cast<Node1**>(array)[parentEntryIndex] = this;
688  node.array = nullptr;
689  }
690 
692  Node1(Node0&& n0, Node0&& n1, const KeyOfVal& kofval)
693  : NodeBase(NODE1), index(255), size(2), capacity(2),
694  totalSize(n0.size+n1.size), first(kofval(n0.array[n0.firstPos])),
695  array(nullptr)
696  {
697  cxbyte* arrayData = new cxbyte[parentEntrySize + capacity*sizeof(Node0)];
698  array = reinterpret_cast<Node0*>(arrayData + parentEntrySize);
699  new (array+0)Node0();
700  new (array+1)Node0();
701  *reinterpret_cast<Node1**>(arrayData) = this;
702  array[0] = std::move(n0);
703  array[1] = std::move(n1);
704  array[0].index = 0;
705  array[1].index = 1;
706  }
708  Node1(Node1&& n0, Node1&& n1) : NodeBase(NODE2), index(255),
709  size(2), capacity(2), totalSize(n0.totalSize+n1.totalSize),
710  first(n0.first), array(nullptr)
711  {
712  cxbyte* arrayData = new cxbyte[parentEntrySize + capacity*sizeof(Node1)];
713  array1 = reinterpret_cast<Node1*>(arrayData + parentEntrySize);
714  new (array1+0)Node1();
715  new (array1+1)Node1();
716  *reinterpret_cast<Node1**>(arrayData) = this;
717  array1[0] = std::move(n0);
718  array1[1] = std::move(n1);
719  array1[0].index = 0;
720  array1[1].index = 1;
721  }
722 
723  ~Node1()
724  {
725  freeArray();
726  }
727 
728  Node1& operator=(const Node1& node)
729  {
730  NodeBase::type = node.NodeBase::type;
731  size = node.size;
732  index = node.index;
733  capacity = node.capacity;
734  totalSize = node.totalSize;
735  copyArray(node);
736  first = node.first;
737  return *this;
738  }
739 
740  Node1& operator=(Node1&& node) noexcept
741  {
742  freeArray();
743  NodeBase::type = node.NodeBase::type;
744  size = node.size;
745  index = node.index;
746  capacity = node.capacity;
747  totalSize = node.totalSize;
748  array = node.array;
749  if (array != nullptr)
750  reinterpret_cast<Node1**>(array)[parentEntryIndex] = this;
751  first = node.first;
752  node.array = nullptr;
753  return *this;
754  }
755 
756  Node0* getFirstNode0()
757  {
758  Node1* cur = this;
759  while (cur->NodeBase::type == NODE2)
760  cur = cur->array1;
761  return cur->array;
762  }
763 
764  const Node0* getFirstNode0() const
765  {
766  const Node1* cur = this;
767  while (cur->NodeBase::type == NODE2)
768  cur = cur->array1;
769  return cur->array;
770  }
771 
772  Node0* getLastNode0()
773  {
774  Node1* cur = this;
775  while (cur->NodeBase::type == NODE2)
776  cur = cur->array1 + cur->size - 1;
777  return cur->array + cur->size - 1;
778  }
779 
780  const Node0* getLastNode0() const
781  {
782  const Node1* cur = this;
783  while (cur->NodeBase::type == NODE2)
784  cur = cur->array1 + cur->size - 1;
785  return cur->array + cur->size - 1;
786  }
787 
789  const Node1* parent() const
790  { return index!=255U ?
791  reinterpret_cast<Node1* const *>(this-index)[parentEntryIndex] : nullptr; }
792 
795  { return index!=255U ?
796  reinterpret_cast<Node1**>(this-index)[parentEntryIndex] : nullptr; }
797 
798  void allocate0(cxuint newCapacity)
799  {
800  cxbyte* newData = new cxbyte[newCapacity*sizeof(Node0) + parentEntrySize];
801  // set parent node
802  *reinterpret_cast<Node1**>(newData) = this;
803  Node0* newArray = reinterpret_cast<Node0*>(newData + parentEntrySize);
805  for (cxuint i = 0; i < newCapacity; i++)
806  new (newArray+i)Node0();
807  if (array != nullptr)
808  {
809  for (cxuint i = 0; i < size; i++)
810  array[i].~Node0();
811  delete[] (reinterpret_cast<cxbyte*>(array) - parentEntrySize);
812  }
813 
814  totalSize = 0;
815  array = newArray;
816  capacity = newCapacity;
817  size = 0;
818  first = K();
819  }
820 
821  void allocate1(cxuint newCapacity)
822  {
823  cxbyte* newData = new cxbyte[newCapacity*sizeof(Node1) + parentEntrySize];
824  // set parent node
825  *reinterpret_cast<Node1**>(newData) = this;
826  Node1* newArray = reinterpret_cast<Node1*>(newData + parentEntrySize);
828  for (cxuint i = 0; i < newCapacity; i++)
829  new (newArray+i)Node1();
830  if (array != nullptr)
831  {
832  for (cxuint i = 0; i < size; i++)
833  array1[i].~Node1();
834  delete[] (reinterpret_cast<cxbyte*>(array1) - parentEntrySize);
835  }
836 
837  totalSize = 0;
838  array1 = newArray;
839  capacity = newCapacity;
840  size = 0;
841  first = K();
842  }
843 
845  void reserve0(cxuint newCapacity)
846  {
847  cxbyte* newData = new cxbyte[newCapacity*sizeof(Node0) + parentEntrySize];
848  // set parent node
849  *reinterpret_cast<Node1**>(newData) = this;
850  Node0* newArray = reinterpret_cast<Node0*>(newData + parentEntrySize);
852  for (cxuint i = 0; i < newCapacity; i++)
853  new (newArray+i)Node0();
854  cxuint newSize = std::min(cxuint(size), newCapacity);
855  if (array != nullptr)
856  {
857  for (cxuint i = newSize; i < size; i++)
858  {
859  totalSize -= array[i].size;
860  array[i].~Node0();
861  }
862  std::move(array, array + newSize, newArray);
863  delete[] (reinterpret_cast<cxbyte*>(array) - parentEntrySize);
864  }
865 
866  array = newArray;
867  capacity = newCapacity;
868  size = newSize;
869  if (size == 0)
870  first = K();
871  }
872 
874  void reserve1(cxuint newCapacity)
875  {
876  cxbyte* newData = new cxbyte[newCapacity*sizeof(Node1) + parentEntrySize];
877  // set parent node
878  *reinterpret_cast<Node1**>(newData) = this;
879  Node1* newArray = reinterpret_cast<Node1*>(newData + parentEntrySize);
881  for (cxuint i = 0; i < newCapacity; i++)
882  new (newArray+i)Node1();
883  cxuint newSize = std::min(cxuint(size), newCapacity);
884  if (array != nullptr)
885  {
886  for (cxuint i = newSize; i < size; i++)
887  {
888  totalSize -= array1[i].totalSize;
889  array1[i].~Node1();
890  }
891  std::move(array1, array1 + newSize, newArray);
892  delete[] (reinterpret_cast<cxbyte*>(array1) - parentEntrySize);
893  }
894 
895  array1 = newArray;
896  capacity = newCapacity;
897  size = newSize;
898  if (size == 0)
899  first = K();
900  }
901 
902 
904  cxuint lowerBoundN(const K& v, const Comp& comp, const KeyOfVal& kofval) const
905  {
906  if (size == 0)
907  return 0;
908  if (NodeBase::type == NODE1)
909  {
910  cxuint l = 0, r = size;
911  cxuint m;
912  while (l+1<r)
913  {
914  m = (l+r)>>1;
915  if (comp(kofval(array[m].array[array[m].firstPos]), v))
916  l = m;
917  else
918  // !(array[m] < v) -> v <= array[m]
919  r = m;
920  }
921  if (comp(kofval(array[l].array[array[l].firstPos]), v))
922  l++;
923  return l;
924  }
925  else
926  {
927  if (size == 1)
928  // !(array[m] < v) -> v <= array[0]
929  return !comp(array1[0].first, v) ? 0 : 1;
930  cxuint l = 0, r = size;
931  cxuint m;
932  while (l+1 < r)
933  {
934  m = (l+r)>>1;
935  if (comp(array1[m].first, v))
936  l = m;
937  else
938  // !(array[m] < v) -> v <= array[m]
939  r = m;
940  }
941  if (comp(array1[l].first, v))
942  l++;
943  return l;
944  }
945  }
946 
948  cxuint upperBoundN(const K& v, const Comp& comp, const KeyOfVal& kofval) const
949  {
950  if (size == 0)
951  return 0;
952  if (NodeBase::type == NODE1)
953  {
954  cxuint l = 0, r = size;
955  cxuint m;
956  while (l+1 < r)
957  {
958  m = (l+r)>>1;
959  if (comp(v, kofval(array[m].array[array[m].firstPos])))
960  // !(array[m] < v) -> v <= array[m]
961  r = m;
962  else
963  l = m;
964  }
965  if (!comp(v, kofval(array[l].array[array[l].firstPos])))
966  l++;
967  return l;
968  }
969  else
970  {
971  cxuint l = 0, r = size;
972  cxuint m;
973  while (l+1 < r)
974  {
975  m = (l+r)>>1;
976  if (comp(v, array1[m].first))
977  // !(array[m] < v) -> v <= array[m]
978  r = m;
979  else
980  l = m;
981  }
982  if (!comp(v, array1[l].first))
983  l++;
984  return l;
985  }
986  }
987 
989  void insertNode0(Node0&& node, cxuint index, const KeyOfVal& kofval,
990  bool updateTotSize = true)
991  {
992  NodeBase::type = NODE1;
993  if (size+1 > capacity)
994  reserve0(std::min(std::max(capacity + (capacity>>1), size+1),
995  int(maxNode1Size)));
996  // move to next position
997  for (size_t i = size; i > index; i--)
998  {
999  array[i] = std::move(array[i-1]);
1000  array[i].index = i;
1001  }
1002 
1003  array[index] = std::move(node);
1004  array[index].index = index;
1005  if (index == 0 && array[0].array!=nullptr)
1006  first = kofval(array[0].array[array[0].firstPos]);
1007  size++;
1008  if (updateTotSize)
1009  totalSize += node.size;
1010  }
1011 
1013  void insertNode1(Node1&& node, cxuint index, bool updateTotSize = true)
1014  {
1015  NodeBase::type = NODE2;
1016  if (size+1 > capacity)
1017  reserve1(std::min(std::max(capacity + (capacity>>1), size+1),
1018  int(maxNode1Size)));
1019  // move to next position
1020  for (size_t i = size; i > index; i--)
1021  {
1022  array1[i] = std::move(array1[i-1]);
1023  array1[i].index = i;
1024  }
1025 
1026  array1[index] = std::move(node);
1027  array1[index].index = index;
1028  if (index == 0)
1029  first = array1[0].first;
1030  size++;
1031  if (updateTotSize)
1032  totalSize += node.totalSize;
1033  }
1034 
1036  void eraseNode0(cxuint index, const KeyOfVal& kofval, bool updateTotSize = true)
1037  {
1038  if (updateTotSize)
1039  totalSize -= array[index].size;
1040  std::move(array+index+1, array+size, array+index);
1041  if (size == index+1)
1042  {
1043  array[size-1].~Node0();
1044  array[size-1].array = nullptr;
1045  }
1046  for (cxuint i = index; i < size-1U; i++)
1047  array[i].index = i;
1048  if (size > 1 && index == 0)
1049  first = kofval(array[0].array[array[0].firstPos]);
1050  size--;
1051  if (size + (size>>1) < capacity)
1052  reserve0(size+1);
1053  if (size == 0)
1054  first = K();
1055  }
1056 
1058  void eraseNode1(cxuint index, bool updateTotSize = true)
1059  {
1060  if (updateTotSize)
1061  totalSize -= array1[index].totalSize;
1062  std::move(array1+index+1, array1+size, array1+index);
1063  if (size == index+1)
1064  {
1065  array1[size-1].~Node1();
1066  array1[size-1].array = nullptr;
1067  }
1068  for (cxuint i = index; i < size-1U; i++)
1069  array1[i].index = i;
1070  if (size > 1 && index == 0)
1071  first = array1[0].first;
1072  size--;
1073  if (size + (size>>1) < capacity)
1074  reserve1(size+1);
1075  if (size == 0)
1076  first = K();
1077  }
1078 
1079  void reorganizeNode0s(cxuint start, cxuint end, bool removeOneNode0 = false)
1080  {
1081  Node0 temps[maxNode1Size];
1082  cxuint nodesSize = 0;
1083  for (cxuint i = start; i < end; i++)
1084  nodesSize += array[i].size;
1085 
1086  cxuint newNodeSize = nodesSize / (end-start - removeOneNode0);
1087  cxuint withExtraElem = nodesSize - newNodeSize*(end-start - removeOneNode0);
1088  cxuint ni = 0; // new item start
1089  AT toFill = AT();
1090  cxuint inIndex, inPos;
1091  cxuint k = 0;
1092  cxuint factor = 0;
1093  cxuint newSize = newNodeSize + (ni < withExtraElem);
1094  temps[ni].allocate(newSize);
1095  temps[ni].index = start + ni;
1096  // main loop to fill up new node0's
1097  for (cxuint i = start; i < end; i++)
1098  {
1099  inPos = inIndex = 0;
1100  while(inIndex < array[i].capacity)
1101  {
1102  temps[ni].assignArray(toFill, array[i].size, inIndex, inPos,
1103  array[i].array, array[i].bitMask, newSize, k, factor);
1104  if (inPos < array[i].size)
1105  {
1106  // fill up end of new node0
1107  if (k < temps[ni].capacity)
1108  {
1109  temps[ni].array[k] = toFill;
1110  temps[ni].bitMask |= (1ULL<<k);
1111  }
1112 
1113  factor = k = 0;
1114  ni++;
1115  newSize = newNodeSize + (ni < withExtraElem);
1116  if (ni < end-start)
1117  {
1118  temps[ni].allocate(newSize);
1119  temps[ni].index = start + ni;
1120  }
1121  }
1122  }
1123  }
1124  // final move to this array
1125  std::move(temps, temps + end-start - removeOneNode0, array+start);
1126  if (removeOneNode0)
1127  {
1128  std::move(array + end, array + size, array + end - 1);
1129  for (cxuint i = end-1; i < cxuint(size - 1); i++)
1130  array[i].index = i;
1131  size--;
1132  }
1133  }
1134 
1135  void merge(Node1&& n2)
1136  {
1137  cxuint oldSize = size;
1138  if ((n2.size != 0 && n2.NodeBase::type == NODE1) ||
1139  (size != 0 && NodeBase::type == NODE1))
1140  {
1141  reserve0(std::max(cxuint(maxNode1Size), cxuint(capacity + n2.capacity)));
1142  std::move(n2.array, n2.array + n2.size, array + size);
1143  for (cxuint i = size; i < size+n2.size; i++)
1144  array[i].index = i;
1145  }
1146  else
1147  {
1148  NodeBase::type = NODE2;
1149  reserve1(std::max(cxuint(maxNode1Size), cxuint(capacity + n2.capacity)));
1150  std::move(n2.array1, n2.array1 + n2.size, array1 + size);
1151  for (cxuint i = size; i < size+n2.size; i++)
1152  array1[i].index = i;
1153  }
1154  totalSize += n2.totalSize;
1155  size += n2.size;
1156  if (oldSize == 0)
1157  first = n2.first;
1158  }
1159 
1160  void splitNode(Node1& n2, const KeyOfVal& kofval)
1161  {
1162  if (NodeBase::type == NODE1)
1163  {
1164  cxuint halfPos = 0;
1165  size_t halfTotSize = 0;
1166  for (; halfPos < size && halfTotSize < (totalSize>>1); halfPos++)
1167  halfTotSize += array[halfPos].size;
1168  if ((halfTotSize - (totalSize>>1)) > size_t(array[halfPos-1].size>>1))
1169  {
1170  halfPos--; //
1171  halfTotSize -= array[halfPos].size;
1172  }
1173 
1174  cxuint newSize2 = size - halfPos;
1175  size_t secHalfTotSize = totalSize - halfTotSize;
1176  n2.allocate0(std::min(newSize2, cxuint(maxNode1Size)));
1177  std::move(array + halfPos, array + size, n2.array);
1178  n2.totalSize = secHalfTotSize;
1179  n2.first = kofval(n2.array[0].array[n2.array[0].firstPos]);
1180  for (cxuint i = 0; i < newSize2; i++)
1181  n2.array[i].index = i;
1182  reserve0(halfPos);
1183  n2.size = newSize2;
1184  }
1185  else
1186  {
1187  cxuint halfPos = 0;
1188  size_t halfTotSize = 0;
1189  for (; halfPos < size && halfTotSize < (totalSize>>1); halfPos++)
1190  halfTotSize += array1[halfPos].totalSize;
1191  if ((halfTotSize - (totalSize>>1)) > (array1[halfPos-1].totalSize>>1))
1192  {
1193  halfPos--; //
1194  halfTotSize -= array1[halfPos].totalSize;
1195  }
1196 
1197  n2.NodeBase::type = NODE2;
1198  cxuint newSize2 = size - halfPos;
1199  size_t secHalfTotSize = totalSize - halfTotSize;
1200  n2.allocate1(std::min(newSize2, cxuint(maxNode1Size)));
1201  std::move(array1 + halfPos, array1 + size, n2.array1);
1202  n2.totalSize = secHalfTotSize;
1203  n2.first = n2.array1[0].first;
1204  for (cxuint i = 0; i < newSize2; i++)
1205  n2.array1[i].index = i;
1206  reserve1(halfPos);
1207  n2.size = newSize2;
1208  }
1209  }
1210 
1211  void reorganizeNode1s(cxuint start, cxuint end, const KeyOfVal& kofval,
1212  bool removeOneNode1 = false)
1213  {
1214  Node1 temps[maxNode1Size];
1215  cxuint node0sNum = 0;
1216  size_t nodesTotSize = 0;
1217  for (cxuint i = start; i < end; i++)
1218  {
1219  node0sNum += array1[i].size;
1220  nodesTotSize += array1[i].totalSize;
1221  }
1222 
1223  const cxuint end2 = end - removeOneNode1;
1224  cxuint node0Count = 0;
1225  cxuint j = start; // input node index
1226  cxuint k = 0; // input child node index
1227  cxuint remaining = end2-start-1;
1228  for (cxuint i = 0; i < end2-start; i++, remaining--)
1229  {
1230  temps[i].index = start+i;
1231  cxuint newNodeSize = nodesTotSize / (end2-start-i);
1232  for (; j < end; j++)
1233  {
1234  const Node1& child = array1[j];
1235  if (child.type == NODE2)
1236  for (; k < child.size && temps[i].size < maxNode1Size &&
1237  (temps[i].size < 2 ||
1238  (node0sNum-node0Count > remaining*maxNode1Size) ||
1239  // if no node0s in parent node
1240  temps[i].totalSize+(child.array1[k].totalSize>>1) <
1241  newNodeSize); k++, node0Count++)
1242  {
1243  if (node0sNum-node0Count <= (remaining<<1))
1244  // prevent too small node0s number for rest node1s
1245  break;
1246  temps[i].insertNode1(std::move(child.array1[k]),
1247  temps[i].size);
1248  }
1249  else
1250  for (; k < child.size && temps[i].size < maxNode1Size &&
1251  (temps[i].size < 2 ||
1252  (node0sNum-node0Count > remaining*maxNode1Size) ||
1253  // if no node0s in parent node
1254  temps[i].totalSize+(child.array[k].size>>1) < newNodeSize);
1255  k++, node0Count++)
1256  {
1257  if (node0sNum-node0Count <= (remaining<<1))
1258  // prevent too small node0s number for rest node1s and
1259  break;
1260  temps[i].insertNode0(std::move(child.array[k]),
1261  temps[i].size, kofval);
1262  }
1263 
1264  if (k >= child.size)
1265  k = 0; // if end of input node
1266  else
1267  break;
1268  }
1269 
1270  nodesTotSize -= temps[i].totalSize;
1271  }
1272 
1273  // final move to this array
1274  std::move(temps, temps + end-start - removeOneNode1, array1+start);
1275  if (removeOneNode1)
1276  {
1277  std::move(array1 + end, array1 + size, array1 + end - 1);
1278  for (cxuint i = end-1; i < cxuint(size - 1); i++)
1279  array1[i].index = i;
1280  size--;
1281  }
1282  }
1283  };
1284 
1285  static const size_t MaxNode01Size = sizeof(Node0) < sizeof(Node1) ?
1286  sizeof(Node1) : sizeof(Node0);
1287 
1288  static const size_t NodeVElemsNum = (MaxNode01Size -
1289  // calculate space took by NodeV fields
1290  (2 < alignof(T) ? alignof(T) : 2)) / sizeof(T);
1291 
1292  struct NodeV: NodeBase
1293  {
1294  cxbyte size;
1295  union {
1296  AT array[NodeVElemsNum];
1297  T arrayOut[NodeVElemsNum];
1298  };
1299 
1300  NodeV() : NodeBase(NODEV), size(0)
1301  { }
1302 
1303  NodeV(const NodeV& nv) : NodeBase(nv.NodeBase::type), size(nv.size)
1304  { std::copy(nv.array, nv.array + nv.size, array); }
1305  NodeV(NodeV&& nv) : NodeBase(nv.NodeBase::type), size(nv.size)
1306  { std::copy(nv.array, nv.array + nv.size, array); }
1307 
1308  NodeV& operator=(const NodeV& nv)
1309  {
1310  NodeBase::type = nv.NodeBase::type;
1311  size = nv.size;
1312  std::copy(nv.array, nv.array + nv.size, array);
1313  return *this;
1314  }
1315  NodeV& operator=(NodeV&& nv)
1316  {
1317  NodeBase::type = nv.NodeBase::type;
1318  size = nv.size;
1319  std::copy(nv.array, nv.array + nv.size, array);
1320  return *this;
1321  }
1322 
1323  void assignNode0(const Node0& n0)
1324  {
1325  size = n0.size;
1326  cxuint j = 0;
1327  for (cxuint i = 0; j < size; i++)
1328  if ((n0.bitMask & (1ULL<<i)) == 0)
1329  array[j++] = n0.array[i];
1330  }
1331 
1332  bool isFull() const
1333  { return size >= NodeVElemsNum; }
1334 
1335  cxuint lower_bound(const K& key, const Comp& comp, const KeyOfVal& kofval) const
1336  {
1337  cxuint index = 0;
1338  for (; index < size && comp(kofval(array[index]), key); index++);
1339  return index;
1340  }
1341 
1342  cxuint upper_bound(const K& key, const Comp& comp, const KeyOfVal& kofval) const
1343  {
1344  cxuint index = 0;
1345  for (; index < size && !comp(key, kofval(array[index])); index++);
1346  return index;
1347  }
1348 
1349  cxuint find(const K& key, const Comp& comp, const KeyOfVal& kofval) const
1350  {
1351  cxuint index = 0;
1352  for (; index < size && comp(kofval(array[index]), key); index++);
1353  if (index < size && !comp(key, kofval(array[index])))
1354  // if elem already found
1355  return index;
1356  return size;
1357  }
1358 
1359  std::pair<cxuint, bool> insert(const T& v,
1360  const Comp& comp, const KeyOfVal& kofval)
1361  {
1362  const K key = kofval(v);
1363  cxuint index = lower_bound(key, comp, kofval);
1364  if (index < size && !comp(key, kofval(array[index])))
1365  // if elem already found
1366  return std::make_pair(index, false);
1367 
1368  std::copy_backward(array + index, array + size, array + size + 1);
1369  array[index] = v;
1370  size++;
1371  return std::make_pair(index, true);
1372  }
1373 
1374  void erase(cxuint index)
1375  {
1376  std::copy(array + index + 1, array + size, array + index);
1377  size--;
1378  }
1379 
1380  const AT& operator[](cxuint i) const
1381  { return array[i]; }
1382 
1383  AT& operator[](cxuint i)
1384  { return array[i]; }
1385  };
1386 
1387 public:
1389  struct IterBase {
1390  typedef T value_type;
1391 
1392  union {
1393  Node0* n0; //< node
1394  const Node0* cn0; //< node
1395  NodeV* nv;
1396  const NodeV* cnv;
1397  };
1399 
1400  IterBase() : cn0(nullptr), index(0)
1401  { }
1402  IterBase(const Node0* _n0, cxuint _index) : cn0(_n0), index(_index)
1403  { }
1404  IterBase(Node0* _n0, cxuint _index) : n0(_n0), index(_index)
1405  { }
1406 
1407  IterBase& operator=(const IterBase& it)
1408  {
1409  n0 = it.n0;
1410  index = it.index;
1411  return *this;
1412  }
1413 
1414  void toNode0()
1415  {
1416  if (n0->type != NODE0)
1417  {
1418  // from root to last Node0
1419  n0 = reinterpret_cast<Node1*>(n0)->getLastNode0();
1420  index = n0->capacity;
1421  }
1422  }
1423 
1425  void next(size_t inc)
1426  {
1427  if (n0->type == NODEV)
1428  {
1429  index += inc;
1430  return;
1431  }
1432  toNode0();
1433 
1434  // first skip in elements this node0
1435  while (index < n0->capacity && inc != 0)
1436  {
1437  if ((n0->bitMask & (1ULL<<index)) == 0)
1438  inc--;
1439  index++;
1440  }
1441  while (index < n0->capacity && (n0->bitMask & (1ULL<<index)) != 0)
1442  index++;
1443 
1444  bool end = false;
1445  // we need to go to next node0
1446  if (index >= n0->capacity)
1447  {
1448  const Node1* n[maxNode1Depth];
1449  //Node1* n1 = n0->parent();
1450  n[1] = n0->parent();
1451  if (n[1] != nullptr)
1452  {
1453  n0++;
1454  // skipping node0's
1455  for (; n0 < n[1]->array+n[1]->size; n0++)
1456  if (n0->size <= inc)
1457  inc -= n0->size;
1458  else
1459  break;
1460 
1461  if (n0 - n[1]->array >= n[1]->size)
1462  {
1463  cxuint i = 1;
1464  for (; i < 20 ; i++)
1465  {
1466  n[i+1] = n[i]->parent();
1467  if (n[i+1] == nullptr)
1468  {
1469  cn0 = reinterpret_cast<const Node0*>(n[i]);
1470  index = n[i]->size;
1471  end = true;
1472  break;
1473  }
1474  n[i]++;
1476  for (; n[i] < n[i+1]->array1+n[i+1]->size; n[i]++)
1477  if (n[i]->totalSize <= inc)
1478  inc -= n[i]->totalSize;
1479  else
1480  break;
1481 
1482  // if it is this level
1483  if (n[i] - n[i+1]->array1 < n[i+1]->size)
1484  break;
1485  }
1486  if (!end)
1487  {
1488  for (; i > 1; i--)
1489  if (n[i+1] != nullptr)
1490  {
1491  // set this node1 for this level
1492  n[i-1] = n[i]->array1;
1494  for (; n[i-1] < n[i]->array1+n[i]->size; n[i-1]++)
1495  if (n[i-1]->totalSize <= inc)
1496  inc -= n[i-1]->totalSize;
1497  else
1498  break;
1499  }
1500  if (n[2] != nullptr)
1501  {
1502  n0 = n[1]->array;
1504  for (; n0 < n[1]->array+n[1]->size; n0++)
1505  if (n0->size <= inc)
1506  inc -= n0->size;
1507  else
1508  break;
1509  }
1510  }
1511  else
1512  // set end
1513  index = n[i]->size;
1514  }
1515  if (!end)
1516  index = n0->firstPos;
1517  }
1518  else
1519  end = true;
1520  }
1521 
1522  if (!end)
1523  {
1524  // skip last elements in count
1525  while (index < n0->capacity && inc != 0)
1526  {
1527  if ((n0->bitMask & (1ULL<<index)) == 0)
1528  inc--; // if it not free space
1529  index++;
1530  }
1531  // and skip empty space
1532  while (index < n0->capacity && (n0->bitMask & (1ULL<<index)) != 0)
1533  index++;
1534  }
1535  }
1536 
1538  {
1539  bool end = false;
1540  if (index >= n0->capacity)
1541  {
1542  const Node1* n[maxNode1Depth];
1543  //Node1* n1 = n0->parent();
1544  n[1] = n0->parent();
1545  if (n[1] != nullptr)
1546  {
1547  n0++;
1548  if (n0 - n[1]->array >= n[1]->size)
1549  {
1550  // deeper level is needed to be visited
1551  cxuint i = 1;
1552  for (; i < 20 ; i++)
1553  {
1554  n[i+1] = n[i]->parent();
1555  if (n[i+1] == nullptr)
1556  {
1557  // if end of tree
1558  cn0 = reinterpret_cast<const Node0*>(n[i]);
1559  index = n[i]->size;
1560  end = true;
1561  break;
1562  }
1563  n[i]++;
1564  if (n[i] - n[i+1]->array1 < n[i+1]->size)
1565  // if it is this level
1566  break;
1567  }
1568  if (!end)
1569  {
1570  for (; i > 1; i--)
1571  if (n[i+1] != nullptr)
1572  // set node for shallower level
1573  n[i-1] = n[i]->array1;
1574  if (n[2] != nullptr)
1576  n0 = n[1]->array;
1577  }
1578  else
1579  // set end
1580  index = n[i]->size;
1581  }
1582  if (!end)
1583  // do not set index if end of tree
1584  index = n0->firstPos;
1585  }
1586  else
1587  end = true;
1588  }
1589  }
1590 
1592  void next()
1593  {
1594  if (n0->type == NODEV)
1595  {
1596  index++;
1597  return;
1598  }
1599 
1600  toNode0();
1601 
1602  // skip empty space
1603  index++;
1604  while (index < n0->capacity && (n0->bitMask & (1ULL<<index)) != 0)
1605  index++;
1606 
1607  toNextNode0();
1608  }
1609 
1611  void prev(size_t inc)
1612  {
1613  if (n0->type == NODEV)
1614  {
1615  index -= inc;
1616  return;
1617  }
1618  toNode0();
1619 
1620  while (index != UINT_MAX && inc != 0)
1621  {
1622  if (index==n0->capacity || (n0->bitMask & (1ULL<<index)) == 0)
1623  inc--;
1624  index--;
1625  }
1626  while (index != UINT_MAX &&
1627  (index != n0->capacity && (n0->bitMask & (1ULL<<index)) != 0))
1628  index--;
1629 
1630  bool end = false;
1631  if (index == UINT_MAX)
1632  {
1633  const Node1* n[maxNode1Depth];
1634  //Node1* n1 = n0->parent();
1635  n[1] = n0->parent();
1636  if (n[1] != nullptr)
1637  {
1638  n0--;
1639  // skipping node0's
1640  for (; n0 >= n[1]->array; n0--)
1641  if (n0->size <= inc)
1642  inc -= n0->size;
1643  else
1644  break;
1645  if (n0 - n[1]->array < 0)
1646  {
1647  cxuint i = 1;
1648  for (; i < 20 ; i++)
1649  {
1650  n[i+1] = n[i]->parent();
1651  if (n[i+1] == nullptr)
1652  {
1653  end = true;
1654  break;
1655  }
1656  n[i]--;
1657  // skipping node1's
1658  for (; n[i] >= n[i+1]->array1; n[i]--)
1659  if (n[i]->totalSize <= inc)
1660  inc -= n[i]->totalSize;
1661  else
1662  break;
1663  if (n[i] - n[i+1]->array1 >= 0)
1664  break;
1665  }
1666  for (; i > 1; i--)
1667  if (n[i+1] != nullptr)
1668  {
1669  if (end)
1670  {
1671  // if end, then set to first node
1672  n[i-1] = n[i][1].array1;
1673  continue;
1674  }
1675  n[i-1] = n[i]->array1 + n[i]->size-1;
1676  // further skipping for shallower level
1677  for (; n[i-1] >= n[i]->array1; n[i-1]--)
1678  if (n[i-1]->totalSize <= inc)
1679  inc -= n[i-1]->totalSize;
1680  else
1681  break;
1682  }
1683  if (n[2] != nullptr)
1684  {
1685  if (end)
1686  n0 = n[1][0].array;
1687  else
1688  {
1689  n0 = n[1]->array + n[1]->size-1;
1690  for (; n0 >= n[1]->array; n0--)
1691  if (n0->size <= inc)
1692  inc -= n0->size;
1693  else
1694  break;
1695  }
1696  }
1697  }
1698  if (!end)
1699  // set index for this node2 (from end of array)
1700  index = n0->capacity-1;
1701  else
1702  // set index for before begin (end)
1703  index = UINT_MAX;
1704  }
1705  else
1706  end = true;
1707  }
1708 
1709  if (!end)
1710  {
1711  // skipping last elements in array of node0
1712  while (index != UINT_MAX && inc != 0)
1713  {
1714  if ((n0->bitMask & (1ULL<<index)) == 0)
1715  inc--;
1716  index--;
1717  }
1718  // and skip empty space
1719  while (index != UINT_MAX && (n0->bitMask & (1ULL<<index)) != 0)
1720  index--;
1721  }
1722  }
1723 
1725  void prev()
1726  {
1727  if (n0->type == NODEV)
1728  {
1729  index--;
1730  return;
1731  }
1732  toNode0();
1733 
1734  index--;
1735  while (index != UINT_MAX &&
1736  (index != n0->capacity && (n0->bitMask & (1ULL<<index)) != 0))
1737  index--;
1738 
1739  bool end = false;
1740  if (index == UINT_MAX)
1741  {
1742  const Node1* n[maxNode1Depth];
1743  //Node1* n1 = n0->parent();
1744  n[1] = n0->parent();
1745  if (n[1] != nullptr)
1746  {
1747  n0--;
1748  if (n0 - n[1]->array < 0)
1749  {
1750  cxuint i = 1;
1751  for (; i < 20 ; i++)
1752  {
1753  n[i+1] = n[i]->parent();
1754  if (n[i+1] == nullptr)
1755  {
1756  end = true;
1757  break;
1758  }
1759  n[i]--;
1760  if (n[i] - n[i+1]->array1 >= 0)
1761  // if it is this level
1762  break;
1763  }
1764  for (; i > 1; i--)
1765  if (n[i+1] != nullptr && !end)
1766  // set node for shallower level
1767  n[i-1] = n[i]->array1 + n[i]->size-1;
1768  if (n[2] != nullptr && !end)
1769  // set node for shallowest level
1770  n0 = n[1]->array + n[1]->size-1;
1771  }
1772  if (!end)
1773  index = n0->capacity-1;
1774  }
1775  else
1776  end = true;
1777  }
1778 
1779  if (end)
1780  // revert if end (before begin)
1781  n0++;
1782 
1784  while (index != UINT_MAX && (n0->bitMask & (1ULL<<index)) != 0)
1785  index--;
1786  }
1787 
1789  void step(ssize_t i)
1790  {
1791  if (i > 0)
1792  next(i);
1793  else if (i < 0)
1794  prev(-i);
1795  }
1796 
1798  ssize_t diff(const IterBase& k2) const
1799  {
1800  if (n0->type == NODEV)
1801  return index - k2.index;
1802 
1803  ssize_t count = 0;
1804  IterBase i1 = *this;
1805  IterBase i2 = k2;
1806  i1.toNode0();
1807  i2.toNode0();
1808  if (i1.n0 == i2.n0)
1809  {
1810  // if node0's are same
1811  cxuint index1 = std::min(i1.index, i2.index);
1812  cxuint index2 = std::max(i1.index, i2.index);
1813  // calculate element between indices
1814  for (cxuint i = index1; i < index2; i++)
1815  if ((i1.n0->bitMask & (1ULL<<i)) == 0)
1816  count++;
1817  return index2 == i1.index ? count : -count;
1818  }
1819  const Node1* n1[maxNode1Depth];
1820  const Node1* n2[maxNode1Depth];
1821  const Node0* xn0_1 = i1.n0;
1822  const Node0* xn0_2 = i2.n0;
1823  cxuint index1 = i1.index;
1824  cxuint index2 = i2.index;
1825  n1[0] = i1.n0->parent();
1826  n2[0] = i2.n0->parent();
1827 
1828  cxuint i = 0;
1830  while (n1[i] != n2[i])
1831  {
1832  i++;
1833  n1[i] = n1[i-1]->parent();
1834  n2[i] = n2[i-1]->parent();
1835  };
1836 
1837  bool negate = false;
1838  // sumarizing
1839  if ((i==0 && xn0_2->index < xn0_1->index) ||
1840  (i>0 && n2[i-1]->index < n1[i-1]->index))
1841  {
1842  // if this position are beyond i2 position, no negation, but swapping
1843  std::swap_ranges(n1, n1+i+1, n2);
1844  std::swap(xn0_1, xn0_2);
1845  std::swap(index1, index2);
1846  }
1847  else
1848  negate = true;
1849 
1850  if (i==0) // first level
1851  for (cxuint j = xn0_1->index+1; j < xn0_2->index; j++)
1852  count += n1[i]->array[j].size;
1853  else
1854  {
1855  // couting elements for nodes between this node and i2's node
1856  for (cxuint j = n1[i-1]->index+1; j < n2[i-1]->index; j++)
1857  count += n1[i]->array1[j].totalSize;
1858 
1859  for (i--; i >= 1; i--)
1860  {
1861  // in shallower level, count left nodes after n1 node
1862  for (cxuint j = n1[i-1]->index+1; j < n1[i]->size; j++)
1863  count += n1[i]->array1[j].totalSize;
1865  for (cxuint j = 0; j < n2[i-1]->index; j++)
1866  count += n2[i]->array1[j].totalSize;
1867  }
1868  // in shallower level, count left nodes after n1 node
1869  for (cxuint j = xn0_1->index+1; j < n1[0]->size; j++)
1870  count += n1[0]->array[j].size;
1872  for (cxuint j = 0; j < xn0_2->index; j++)
1873  count += n2[0]->array[j].size;
1874  }
1875 
1876  // last distances in left
1877  for (cxuint j = index1; j < xn0_1->capacity; j++)
1878  if ((xn0_1->bitMask & (1ULL<<j)) == 0)
1879  count++;
1880  // right side
1881  for (cxuint j = 0; j < index2; j++)
1882  if ((xn0_2->bitMask & (1ULL<<j)) == 0)
1883  count++;
1884 
1885  return negate ? -count : count;
1886  }
1887  };
1888 
1890  struct Iter: IterBase
1891  {
1892  typedef T value_type;
1893  typedef T& reference;
1894  typedef T* pointer;
1895  typedef ssize_t difference_type;
1896  typedef std::bidirectional_iterator_tag iterator_category;
1897 
1899  Iter(Node0* n0 = nullptr, cxuint index = 0): IterBase{n0, index}
1900  { }
1901 
1902  Iter(const IterBase& it) : IterBase(it)
1903  { }
1904 
1907  {
1908  IterBase::next();
1909  return *this;
1910  }
1911  // post-increment
1912  Iter operator++(int)
1913  {
1914  Iter tmp = *this;
1915  IterBase::next();
1916  return tmp;
1917  }
1919  Iter operator+(ssize_t i) const
1920  {
1921  Iter tmp = *this;
1922  tmp.IterBase::step(i);
1923  return tmp;
1924  }
1926  Iter& operator+=(ssize_t i)
1927  {
1928  IterBase::step(i);
1929  return *this;
1930  }
1933  {
1934  IterBase::prev();
1935  return *this;
1936  }
1939  {
1940  Iter tmp = *this;
1941  IterBase::prev();
1942  return tmp;
1943  }
1945  Iter operator-(ssize_t i) const
1946  {
1947  Iter tmp = *this;
1948  tmp.IterBase::step(-i);
1949  return tmp;
1950  }
1952  Iter& operator-=(ssize_t i)
1953  {
1954  IterBase::step(-i);
1955  return *this;
1956  }
1957  // distance between iterators
1958  ssize_t operator-(const IterBase& i2) const
1959  { return IterBase::diff(i2); }
1961  T& operator*() const
1962  {
1963  return (IterBase::n0->type == NODE0) ?
1964  IterBase::n0->arrayOut[IterBase::index] :
1965  IterBase::nv->arrayOut[IterBase::index];
1966  }
1968  T* operator->() const
1969  {
1970  return (IterBase::n0->type == NODE0) ?
1971  IterBase::n0->arrayOut + IterBase::index :
1972  IterBase::nv->arrayOut + IterBase::index;
1973  }
1975  bool operator==(const IterBase& it) const
1976  { return IterBase::n0==it.n0 && IterBase::index==it.index; }
1978  bool operator!=(const IterBase& it) const
1979  { return IterBase::n0!=it.n0 || IterBase::index!=it.index; }
1980  };
1981 
1984  {
1985  typedef T value_type;
1986  typedef const T& reference;
1987  typedef const T* pointer;
1988  typedef ssize_t difference_type;
1989  typedef std::bidirectional_iterator_tag iterator_category;
1990 
1992  ConstIter(const Node0* n0 = nullptr, cxuint index = 0): IterBase{n0, index}
1993  { }
1994 
1995  ConstIter(const IterBase& it) : IterBase(it)
1996  { }
1997 
2000  {
2001  IterBase::next();
2002  return *this;
2003  }
2006  {
2007  ConstIter tmp = *this;
2008  IterBase::next();
2009  return tmp;
2010  }
2012  ConstIter operator+(ssize_t i) const
2013  {
2014  ConstIter tmp = *this;
2015  tmp.IterBase::step(i);
2016  return tmp;
2017  }
2019  ConstIter& operator+=(ssize_t i)
2020  {
2021  IterBase::step(i);
2022  return *this;
2023  }
2026  {
2027  IterBase::prev();
2028  return *this;
2029  }
2032  {
2033  ConstIter tmp = *this;
2034  IterBase::prev();
2035  return tmp;
2036  }
2038  ConstIter operator-(ssize_t i) const
2039  {
2040  ConstIter tmp = *this;
2041  tmp.IterBase::step(-i);
2042  return tmp;
2043  }
2045  ConstIter& operator-=(ssize_t i)
2046  {
2047  IterBase::step(-i);
2048  return *this;
2049  }
2050 
2051  // distance between iterators
2052  ssize_t operator-(const IterBase& i2) const
2053  { return IterBase::diff(i2); }
2055  const T& operator*() const
2056  {
2057  return (IterBase::n0->type == NODE0) ?
2058  IterBase::n0->arrayOut[IterBase::index] :
2059  IterBase::nv->arrayOut[IterBase::index];
2060  }
2062  const T* operator->() const
2063  {
2064  return (IterBase::n0->type == NODE0) ?
2065  IterBase::n0->arrayOut + IterBase::index :
2066  IterBase::nv->arrayOut + IterBase::index;
2067  }
2069  bool operator==(const IterBase& it) const
2070  { return IterBase::n0==it.n0 && IterBase::index==it.index; }
2072  bool operator!=(const IterBase& it) const
2073  { return IterBase::n0!=it.n0 || IterBase::index!=it.index; }
2074  };
2075 #ifdef DTREE_TESTING
2076 public:
2077 #else
2078 protected:
2079 #endif
2080  union {
2081  Node0 n0; // root Node0
2082  Node1 n1; // root Node1
2083  NodeV nv; // root NodeV
2084  };
2085 public:
2087  typedef ConstIter const_iterator;
2088  typedef Iter iterator;
2089  typedef T value_type;
2090  typedef K key_type;
2091 
2093  DTree(const Comp& comp = Comp(), const KeyOfVal& kofval = KeyOfVal())
2094  : Comp(comp), KeyOfVal(kofval), nv()
2095  { }
2096 
2097 #if DTREE_TESTING
2098  DTree(const Node0& node0, const Comp& comp = Comp(),
2099  const KeyOfVal& kofval = KeyOfVal()) : Comp(comp), KeyOfVal(kofval), n0(node0)
2100  { }
2101 
2102  DTree(const Node1& node1, const Comp& comp = Comp(),
2103  const KeyOfVal& kofval = KeyOfVal()) : Comp(comp), KeyOfVal(kofval), n1(node1)
2104  { }
2105 #endif
2106  template<typename Iter>
2108  DTree(Iter first, Iter last, const Comp& comp = Comp(),
2109  const KeyOfVal& kofval = KeyOfVal()) : Comp(comp), KeyOfVal(kofval), nv()
2110  {
2111  for (Iter it = first; it != last; ++it)
2112  insert(*it);
2113  }
2114 
2116  DTree(std::initializer_list<value_type> init, const Comp& comp = Comp(),
2117  const KeyOfVal& kofval = KeyOfVal()) : Comp(comp), KeyOfVal(kofval), nv()
2118  {
2119  for (const value_type& v: init)
2120  insert(v);
2121  }
2123  DTree(const DTree& dt)
2124  {
2125  if (dt.nv.type == NODEV)
2126  nv = dt.nv;
2127  else if (dt.n0.type == NODE0)
2128  {
2129  n0.array = nullptr;
2130  n0 = dt.n0;
2131  }
2132  else
2133  {
2134  n1.array = nullptr;
2135  n1 = dt.n1;
2136  }
2137  }
2139  DTree(DTree&& dt) noexcept
2140  {
2141  if (dt.nv.type == NODEV)
2142  nv = dt.nv;
2143  else if (dt.n0.type == NODE0)
2144  {
2145  n0.array = nullptr;
2146  n0 = std::move(dt.n0);
2147  }
2148  else
2149  {
2150  n1.array = nullptr;
2151  n1 = std::move(dt.n1);
2152  }
2153  }
2156  {
2157  if (n0.type == NODE0)
2158  n0.~Node0();
2159  else if (n0.type != NODEV)
2160  n1.~Node1();
2161  }
2162 
2164  DTree& operator=(const DTree& dt)
2165  {
2166  if (this == &dt)
2167  return *this;
2168  if (n0.type == NODE0)
2169  n0.~Node0();
2170  else if (n0.type != NODEV)
2171  n1.~Node1();
2172 
2173  if (dt.n0.type == NODEV)
2174  nv = dt.nv;
2175  else if (dt.n0.type == NODE0)
2176  {
2177  n0.array = nullptr;
2178  n0 = dt.n0;
2179  }
2180  else
2181  {
2182  n1.array = nullptr;
2183  n1 = dt.n1;
2184  }
2185  return *this;
2186  }
2188  DTree& operator=(DTree&& dt) noexcept
2189  {
2190  if (this == &dt)
2191  return *this;
2192  if (n0.type == NODE0)
2193  n0.~Node0();
2194  else if (n0.type != NODEV)
2195  n1.~Node1();
2196 
2197  if (dt.n0.type == NODEV)
2198  nv = dt.nv;
2199  else if (dt.n0.type == NODE0)
2200  {
2201  n0.array = nullptr;
2202  n0 = std::move(dt.n0);
2203  }
2204  else
2205  {
2206  n1.array = nullptr;
2207  n1 = std::move(dt.n1);
2208  }
2209  return *this;
2210  }
2212  DTree& operator=(std::initializer_list<value_type> init)
2213  { return *this; }
2214 
2216  bool empty() const
2217  { return (n0.type==NODE0 && n0.size==0) || (nv.type==NODEV && nv.size==0); }
2218 
2220  size_t size() const
2221  {
2222  if (nv.type==NODEV)
2223  return nv.size;
2224  return n0.type==NODE0 ? n0.size : n1.totalSize;
2225  }
2226 
2228  void clear()
2229  {
2230  if (n0.type == NODE0)
2231  n0.~Node0();
2232  else if (n0.type != NODEV)
2233  n1.~Node1();
2234  nv = NodeV();
2235  }
2236 
2237 private:
2238  IterBase findInt(const key_type& key) const
2239  {
2240  if (n0.type == NODEV)
2241  return IterBase{&n0, nv.find(key, *this, *this)};
2242 
2243  if (n0.type == NODE0)
2244  return IterBase{&n0, n0.find(key, *this, *this)};
2245  const Node1* curn1 = &n1;
2246  cxuint index = 0;
2247  while (curn1->type == NODE2)
2248  {
2249  index = curn1->upperBoundN(key, *this, *this);
2250  if (index == 0)
2251  return end();
2252  curn1 = curn1->array1 + index - 1;
2253  }
2254  // node1
2255  index = curn1->upperBoundN(key, *this, *this);
2256  if (index == 0)
2257  return end();
2258  const Node0* curn0 = curn1->array + index - 1;
2259  // node0
2260  IterBase it{curn0, curn0->find(key, *this, *this)};
2261  if (it.index == curn0->capacity)
2262  return end();
2263  return it;
2264  }
2265 
2266  IterBase lower_boundInt(const key_type& key) const
2267  {
2268  if (n0.type == NODEV)
2269  return IterBase{&n0, nv.lower_bound(key, *this, *this)};
2270 
2271  if (n0.type == NODE0)
2272  return IterBase{&n0, n0.lower_bound(key, *this, *this)};
2273  const Node1* curn1 = &n1;
2274  cxuint index = 0;
2275  while (curn1->type == NODE2)
2276  {
2277  index = curn1->upperBoundN(key, *this, *this);
2278  if (index == 0)
2279  return begin();
2280  curn1 = curn1->array1 + index - 1;
2281  }
2282  // node1
2283  index = curn1->upperBoundN(key, *this, *this);
2284  if (index == 0)
2285  return begin();
2286  const Node0* curn0 = curn1->array + index - 1;
2287  // node0
2288  IterBase it{curn0, curn0->lower_bound(key, *this, *this)};
2289  if (it.index == curn0->capacity)
2290  it.toNextNode0();
2291  return it;
2292  }
2293 
2294  IterBase upper_boundInt(const key_type& key) const
2295  {
2296  if (n0.type == NODEV)
2297  return IterBase{&n0, nv.upper_bound(key, *this, *this)};
2298 
2299  if (n0.type == NODE0)
2300  return IterBase{&n0, n0.upper_bound(key, *this, *this)};
2301  const Node1* curn1 = &n1;
2302  cxuint index = 0;
2303  while (curn1->type == NODE2)
2304  {
2305  index = curn1->upperBoundN(key, *this, *this);
2306  if (index == 0)
2307  return begin();
2308  curn1 = curn1->array1 + index - 1;
2309  }
2310  index = curn1->upperBoundN(key, *this, *this);
2311  if (index == 0)
2312  return begin();
2313  const Node0* curn0 = curn1->array + index - 1;
2314  // node0
2315  IterBase it{curn0, curn0->upper_bound(key, *this, *this)};
2316  if (it.index == curn0->capacity)
2317  it.toNextNode0();
2318  return it;
2319  }
2320 
2321 public:
2323  iterator find(const key_type& key)
2324  { return findInt(key); }
2326  const_iterator find(const key_type& key) const
2327  { return findInt(key); }
2328 
2330  iterator begin()
2331  {
2332  if (nv.type == NODEV)
2333  return iterator(&n0, 0);
2334  if (n0.type == NODE0)
2335  return iterator(&n0, n0.firstPos);
2336  else
2337  {
2338  iterator it(n1.getFirstNode0());
2339  it.index = it.n0->firstPos;
2340  return it;
2341  }
2342  }
2344  const_iterator cbegin() const
2345  {
2346  if (nv.type == NODEV)
2347  return const_iterator(&n0, 0);
2348  if (n0.type == NODE0)
2349  return const_iterator(&n0, n0.firstPos);
2350  else
2351  {
2352  const_iterator it(n1.getFirstNode0());
2353  it.index = it.n0->firstPos;
2354  return it;
2355  }
2356  }
2358  const_iterator begin() const
2359  { return cbegin(); }
2361  iterator end()
2362  {
2363  if (nv.type == NODEV)
2364  return iterator(&n0, nv.size);
2365  return iterator(&n0, n0.type==NODE0 ? n0.capacity : n1.size);
2366  }
2368  const_iterator end() const
2369  {
2370  if (nv.type == NODEV)
2371  return const_iterator(&n0, nv.size);
2372  return const_iterator(&n0, n0.type==NODE0 ? n0.capacity : n1.size);
2373  }
2375  const_iterator cend() const
2376  {
2377  if (nv.type == NODEV)
2378  return const_iterator(&n0, nv.size);
2379  return const_iterator(&n0, n0.type==NODE0 ? n0.capacity : n1.size);
2380  }
2381 
2383  iterator lower_bound(const key_type& key)
2384  { return lower_boundInt(key); }
2386  const_iterator lower_bound(const key_type& key) const
2387  { return lower_boundInt(key); }
2389  iterator upper_bound(const key_type& key)
2390  { return upper_boundInt(key); }
2392  const_iterator upper_bound(const key_type& key) const
2393  { return upper_boundInt(key); }
2394 
2395 #ifdef DTREE_TESTING
2396 public:
2397 #else
2398 private:
2399 #endif
2400  static void findReorgBounds0(cxuint n0Index, const Node1* curn1, cxuint neededN0Size,
2401  cxint& left, cxint& right, bool* removeOneNode = nullptr)
2402  {
2403  cxuint freeSpace = 0;
2404  left = right = n0Index;
2405  cxuint nodeCount = 0;
2406  do {
2407  left--;
2408  right++;
2409  if (left >= 0)
2410  {
2411  freeSpace += maxNode0Size - curn1->array[left].size;
2412  nodeCount++;
2413  }
2414  if (right < curn1->size)
2415  {
2416  freeSpace += maxNode0Size - curn1->array[right].size;
2417  nodeCount++;
2418  }
2419  } while (freeSpace < neededN0Size && (left >= 0 || right < curn1->size));
2420 
2421  left = std::max(0, left);
2422  right = std::min(curn1->size-1, right);
2423  if (removeOneNode != nullptr)
2424  *removeOneNode = freeSpace >= neededN0Size;
2425  }
2426 
2427  static void findReorgBounds1(const Node1* prevn1, const Node1* curn1,
2428  size_t neededN1Size, size_t maxN1Size, cxint& left, cxint& right,
2429  bool* removeOneNode = nullptr)
2430  {
2431  cxuint n1Index = prevn1->index;
2432  size_t freeSpace = 0;
2433  left = right = n1Index;
2434  cxuint children = prevn1->size;
2435  const size_t needed = neededN1Size + (neededN1Size>>2);
2436 
2437  do {
2438  left--;
2439  right++;
2440  if (left >= 0)
2441  {
2442  freeSpace += maxN1Size -
2443  std::min(curn1->array1[left].totalSize, maxN1Size);
2444  children += curn1->array1[left].size;
2445  }
2446  if (right < curn1->size)
2447  {
2448  freeSpace += maxN1Size -
2449  std::min(curn1->array1[right].totalSize, maxN1Size);
2450  children += curn1->array1[right].size;
2451  }
2452  } while (freeSpace < needed && (left >= 0 || right < curn1->size));
2453 
2454  left = std::max(0, left);
2455  right = std::min(curn1->size-1, right);
2456  if (removeOneNode != nullptr)
2457  *removeOneNode = (freeSpace >= needed &&
2458  children < maxNode1Size*(right-left));
2459  }
2460 public:
2461 
2463  std::pair<iterator, bool> insert(const value_type& value)
2464  {
2465  if (nv.type == NODEV)
2466  {
2467  if (!nv.isFull())
2468  {
2469  auto res = nv.insert(value, *this, *this);
2470  return std::make_pair(iterator(&n0, res.first), res.second);
2471  }
2472  else
2473  {
2474  // if full
2475  NodeV tmpnv = nv;
2476  n0.array = nullptr;
2477  n0 = Node0();
2478  n0.setFromArray(tmpnv.size, tmpnv.array);
2479  }
2480  }
2481  const key_type key = KeyOfVal::operator()(value);
2482  iterator it = lower_bound(key);
2483  if (it!=end())
2484  {
2485  const key_type itkey = KeyOfVal::operator()(*it);
2486  if (!Comp::operator()(key, itkey))
2487  return std::make_pair(it, false);
2488  }
2489 
2490  if (it.n0->type != NODE0)
2491  it.toNode0();
2492 
2493  cxuint index = it.n0->insert(value, *this, *this).first;
2494  Node1* curn1 = it.n0->parent();
2495  iterator newit(it.n0, index);
2496  // reorganize/merge/split needed
2497  if (it.n0->size > maxNode0Size)
2498  {
2499  // simple split to first level
2500  cxuint n0Index = it.n0->index;
2501  if (curn1 == nullptr || curn1->size < maxNode1Size)
2502  {
2503  // put new node0 in node1 or create new node1 with two nodes
2504  Node0 node0_2;
2505  it.n0->split(node0_2);
2506  cxuint index = 0;
2507  bool secondNode = false;
2508  if (Comp::operator()(key,
2509  KeyOfVal::operator()(node0_2.array[it.n0->firstPos])))
2510  // key < first key in second node0
2511  index = it.n0->lower_bound(key, *this, *this);
2512  else
2513  { // put to node0 2
2514  secondNode = true;
2515  index = node0_2.lower_bound(key, *this, *this);
2516  }
2517  if (curn1 == nullptr)
2518  {
2519  Node1 node1(std::move(*it.n0), std::move(node0_2), *this);
2520  new(&n1) Node1();
2521  n1 = std::move(node1);
2522 
2523  return std::make_pair(iterator(n1.array + secondNode, index), true);
2524  }
2525  curn1->insertNode0(std::move(node0_2), n0Index+1, *this, false);
2526  newit = iterator(curn1->array + n0Index + secondNode, index);
2527  }
2528  else
2529  {
2530  cxint left, right;
2531  // reorganize in this level
2532  findReorgBounds0(it.n0->index, curn1, it.n0->size, left, right);
2533 
2534  // reorganize array from left to right
2535  curn1->reorganizeNode0s(left, right+1);
2536  // find newit for inserted value
2537  newit.n0 = curn1->array + curn1->upperBoundN(key, *this, *this) - 1;
2538  newit.index = newit.n0->lower_bound(key, *this, *this);
2539  }
2540  }
2541 
2542  cxuint level = 1;
2543  Node1* prevn1 = nullptr;
2544  while (curn1 != nullptr)
2545  {
2546  prevn1 = curn1;
2547  curn1 = prevn1->parent();
2548  prevn1->first = prevn1->NodeBase::type==NODE1 ?
2549  KeyOfVal::operator()(
2550  prevn1->array[0].array[prevn1->array[0].firstPos]) :
2551  prevn1->array1[0].first;
2552 
2553  prevn1->totalSize++; // increase
2554  cxuint maxN1Size = maxTotalSize(level);
2555 
2556  if (prevn1->totalSize > maxN1Size)
2557  {
2558  cxuint n0Index = newit.n0->index;
2559  cxuint n1Index = prevn1->index;
2560  if (curn1 == nullptr || curn1->size < maxNode1Size)
2561  {
2562  // simple split
2563  Node1 node1_2;
2564  prevn1->splitNode(node1_2, *this);
2565 
2566  if (level==1)
2567  {
2568  if (n0Index < prevn1->size)
2569  newit.n0 = prevn1->array + n0Index;
2570  else
2571  newit.n0 = node1_2.array + n0Index - prevn1->size;
2572  }
2573  // node0 has been moved (no array/array1 pointer change/reallocate)
2574  if (curn1 == nullptr)
2575  {
2576  Node1 node1(std::move(*prevn1), std::move(node1_2));
2577  n1 = std::move(node1);
2578  }
2579  else
2580  curn1->insertNode1(std::move(node1_2), n1Index+1, false);
2581  }
2582  else
2583  {
2584  // reorganize nodes
2585  cxint left, right;
2586  findReorgBounds1(prevn1, curn1, prevn1->totalSize,
2587  maxN1Size, left, right);
2588  // reorganize array from left to right
2589  curn1->reorganizeNode1s(left, right+1, *this);
2590  if (level == 1)
2591  {
2592  const Node1* pn1 = curn1->array1 +
2593  curn1->upperBoundN(key, *this, *this) - 1;
2594  newit.n0 = pn1->array + pn1->upperBoundN(key, *this, *this) - 1;
2595  }
2596  }
2597  }
2598  level++;
2599  }
2600 
2601  return std::make_pair(newit, true);
2602  }
2604  void insert(std::initializer_list<value_type> ilist)
2605  {
2606  for (const value_type& v: ilist)
2607  insert(v);
2608  }
2609  // insert new elements from iterators
2610  template<typename Iter>
2611  void insert(Iter first, Iter last)
2612  {
2613  for (Iter it = first; it != last; ++it)
2614  insert(*it);
2615  }
2617  iterator erase(const_iterator it)
2618  {
2619 
2620  if (nv.type == NODEV)
2621  {
2622  if (nv.size == 0)
2623  return it;
2624  nv.erase(it.index);
2625  return it;
2626  }
2627  K key = KeyOfVal::operator()(*it);
2628 
2629  const_iterator newit(it);
2630  if (it == end())
2631  return newit; // do nothing (if end or free space)
2632  if (!it.n0->erase(it.index))
2633  // not finished
2634  return newit;
2635 
2636  newit.index = newit.n0->lower_bound(key, *this, *this);
2637  if (newit.n0->size != 0 && newit.index == newit.n0->firstPos)
2638  // update key because will be removed and first will be greater than it
2639  key = KeyOfVal::operator()(*newit);
2640  if (it.n0 == &n0)
2641  {
2642  if (n0.size <= NodeVElemsNum)
2643  {
2644  // to NodeV
2645  Node0 tmpn0 = std::move(n0);
2646  n0.array = nullptr;
2647  nv.type = NODEV;
2648  nv.assignNode0(tmpn0);
2649  }
2650  return newit;
2651  }
2652 
2653  Node1* curn1 = it.n0->parent();
2654  if (it.n0->size < minNode0Size)
2655  {
2656  Node1* curn1 = it.n0->parent();
2657  const cxuint n0Index = it.n0->index;
2658  cxuint n0Left1 = n0Index > 0 ? curn1->array[n0Index-1].size : UINT_MAX;
2659  cxuint n0Right1 = n0Index+1 < curn1->size ? curn1->array[n0Index+1].size :
2660  UINT_MAX;
2661  cxuint mergedN0Index = UINT_MAX;
2662  if (n0Left1 < n0Right1)
2663  {
2664  if (n0Left1+minNode0Size-1 <= maxNode0Size)
2665  {
2666  curn1->array[n0Index-1].merge(*it.n0);
2667  curn1->eraseNode0(n0Index, *this, false);
2668  mergedN0Index = n0Index-1;
2669  newit.n0 = curn1->array + n0Index-1;
2670  newit.index = newit.n0->lower_bound(key, *this, *this);
2671  }
2672  }
2673  else if (n0Right1 != UINT_MAX)
2674  {
2675  if (n0Right1+minNode0Size-1 <= maxNode0Size)
2676  {
2677  it.n0->merge(curn1->array[n0Index+1]);
2678  curn1->eraseNode0(n0Index+1, *this, false);
2679  mergedN0Index = n0Index;
2680  newit.n0 = curn1->array + n0Index;
2681  newit.index = newit.n0->lower_bound(key, *this, *this);
2682  }
2683  }
2684  if (mergedN0Index == UINT_MAX)
2685  {
2686  // reorganization needed before inserting
2687  cxint left, right;
2688  bool removeNode0 = false;
2689  // reorganize in this level
2690  findReorgBounds0(n0Index, curn1, curn1->array[n0Index].size,
2691  left, right, &removeNode0);
2692  curn1->reorganizeNode0s(left, right+1, removeNode0);
2693  // find newit for inserted value
2694  newit.n0 = curn1->array + curn1->upperBoundN(key, *this, *this) - 1;
2695  newit.index = newit.n0->lower_bound(key, *this, *this);
2696  }
2697  }
2698  if (newit.index == newit.n0->capacity)
2699  {
2700  newit.toNextNode0();
2701  if (newit != end())
2702  key = KeyOfVal::operator()(newit.n0->array[newit.n0->firstPos]);
2703  }
2704 
2705  cxuint level = 1;
2706  Node1* prevn1 = nullptr;
2707  const Node1* newItN1 = newit.n0->parent();
2708  while (curn1 != nullptr)
2709  {
2710  curn1->totalSize--;
2711  prevn1 = curn1;
2712  curn1 = prevn1->parent();
2713  prevn1->first = prevn1->NodeBase::type==NODE1 ?
2714  KeyOfVal::operator()(
2715  prevn1->array[0].array[prevn1->array[0].firstPos]) :
2716  prevn1->array1[0].first;
2717 
2718  cxuint maxN1Size = maxTotalSize(level);
2719  cxuint minN1Size = minTotalSize(level);
2720  if (curn1 == nullptr)
2721  {
2722  if (prevn1->size == 1)
2723  {
2724  // remove old root
2725  if (prevn1->type == NODE1)
2726  {
2727  Node0 tempN0 = std::move(prevn1->array[0]);
2728  n1.~Node1();
2729  n0.array = nullptr;
2730  n0 = std::move(tempN0);
2731  n0.index = 255;
2732  newit.n0 = &n0;
2733  }
2734  else
2735  {
2736  Node1 tempN1 = std::move(prevn1->array1[0]);
2737  n1.~Node1();
2738  n1.array = nullptr;
2739  n1 = std::move(tempN1);
2740  n1.index = 255;
2741  }
2742  }
2743  break;
2744  }
2745 
2746  const cxuint n1Index = prevn1->index;
2747  size_t n1Left1 = n1Index > 0 ? curn1->array1[n1Index-1].totalSize : SIZE_MAX;
2748  size_t n1Right1 = n1Index+1 < curn1->size ?
2749  curn1->array1[n1Index+1].totalSize : SIZE_MAX;
2750 
2751  if (prevn1->totalSize >= minN1Size && prevn1->size > 1)
2752  {
2753  level++;
2754  continue;
2755  }
2756 
2757  // check number of total children after merging
2758  if (n1Left1!=SIZE_MAX &&
2759  prevn1->size + curn1->array1[n1Index-1].size > maxNode1Size)
2760  n1Left1 = SIZE_MAX;
2761  if (n1Right1!=SIZE_MAX &&
2762  prevn1->size + curn1->array1[n1Index+1].size > maxNode1Size)
2763  n1Right1 = SIZE_MAX;
2764 
2765  cxuint mergedN1Index = UINT_MAX;
2766  if (n1Left1 < n1Right1 && n1Left1 != SIZE_MAX)
2767  {
2768  if (n1Left1+minN1Size-1 <= maxN1Size)
2769  {
2770  curn1->array1[n1Index-1].merge(std::move(*prevn1));
2771  curn1->eraseNode1(n1Index, false);
2772  mergedN1Index = n1Index-1;
2773  if (level == 1 && newItN1 == prevn1)
2774  newit.n0 = curn1->array1[n1Index-1].array +
2775  curn1->array1[n1Index-1].upperBoundN(key, *this, *this) - 1;
2776  }
2777  }
2778  else if (n1Right1 != SIZE_MAX)
2779  {
2780  if (n1Right1+minN1Size-1 <= maxN1Size)
2781  {
2782  prevn1->merge(std::move(curn1->array1[n1Index+1]));
2783  curn1->eraseNode1(n1Index+1, false);
2784  mergedN1Index = n1Index;
2785  if (level == 1 && newItN1 == prevn1)
2786  newit.n0 = curn1->array1[n1Index].array +
2787  curn1->array1[n1Index].upperBoundN(key, *this, *this) - 1;
2788  }
2789  }
2790  if (mergedN1Index == UINT_MAX)
2791  {
2792  // reorganization needed before inserting
2793  cxint left, right;
2794  bool removeNode1 = false;
2795  // reorganize in this level
2796  findReorgBounds1(prevn1, curn1, prevn1->totalSize, maxN1Size,
2797  left, right, &removeNode1);
2798  curn1->reorganizeNode1s(left, right+1, *this, removeNode1);
2799  if (level == 1 && newItN1 == prevn1)
2800  {
2801  const Node1* pn1 = curn1->array1 +
2802  curn1->upperBoundN(key, *this, *this) - 1;
2803  newit.n0 = pn1->array + pn1->upperBoundN(key, *this, *this) - 1;
2804  }
2805  }
2806  level++;
2807  }
2808  return newit;
2809  }
2811  size_t erase(const key_type& key)
2812  {
2813  iterator it = find(key);
2814  if (it == end())
2815  return 0;
2816  erase(it);
2817  return 1;
2818  }
2819 
2821  void replace(iterator iter, const value_type& value)
2822  {
2823  if (iter == end())
2824  return;
2825  if (iter != begin())
2826  {
2827  iterator prevIt = iter;
2828  --prevIt;
2829  if (*prevIt >= value)
2830  throw std::out_of_range("Value out of range");
2831  }
2832  iterator nextIt = iter;
2833  ++nextIt;
2834  if (nextIt != end() && value >= *nextIt)
2835  throw std::out_of_range("Value out of range");
2836 
2837  if (iter.n0->type == NODE0)
2838  {
2839  Node0* n0 = iter.n0;
2840  n0->array[iter.index] = value;
2841  // fill up surrounding freespace for correct order
2842  for (cxint i = iter.index-1; i >= 0 && (n0->bitMask & (1ULL<<i)) != 0; i--)
2843  n0->array[i] = value;
2844  for (cxint i = iter.index+1; i < n0->capacity &&
2845  (n0->bitMask & (1ULL<<i)) != 0; i++)
2846  n0->array[i] = value;
2847  }
2848  else if (iter.n0->type == NODEV)
2849  nv.array[iter.index] = value;
2850  }
2851 
2853  bool operator==(const DTree& dt) const
2854  { return size()==dt.size() && std::equal(begin(), end(), dt.begin()); }
2856  bool operator!=(const DTree& dt) const
2857  { return size()!=dt.size() || !std::equal(begin(), end(), dt.begin()); }
2859  bool operator<(const DTree& dt) const
2860  { return std::lexicographical_compare(begin(), end(), dt.begin(), dt.end()); }
2862  bool operator<=(const DTree& dt) const
2863  { return !(dt < *this); }
2865  bool operator>(const DTree& dt) const
2866  { return (dt < *this); }
2868  bool operator>=(const DTree& dt) const
2869  { return !(*this < dt); }
2870 };
2871 
2872 
2874 template<typename T, typename Comp = std::less<T> >
2875 class DTreeSet: public DTree<T, T, Comp, Identity<T> >
2876 {
2877 private:
2879 public:
2880  typedef typename Impl::const_iterator const_iterator;
2881  typedef typename Impl::iterator iterator;
2882  typedef typename Impl::value_type value_type;
2883  typedef typename Impl::key_type key_type;
2884 
2886  DTreeSet(const Comp& comp = Comp()) : Impl(comp)
2887  { }
2888 #ifdef DTREE_TESTING
2889  DTreeSet(const typename Impl::Node0& node0, const Comp& comp = Comp())
2890  : Impl(node0, comp)
2891  { }
2892  DTreeSet(const typename Impl::Node1& node1, const Comp& comp = Comp())
2893  : Impl(node1, comp)
2894  { }
2895 #endif
2896  template<typename Iter>
2898  DTreeSet(Iter first, Iter last, const Comp& comp = Comp()) :
2899  Impl(first, last, comp)
2900  { }
2902  DTreeSet(std::initializer_list<value_type> init, const Comp& comp = Comp())
2903  : Impl(init, comp)
2904  { }
2905 };
2906 
2908 template<typename K, typename V, typename Comp = std::less<K> >
2909 class DTreeMap: public DTree<K, std::pair<const K, V>, Comp, SelectFirst<K, V>,
2910  std::pair<K, V> >
2911 {
2912 private:
2914  std::pair<K, V> > Impl;
2915 public:
2916  typedef typename Impl::const_iterator const_iterator;
2917  typedef typename Impl::iterator iterator;
2918  typedef typename Impl::value_type value_type;
2919  typedef typename Impl::key_type key_type;
2920  typedef V mapped_type;
2921 
2923  DTreeMap(const Comp& comp = Comp()) : Impl(comp)
2924  { }
2926  template<typename Iter>
2927  DTreeMap(Iter first, Iter last, const Comp& comp = Comp()) :
2928  Impl(first, last, comp)
2929  { }
2931  DTreeMap(std::initializer_list<value_type> init, const Comp& comp = Comp())
2932  : Impl(init, comp)
2933  { }
2934 
2936  void replace(iterator iter, const value_type& value)
2937  {
2938  if (iter == Impl::end())
2939  return;
2940  if (iter != Impl::begin())
2941  {
2942  iterator prevIt = iter;
2943  --prevIt;
2944  if (prevIt->first >= value.first)
2945  throw std::out_of_range("Key out of range");
2946  }
2947  iterator nextIt = iter;
2948  ++nextIt;
2949  if (nextIt != Impl::end() && value.first >= nextIt->first)
2950  throw std::out_of_range("Key out of range");
2951  if (iter.n0->type == Impl::NODE0)
2952  {
2953  typename Impl::Node0* n0 = iter.n0;
2954  n0->array[iter.index].first = value.first;
2955  n0->array[iter.index].second = value.second;
2956  // fill up surrounding freespace for correct order
2957  for (cxint i = iter.index-1; i >= 0 && (n0->bitMask & (1ULL<<i)) != 0; i--)
2958  n0->array[i].first = value.first;
2959  for (cxint i = iter.index+1; i < n0->capacity &&
2960  (n0->bitMask & (1ULL<<i)) != 0; i++)
2961  n0->array[i].first = value.first;
2962  }
2963  else if (iter.n0->type == Impl::NODEV)
2964  {
2965  Impl::nv.array[iter.index].first = value.first;
2966  Impl::nv.array[iter.index].second = value.second;
2967  }
2968  }
2969 
2971  std::pair<iterator, bool> put(const value_type& value)
2972  {
2973  auto res = Impl::insert(value);
2974  if (!res.second)
2975  res.first->second = value.second;
2976  return res;
2977  }
2978 
2980  mapped_type& at(const key_type& key)
2981  {
2982  iterator it = Impl::find(key);
2983  if (it == Impl::end())
2984  throw std::out_of_range("DTreeMap key not found");
2985  return it->second;
2986  }
2988  const mapped_type& at(const key_type& key) const
2989  {
2990  const_iterator it = Impl::find(key);
2991  if (it == Impl::end())
2992  throw std::out_of_range("DTreeMap key not found");
2993  return it->second;
2994  }
2996  mapped_type& operator[](const key_type& key)
2997  {
2998  iterator it = Impl::insert(std::pair<const K, V>(key, V())).first;
2999  return it->second;
3000  }
3001 };
3002 
3003 };
3004 
3005 #endif
iterator end()
return iterator after last element
Definition: DTree.h:2361
bool operator<=(const DTree &dt) const
lexicograhical less or equal
Definition: DTree.h:2862
bool operator!=(const DTree &dt) const
lexicograhical not equal
Definition: DTree.h:2856
const T * operator->() const
get element
Definition: DTree.h:2062
main D-Tree container of the unique ordered elements (D-Tree is kind of the B-Tree) ...
Definition: DTree.h:75
Node1 * parent()
get parent node
Definition: DTree.h:226
~DTree()
destructor
Definition: DTree.h:2155
const_iterator find(const key_type &key) const
find element or return end iterator
Definition: DTree.h:2326
bool operator==(const IterBase &it) const
equal to
Definition: DTree.h:1975
void next()
go to next element
Definition: DTree.h:1592
cxbyte size
number of the nodes
Definition: DTree.h:603
iterator lower_bound(const key_type &key)
first element that not less than key
Definition: DTree.h:2383
DTreeMap(Iter first, Iter last, const Comp &comp=Comp())
constructor iterator ranges
Definition: DTree.h:2927
Node1(Node0 &&n0, Node0 &&n1, const KeyOfVal &kofval)
create from two Node0&#39;s
Definition: DTree.h:692
DTreeSet(Iter first, Iter last, const Comp &comp=Comp())
constructor iterator ranges
Definition: DTree.h:2898
DTree(const Comp &comp=Comp(), const KeyOfVal &kofval=KeyOfVal())
default constructor
Definition: DTree.h:2093
Node1 - main node that holds Node0&#39;s or Node1&#39;s.
Definition: DTree.h:600
DTree(DTree &&dt) noexcept
move constructor
Definition: DTree.h:2139
ConstIter & operator++()
pre-increment
Definition: DTree.h:1999
static void organizeArray(AT &toFill, cxuint &i, cxuint size, const AT *array, uint64_t inBitMask, cxuint &k, cxuint newSize, AT *out, uint64_t &outBitMask, cxuint &factor, cxuint finc)
internal routine to organize array with empty holes
Definition: DTree.h:283
bool erase(const K &k, const Comp &comp, const KeyOfVal &kofval)
erase element of value v
Definition: DTree.h:590
cxuint lowerBoundN(const K &v, const Comp &comp, const KeyOfVal &kofval) const
find node that hold first element not less than value
Definition: DTree.h:904
bool operator==(const DTree &dt) const
lexicograhical equal to
Definition: DTree.h:2853
Iter operator--(int)
post-decrement
Definition: DTree.h:1938
const Node1 * parent() const
get parent node
Definition: DTree.h:789
DTree & operator=(DTree &&dt) noexcept
move assignment
Definition: DTree.h:2188
Iter & operator--()
pre-decrement
Definition: DTree.h:1932
DTree set.
Definition: DTree.h:2875
const_iterator lower_bound(const key_type &key) const
first element that not less than key
Definition: DTree.h:2386
void insert(std::initializer_list< value_type > ilist)
insert new elements from initializer list
Definition: DTree.h:2604
void step(ssize_t i)
go to i element from current position
Definition: DTree.h:1789
Iter(Node0 *n0=nullptr, cxuint index=0)
constructor
Definition: DTree.h:1899
T * operator->() const
get element
Definition: DTree.h:1968
const_iterator begin() const
return iterator to first element
Definition: DTree.h:2358
DTree & operator=(std::initializer_list< value_type > init)
assignment of initilizer list
Definition: DTree.h:2212
Node1 that holds Node0&#39;s.
Definition: DTree.h:82
const_iterator upper_bound(const key_type &key) const
first element that greater than key
Definition: DTree.h:2392
ConstIter(const Node0 *n0=nullptr, cxuint index=0)
constructor
Definition: DTree.h:1992
void split(Node0 &node2)
split this node and store in this node and node2
Definition: DTree.h:404
Node1 * parent()
get parent node
Definition: DTree.h:794
void prev(size_t inc)
go to inc previous element
Definition: DTree.h:1611
Configuration header.
ConstIter operator--(int)
post-decrement
Definition: DTree.h:2031
iterator which allow to modify underlying element
Definition: DTree.h:1890
Node0 & operator=(Node0 &&node) noexcept
moving assigment
Definition: DTree.h:206
DTreeMap(std::initializer_list< value_type > init, const Comp &comp=Comp())
constructor with element ranges
Definition: DTree.h:2931
cxuint CTZ64(uint64_t v)
counts trailing zeroes for 64-bit unsigned integer. For zero behavior is undefined ...
Definition: Utilities.h:422
bool operator==(const IterBase &it) const
equal to
Definition: DTree.h:2069
size_t erase(const key_type &key)
remove element by key
Definition: DTree.h:2811
Iter & operator+=(ssize_t i)
add to iterator with assignment
Definition: DTree.h:1926
bool empty() const
return true if empty
Definition: DTree.h:2216
Definition: DTree.h:132
DTree(Iter first, Iter last, const Comp &comp=Comp(), const KeyOfVal &kofval=KeyOfVal())
constructor with range assignment
Definition: DTree.h:2108
void reserve1(cxuint newCapacity)
reserve1 elements in Node0&#39;s array
Definition: DTree.h:874
void insertNode1(Node1 &&node, cxuint index, bool updateTotSize=true)
insert Node1 - (move to this node)
Definition: DTree.h:1013
cxuint upper_bound(const K &k, const Comp &comp, const KeyOfVal &kofval) const
get upper_bound (first index of element greater than value)
Definition: DTree.h:260
bool operator<(const DTree &dt) const
lexicograhical less
Definition: DTree.h:2859
DTree(const DTree &dt)
copy construcror
Definition: DTree.h:2123
cxuint lower_bound(const K &k, const Comp &comp, const KeyOfVal &kofval) const
get lower_bound (first index of element not less than value)
Definition: DTree.h:248
void copyArray(const Node1 &node)
Definition: DTree.h:639
bool operator!=(const IterBase &it) const
not equal
Definition: DTree.h:1978
std::pair< iterator, bool > insert(const value_type &value)
insert new element
Definition: DTree.h:2463
void allocate0(cxuint newCapacity)
Definition: DTree.h:798
DTreeSet(const Comp &comp=Comp())
default constructor
Definition: DTree.h:2886
ConstIter operator++(int)
post-increment
Definition: DTree.h:2005
iterator upper_bound(const key_type &key)
first element that greater than key
Definition: DTree.h:2389
Definition: DTree.h:148
unsigned char cxbyte
unsigned byte
Definition: Config.h:229
const_iterator end() const
return iterator after last element
Definition: DTree.h:2368
std::pair< iterator, bool > put(const value_type &value)
put element, insert or replace if found
Definition: DTree.h:2971
ssize_t diff(const IterBase &k2) const
calculate distance between iterators
Definition: DTree.h:1798
iterator find(const key_type &key)
find element or return end iterator
Definition: DTree.h:2323
main namespace
Definition: AsmDefs.h:38
Node1(Node1 &&n0, Node1 &&n1)
create from two Node1&#39;s
Definition: DTree.h:708
DTree map.
Definition: DTree.h:2909
size_t size() const
return size
Definition: DTree.h:2220
bool operator>=(const DTree &dt) const
lexicograhical greater or equal
Definition: DTree.h:2868
DTreeMap(const Comp &comp=Comp())
default constructor
Definition: DTree.h:2923
unsigned int cxuint
unsigned int
Definition: Config.h:237
get element same as input
Definition: DTree.h:50
Node0 & operator=(const Node0 &node)
copying assignment
Definition: DTree.h:186
Node1 * array1
array hold Node0&#39;s
Definition: DTree.h:610
Select first element from pair.
Definition: DTree.h:40
cxuint lower_boundFree(const K &k, const Comp &comp, const KeyOfVal &kofval) const
get lower_bound (first index of element not less than value)
Definition: DTree.h:237
const mapped_type & at(const key_type &key) const
get reference to element pointed by key
Definition: DTree.h:2988
bool operator>(const DTree &dt) const
lexicograhical greater
Definition: DTree.h:2865
Iter & operator++()
pre-increment
Definition: DTree.h:1906
const_iterator cend() const
return iterator after last element
Definition: DTree.h:2375
Node1 that holds Node1&#39;s.
Definition: DTree.h:83
cxbyte index
index in array
Definition: DTree.h:602
void toNextNode0()
Definition: DTree.h:1537
void reserve0(cxuint newCapacity)
reserve0 elements in Node0&#39;s array
Definition: DTree.h:845
const_iterator cbegin() const
return iterator to first element
Definition: DTree.h:2344
ConstIter operator+(ssize_t i) const
add to iterator
Definition: DTree.h:2012
std::pair< cxuint, bool > insert(const T &v, const Comp &comp, const KeyOfVal &kofval)
insert element
Definition: DTree.h:506
cxuint find(const K &k, const Comp &comp, const KeyOfVal &kofval) const
get lower_bound (first index of element not less than value)
Definition: DTree.h:272
void prev()
go to previous element
Definition: DTree.h:1725
iterator erase(const_iterator it)
remove element in postion pointed by iterator
Definition: DTree.h:2617
ConstIter & operator--()
pre-decrement
Definition: DTree.h:2025
mapped_type & at(const key_type &key)
get reference to element pointed by key
Definition: DTree.h:2980
DTree & operator=(const DTree &dt)
copy assignment
Definition: DTree.h:2164
Definition: DTree.h:1292
void next(size_t inc)
go to inc next elements
Definition: DTree.h:1425
const T & operator*() const
get element
Definition: DTree.h:2055
DTreeSet(std::initializer_list< value_type > init, const Comp &comp=Comp())
constructor with element ranges
Definition: DTree.h:2902
bool erase(cxuint index)
erase element in index
Definition: DTree.h:573
iterator begin()
return iterator to first element
Definition: DTree.h:2330
void insertNode0(Node0 &&node, cxuint index, const KeyOfVal &kofval, bool updateTotSize=true)
insert Node0 - (move to this node)
Definition: DTree.h:989
utilities for other libraries and programs
main iterator class
Definition: DTree.h:1389
void merge(const Node0 &node2)
merge this node with node2
Definition: DTree.h:365
cxuint index
index in array
Definition: DTree.h:1398
Iter & operator-=(ssize_t i)
subtract from iterator with assignment
Definition: DTree.h:1952
size_t totalSize
total size in this node (count recursively)
Definition: DTree.h:605
void replace(iterator iter, const value_type &value)
replace element with checking range
Definition: DTree.h:2821
Iter operator-(ssize_t i) const
subtract from iterator
Definition: DTree.h:1945
const Node1 * parent() const
get parent node
Definition: DTree.h:221
ConstIter & operator-=(ssize_t i)
subtract from iterator with assignment
Definition: DTree.h:2045
Iter operator+(ssize_t i) const
add to iterator
Definition: DTree.h:1919
signed int cxint
signed int
Definition: Config.h:235
cxbyte capacity
capacity
Definition: DTree.h:604
iterator that allow only to read element
Definition: DTree.h:1983
DTree(std::initializer_list< value_type > init, const Comp &comp=Comp(), const KeyOfVal &kofval=KeyOfVal())
constructor with initializer list
Definition: DTree.h:2116
cxuint CLZ64(uint64_t v)
counts leading zeroes for 64-bit unsigned integer. For zero behavior is undefined ...
Definition: Utilities.h:378
void freeArray()
helper for freeing array
Definition: DTree.h:618
T & operator*() const
get element
Definition: DTree.h:1961
void resize(cxint extraSize)
simple resize
Definition: DTree.h:472
ConstIter operator-(ssize_t i) const
subtract from iterator
Definition: DTree.h:2038
mapped_type & operator[](const key_type &key)
get reference to element pointed by key (add if key doesn&#39;t exists)
Definition: DTree.h:2996
void clear()
clear (remove all elements)
Definition: DTree.h:2228
void eraseNode1(cxuint index, bool updateTotSize=true)
remove node1 with index from this node
Definition: DTree.h:1058
bool operator!=(const IterBase &it) const
not equal
Definition: DTree.h:2072
cxuint upperBoundN(const K &v, const Comp &comp, const KeyOfVal &kofval) const
find node that hold first element greater than value
Definition: DTree.h:948
void eraseNode0(cxuint index, const KeyOfVal &kofval, bool updateTotSize=true)
remove node0 with index from this node
Definition: DTree.h:1036
void allocate1(cxuint newCapacity)
Definition: DTree.h:821
void replace(iterator iter, const value_type &value)
replace element with checking range of the key
Definition: DTree.h:2936
ConstIter & operator+=(ssize_t i)
add to iterator with assignment
Definition: DTree.h:2019