chunkedseq
container library for large in-memory data sets
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ftree.hpp
Go to the documentation of this file.
1 
13 #include "fixedcapacity.hpp"
14 
15 #ifndef _PASL_DATA_FTREE_H_
16 #define _PASL_DATA_FTREE_H_
17 
18 namespace pasl {
19 namespace data {
20 namespace ftree {
21 
22 /***********************************************************************/
23 
24 template <
25  class Top_item_base, // use "foo" to obtain a sequence of "foo*" items
26  int Chunk_capacity,
27  class Cached_measure,
28  class Top_item_deleter = chunkedseq::Pointer_deleter, // provides: static void dealloc(foo* x)
29  class Top_item_copier = chunkedseq::Pointer_deep_copier, // provides: static void copy(foo* x)
30  template <
31  class Item,
32  int Capacity,
33  class Item_alloc
34  >
37 >
38 class ftree {
39 public:
40 
41  using cache_type = Cached_measure;
42  using measured_type = typename cache_type::measured_type;
43  using algebra_type = typename cache_type::algebra_type;
44  using measure_type = typename cache_type::measure_type;
45 
46  class digit;
47  class node;
48  class branch_node;
49 
50  class leaf_node;
51 
52  struct split_type {
56  };
57 
58  using node_p = node*;
60  using ftree_p = ftree*;
62 
63  using size_type = size_t;
65  using leaf_item_type = Top_item_base*;
66 
67  /*---------------------------------------------------------------------*/
68  /* 2-3 tree node */
69 
70  class node {
71  private:
72 
73  // note: uninitialized_tag is only needed for debug mode
74  typedef enum {
75  leaf_node_tag,
76  branch_node_tag,
77  uninitialized_tag
78  } tag_t;
79 
80  tag_t tag;
81 
82  protected:
83 
84  node()
85  : tag(uninitialized_tag) { }
86 
87  node(tag_t _tag)
88  : tag(_tag) { }
89 
90  node(const node& other)
91  : tag(other.tag) { }
92 
93  virtual ~node() { }
94 
95  bool is_leaf() const {
96  return tag == leaf_node_tag;
97  }
98 
99  bool is_branch() const {
100  return tag == branch_node_tag;
101  }
102 
103  void set_tag(tag_t _tag) {
104  assert(tag == uninitialized_tag);
105  tag = _tag;
106  }
107 
108  void make_leaf() {
109  set_tag(leaf_node_tag);
110  }
111 
112  void make_branch() {
113  set_tag(branch_node_tag);
114  }
115 
116  virtual measured_type get_cached() const = 0;
117 
118  template <class Pred>
119  static const leaf_node_type* down(const node* t,
120  const Pred& p,
121  measured_type& prefix);
122 
123  virtual void clear() = 0;
124 
125  friend class ftree;
126  };
127 
128  /*---------------------------------------------------------------------*/
129  /* Leaf */
130 
131 public:
132 
133  class leaf_node : public node {
134  private:
135 
136  typedef leaf_node* leaf_node_p;
137 
138  static leaf_node_p force(node_p t) {
139  assert(t != NULL);
140  assert(t->is_leaf());
141  return (leaf_node_p)t;
142  }
143 
144  static const leaf_node_type* cforce(const node* t) {
145  assert(t != NULL);
146  assert(t->is_leaf());
147  return (const leaf_node_type*)t;
148  }
149 
150  public:
151 
153 
154  leaf_node() : node() {
155  node::make_leaf();
156  }
157 
159  : node(), item(leaf) {
160  node::make_leaf();
161  }
162 
163  leaf_node(const leaf_node& other)
164  : node(other), item(other.item) { }
165 
167  measure_type meas_fct;
168  measured_type m = meas_fct(item);
169  return m;
170  }
171 
172  template <class Body>
173  void for_each(const Body& body) const {
174  body(item);
175  }
176 
177  void clear() {
178 
179  }
180 
181  friend class ftree;
182  };
183 
184  /*---------------------------------------------------------------------*/
185  /* Branch */
186 
187 public:
188 
189  class branch_node : public node {
190  private:
191 
192  typedef branch_node* branch_node_p;
193 
194  static const int max_nb_branches = 3;
195 
196  int nb; // number of branches (== 2 or 3)
197  node_p branches[max_nb_branches];
198  measured_type cached;
199 
200  static branch_node_p force(node_p t) {
201  assert(t->is_branch());
202  return (branch_node_p)t;
203  }
204 
205  static const branch_node* cforce(const node* t) {
206  assert(t->is_branch());
207  return (const branch_node*)t;
208  }
209 
210  void set_branch(int id, node_p t) {
211  branches[id] = t;
212  }
213 
214  void refresh_cache() {
215  cached = algebra_type::identity();
216  for (int i = 0; i < nb; i++)
217  cached = algebra_type::combine(cached, branches[i]->get_cached());
218  }
219 
220  public:
221 
223  : node(), nb(2) {
225  set_branch(0, t0);
226  set_branch(1, t1);
227  refresh_cache();
228  }
229 
231  : node(), nb(3) {
233  set_branch(0, t0);
234  set_branch(1, t1);
235  set_branch(2, t2);
236  refresh_cache();
237  }
238 
239  branch_node(const branch_node& other)
240  : node(other), nb(other.nb) {
241  for (int i = 0; i < other.nb_branches(); i++)
242  set_branch(i, make_deep_copy_tree(other.branches[i]));
243  refresh_cache();
244  }
245 
246  int nb_branches() const {
247  return nb;
248  }
249 
250  node_p get_branch(int i) const {
251  return branches[i];
252  }
253 
255  return cached;
256  }
257 
258  void clear() {
259  for (int i = 0; i < nb; i++)
260  delete branches[i];
261  }
262 
263  template <class Body>
264  void for_each(const Body& body) const {
265  for (int i = 0; i < nb; i++)
266  node_for_each(body, branches[i]);
267  }
268 
269  friend class ftree;
270  };
271 
273  node* new_node;
274  if (n->is_leaf()) {
275  leaf_node_type* new_leaf = new leaf_node(*leaf_node::force(n));
276  new_node = new_leaf;
277  } else {
278  new_node = new branch_node(*branch_node::force(n));
279  }
280  return new_node;
281  }
282 
283  template <class Body>
284  static void node_for_each(const Body& body, const node* n) {
285  if (n->is_leaf()) {
286  const leaf_node_type* l = leaf_node::cforce(n);
287  l->for_each(body);
288  } else {
289  const branch_node* b = branch_node::cforce(n);
290  b->for_each(body);
291  }
292  }
293 
294  /*---------------------------------------------------------------------*/
295  /* Digit */
296 
297  class digit {
298  private:
299 
300  typedef node* node_p;
301  typedef branch_node* branch_node_p;
302  typedef leaf_node* leaf_node_p;
303  typedef digit* digit_p;
304  static const int max_nb_digits = 4;
306 
307  buffer_type d;
308 
309  public:
310 
311  digit() { }
312 
313  size_type size() const {
314  return d.size();
315  }
316 
317  bool empty() const {
318  return d.empty();
319  }
320 
321  node_p back() const {
322  return d.back();
323  }
324 
325  node_p front() const {
326  return d.front();
327  }
328 
329  void push_back(node_p x) {
330  d.push_back(x);
331  }
332 
333  void push_front(node_p x) {
334  d.push_front(x);
335  }
336 
337  void pop_back() {
338  d.pop_back();
339  }
340 
341  void pop_front() {
342  d.pop_front();
343  }
344 
345  void pop_front(int nb) {
346  for (int i = 0; i < nb; i++)
347  pop_front();
348  }
349 
350  void pop_back(int nb) {
351  for (int i = 0; i < nb; i++)
352  pop_back();
353  }
354 
355  node_p operator[](size_type ix) const {
356  assert(ix >= 0 && ix < d.size());
357  return d[ix];
358  }
359 
360  void clear() {
361  size_type sz = size();
362  for (size_type i = 0; i < sz; i++) {
363  d[i]->clear();
364  delete d[i];
365  }
366  d.clear();
367  }
368 
369  bool is_one() const {
370  return size() == 1;
371  }
372 
373  bool is_four() const {
374  return size() == 4;
375  }
376 
377  void make_deep_copy(digit& dst) const {
378  for (size_type i = 0; i < size(); i++)
379  dst.push_back(make_deep_copy_tree(d[i]));
380  }
381 
382  /*
383  * Assigns new contents to the digit container,
384  * replacing current items with those of the
385  * branches of the given tree
386  */
387  void assign(branch_node_p x) {
388  clear();
389  for (int i = 0; i < x->nb_branches(); i++)
390  push_back(x->get_branch(i));
391  }
392 
393  branch_node_p front_three() const {
394  assert(is_four());
395  return new branch_node(d[0], d[1], d[2]);
396  }
397 
398  branch_node_p back_three() const {
399  assert(is_four());
400  return new branch_node(d[1], d[2], d[3]);
401  }
402 
403  /*
404  * Returns the index of the first tree t in d
405  * for which p(t.cached+i) holds
406  */
407  template <typename Pred>
408  size_type find(const Pred& p, measured_type i) const {
409  size_type ix;
410  measured_type j = algebra_type::identity();
411  j = algebra_type::combine(j, i);
412  for (ix = 0; ix < size(); ix++) {
413  j = algebra_type::combine(j, d[ix]->get_cached());
414  if (p(j))
415  break;
416  }
417  return ix;
418  }
419 
420  static digit concat3(digit d1, digit d2, digit d3) {
421  static constexpr int max_concat_nb_digits = max_nb_digits*3;
423  tmp_buffer_type tmp;
424  digit digits[3] = {d1, d2, d3};
425  for (int k = 0; k < 3; k++) {
426  digit d = digits[k];
427  for (size_type i = 0; i < d.size(); i++)
428  tmp.push_back(d[i]);
429  }
430  digit res;
431  size_type sz = tmp.size();
432  for (size_type i = 0; i < sz; ) {
433  size_type m = sz - i;
434  if (m == 2) {
435  res.push_back(new branch_node(tmp[i], tmp[i+1]));
436  } else if (m == 3) {
437  res.push_back(new branch_node(tmp[i], tmp[i+1], tmp[i+2]));
438  } else if (m == 4) {
439  res.push_back(new branch_node(tmp[i], tmp[i+1]));
440  res.push_back(new branch_node(tmp[i+2], tmp[i+3]));
441  } else {
442  res.push_back(new branch_node(tmp[i], tmp[i+1], tmp[i+2]));
443  m = 3;
444  }
445  i += m;
446  }
447  return res;
448  }
449 
451  measured_type cached = algebra_type::identity();
452  for (size_type i = 0; i < size(); i++)
453  cached = algebra_type::combine(cached, d[i]->get_cached());
454  return cached;
455  }
456 
457  template <class Pred>
458  static const node* down(const Pred& p, const digit* d, measured_type& prefix) {
459  measured_type v = prefix;
460  node_p n = nullptr;
461  for (size_type i = 0; i < d->size(); i++) {
462  n = (*d)[i];
463  v = algebra_type::combine(v, n->get_cached());
464  if (p(v))
465  return n;
466  prefix = v;
467  }
468  return n;
469  }
470 
471  template <class Body>
472  void for_each(const Body& body) const {
473  for (int i = 0; i < size(); i++)
474  node_for_each(body, d[i]);
475  }
476 
477  void swap(digit& other) {
478  d.swap(other.d);
479  }
480 
481  };
482 
483  /*---------------------------------------------------------------------*/
484  /* Finger tree */
485 
486 public:
487 
492 
493  bool single() const {
494  return fr.is_one() && bk.empty();
495  }
496 
497  bool deep() const {
498  return ! (empty() || single());
499  }
500 
501  void refresh_cache() {
502  cached = algebra_type::identity();
503  cached = algebra_type::combine(cached, fr.get_cached());
504  if (deep())
505  cached = algebra_type::combine(cached, middle->get_cached());
506  cached = algebra_type::combine(cached, bk.get_cached());
507  }
508 
509  void initialize() {
510  refresh_cache();
511  }
512 
514  ftree_p m = middle;
515  middle = NULL;
516  return m;
517  }
518 
519  void make_deep_copy(const ftree& other) {
520  other.fr.make_deep_copy(fr);
521  middle = NULL;
522  if (other.deep())
523  middle = new ftree(*other.middle);
524  other.bk.make_deep_copy(bk);
525  initialize();
526  }
527 
528  ftree(digit fr, ftree_p middle, digit bk)
529  : fr(fr), middle(middle), bk(bk) {
530  initialize();
531  }
532 
534  size_type sz = d.size();
535  if (sz == 0) {
536  ;
537  } else if (sz == 1) {
538  fr.push_front(d[0]);
539  } else if (sz == 2) {
540  fr.push_front(d[0]);
541  bk.push_back(d[1]);
542  } else if (sz == 3) {
543  fr.push_front(d[1]);
544  fr.push_front(d[0]);
545  bk.push_back(d[2]);
546  } else {
547  assert(sz == 4);
548  fr.push_front(d[2]);
549  fr.push_front(d[1]);
550  fr.push_front(d[0]);
551  bk.push_back(d[3]);
552  }
553  if (sz > 1)
554  middle = new ftree();
555  else
556  middle = NULL;
557  initialize();
558  }
559 
560  bool empty() const {
561  return fr.empty();
562  }
563 
564  node_p _back() const {
565  assert(! empty());
566  if (single())
567  return fr.front();
568  return bk.back();
569  }
570 
571  node_p _front() const {
572  assert(! empty());
573  return fr.front();
574  }
575 
576  void _push_back(node_p x) {
577  if (empty()) {
578  fr.push_front(x);
579  } else if (single()) {
580  middle = new ftree();
581  bk.push_back(x);
582  } else {
583  if (bk.is_four()) {
584  branch_node_p y = bk.front_three();
585  bk.pop_front(3);
586  bk.push_back(x);
587  middle->_push_back(y);
588  } else {
589  bk.push_back(x);
590  }
591  }
592  cached = algebra_type::combine(cached, x->get_cached());
593  }
594 
595  void _push_front(node_p x) {
596  if (empty()) {
597  fr.push_front(x);
598  cached = algebra_type::combine(cached, x->get_cached());
599  return;
600  } else if (single()) {
601  middle = new ftree();
602  bk.push_back(fr.front());
603  fr.pop_front();
604  fr.push_front(x);
605  } else {
606  if (fr.is_four()) {
607  branch_node_p y = fr.back_three();
608  fr.pop_back(3);
609  fr.push_front(x);
610  middle->_push_front(y);
611  } else {
612  fr.push_front(x);
613  }
614  }
615  cached = algebra_type::combine(x->get_cached(), cached);
616  }
617 
618  void _pop_back() {
619  assert(! empty());
620  if (algebra_type::has_inverse)
621  cached = algebra_type::combine(cached, algebra_type::inverse(_back()->get_cached()));
622  if (single()) {
623  fr.pop_front();
624  assert(empty());
625  } else { // deep
626  bk.pop_back();
627  if (bk.empty()) {
628  if (middle->empty()) {
629  if (fr.is_one()) {
630  delete middle;
631  } else {
632  node_p x = fr.back();
633  fr.pop_back();
634  bk.push_back(x);
635  }
636  } else {
637  branch_node_p x = branch_node::force(middle->_back());
638  middle->_pop_back();
639  bk.assign(x);
640  delete x;
641  }
642  }
643  }
644  if (! algebra_type::has_inverse)
645  refresh_cache();
646  }
647 
648  void _pop_front() {
649  assert(! empty());
650  if (algebra_type::has_inverse)
651  cached = algebra_type::combine(algebra_type::inverse(_front()->get_cached()), cached);
652  if (single()) {
653  fr.pop_front();
654  assert(empty());
655  } else { // deep
656  fr.pop_front();
657  if (fr.empty()) {
658  if (middle->empty()) {
659  fr.push_front(bk.front());
660  bk.pop_front();
661  if (bk.empty())
662  delete middle;
663  } else {
664  branch_node_p x = branch_node::force(middle->_front());
665  middle->_pop_front();
666  fr.assign(x);
667  delete x;
668  }
669  }
670  }
671  if (! algebra_type::has_inverse)
672  refresh_cache();
673  }
674 
675  void _push_back(digit d) {
676  for (size_type i = 0; i < d.size(); i++)
677  _push_back(d[i]);
678  }
679 
680  void _push_front(digit d) {
681  for (int i = (int)d.size() - 1; i >= 0; i--)
682  _push_front(d[i]);
683  }
684 
685  static ftree_p app3(ftree_p fr, digit m, ftree_p bk) {
686  ftree_p r;
687  if (fr->empty()) {
688  r = bk;
689  r->_push_front(m);
690  delete fr;
691  } else if (bk->empty()) {
692  r = fr;
693  r->_push_back(m);
694  delete bk;
695  } else if (fr->single()) {
696  r = bk;
697  node_p x = fr->_back();
698  r->_push_front(m);
699  r->_push_front(x);
700  delete fr;
701  } else if (bk->single()) {
702  r = fr;
703  node_p x = bk->_back();
704  r->_push_back(m);
705  r->_push_back(x);
706  delete bk;
707  } else {
708  digit m2 = digit::concat3(fr->bk, m, bk->fr);
709  ftree_p n = app3(fr->take_middle(), m2, bk->take_middle());
710  r = new ftree(fr->fr, n, bk->bk);
711  delete fr;
712  delete bk;
713  }
714  return r;
715  }
716 
717  bool is_front(const digit* d) const {
718  return d == &fr;
719  }
720 
721  bool is_back(const digit* d) const {
722  return d == &bk;
723  }
724 
725  typedef struct {
729  } split_rec_type;
730 
731  template <typename Pred>
732  static split_rec_type split_rec(const Pred& p, measured_type i, ftree_p f) {
733  assert(! f->empty());
734  split_rec_type v;
735  if (f->single()) {
736  v.fr = new ftree();
737  v.middle = f->_back();
738  v.bk = new ftree();
739  delete f;
740  } else { // deep
741  measured_type vfr = algebra_type::identity();
742  vfr = algebra_type::combine(vfr, i);
743  vfr = algebra_type::combine(vfr, f->fr.get_cached());
744  size_type sz;
745  size_type ix;
746  if (p(vfr)) {
747  ix = f->fr.find(p, i);
748  sz = f->fr.size();
749  v.fr = new ftree(f->fr);
750  v.middle = f->fr[ix];
751  v.bk = f;
752  } else {
753  measured_type vm = algebra_type::identity();
754  vm = algebra_type::combine(vm, vfr);
755  vm = algebra_type::combine(vm, f->middle->get_cached());
756  if (p(vm)) {
757  split_rec_type ms = split_rec(p, vfr, f->take_middle());
758  digit xs;
759  xs.assign(branch_node::force(ms.middle));
760  delete ms.middle;
761  measured_type tmp = algebra_type::identity();
762  tmp = algebra_type::combine(tmp, vfr);
763  tmp = algebra_type::combine(tmp, ms.fr->get_cached());
764  ix = xs.find(p, tmp);
765  sz = xs.size();
766  v.fr = new ftree(f->fr, ms.fr, xs);
767  v.middle = xs[ix];
768  v.bk = new ftree(xs, ms.bk, f->bk);
769  delete f;
770  } else {
771  ix = f->bk.find(p, vm);
772  sz = f->bk.size();
773  v.fr = f;
774  v.middle = f->bk[ix];
775  v.bk = new ftree(f->bk);
776  }
777  }
778  for (size_type i = 0; i < sz - ix; i++)
779  v.fr->_pop_back();
780  for (size_type i = 0; i < ix + 1; i++)
781  v.bk->_pop_front();
782  }
783  return v;
784  }
785 
786  template <class Pred>
787  static const digit* down(const ftree* ft, const Pred& p, measured_type& prefix) {
788  assert(! ft->empty());
789  if (ft->single())
790  return &(ft->fr);
791  assert(ft->deep());
792  measured_type v = prefix;
793  v = algebra_type::combine(v, ft->fr.get_cached());
794  if (p(v))
795  return &(ft->fr);
796  prefix = v;
797  v = algebra_type::combine(v, ft->middle->get_cached());
798  if (p(v))
799  return down(ft->middle, p, prefix);
800  prefix = v;
801  v = algebra_type::combine(v, ft->bk.get_cached());
802  if (p(v))
803  return &(ft->bk);
804  assert(ft->bk.size() > 0);
805  return &(ft->bk);
806  }
807 
809  return leaf_node::force(_back());
810  }
811 
813  return leaf_node::force(_front());
814  }
815 
816  template <class Body>
817  void _for_each(const Body& body) const {
818  if (empty())
819  return;
820  if (single()) {
821  fr.for_each(body);
822  return;
823  }
824  fr.for_each(body);
825  middle->_for_each(body);
826  bk.for_each(body);
827  }
828 
830  _push_back(x);
831  }
832 
834  _push_front(x);
835  }
836 
837  void ___pop_back() {
838  assert(_back()->is_leaf());
839  __back();
840  _pop_back();
841  }
842 
843  void ___pop_front() {
844  assert(_front()->is_leaf());
845  __front();
846  _pop_front();
847  }
848 
849  template <class Pred>
850  static const leaf_node* search_aux(const Pred& p, const ftree* start, measured_type& prefix) {
851  const digit* d = down(start, p, prefix);
852  const node* n = digit::down(p, d, prefix);
853  return leaf_node::down(n, p, prefix);
854  }
855 
856 
857  template <typename Pred>
858  static split_type split_aux(const Pred& p, measured_type prefix, ftree* f) {
859  split_rec_type s1 = split_rec(p, prefix, f);
860  leaf_node_p l = leaf_node::force(s1.middle);
861  split_type s2 = {s1.fr, l, s1.bk};
862  return s2;
863  }
864 
865  static ftree* concatenate(ftree* fr, ftree* bk) {
866  digit d;
867  return app3(fr, d, bk);
868  }
869 
870 public:
871 
872  /*---------------------------------------------------------------------*/
873 
875  : middle(NULL) {
876  initialize();
877  }
878 
879  ftree(const ftree& other) {
880  make_deep_copy(other);
881  }
882 
883  ~ftree() {
884  if (middle != NULL && deep())
885  delete middle;
886  }
887 
889  return cached;
890  }
891 
892 };
893 
894 template <
895 class Top_item_base,
896 int Chunk_capacity,
897 class Cached_measure,
898 class Top_item_deleter,
899 class Top_item_copier,
900 template<class Item, int Capacity, class Item_alloc> class Chunk_struct,
901 class Size_access
902 >
903 template <class Pred>
904 const typename ftree< Top_item_base,
905 Chunk_capacity,
906 Cached_measure,
907 Top_item_deleter,
908 Top_item_copier,
909 Chunk_struct,
910 Size_access>::leaf_node_type*
911 ftree< Top_item_base,
912 Chunk_capacity,
913 Cached_measure,
914 Top_item_deleter,
915 Top_item_copier,
916 Chunk_struct,
917 Size_access>::node::down(const node* t,
918  const Pred& p,
919  measured_type& prefix) {
920  if (t->is_leaf())
921  return ftree< Top_item_base,
922  Chunk_capacity,
923  Cached_measure,
924  Top_item_deleter,
925  Top_item_copier,
926  Chunk_struct,
927  Size_access>::leaf_node::cforce(t);
928  const branch_node* b = branch_node::cforce(t);
929  int nb = b->nb_branches();
930  for (int i = 0; i < nb; i++) {
931  node_p s = b->get_branch(i);
932  measured_type v = prefix;
933  v = algebra_type::combine(v, s->get_cached());
934  if (p(v))
935  return down(s, p, prefix);
936  prefix = v;
937  }
938  return down(b->get_branch(nb-1), p, prefix);
939 }
940 
941 /*---------------------------------------------------------------------*/
942 
943 template <
944  class Top_item_base, // use "foo" to obtain a sequence of "foo*" items
945  int Chunk_capacity,
946  class Cached_measure,
947  class Top_item_deleter = chunkedseq::Pointer_deleter, // provides: static void dealloc(foo* x)
948  class Top_item_copier = chunkedseq::Pointer_deep_copier, // provides: static void copy(foo* x)
949  template <
950  class Item,
951  int Capacity,
952  class Item_alloc
953  >
956 >
957 class tftree {
958 public:
959 
960  using ftree_type = ftree<Top_item_base, Chunk_capacity, Cached_measure,
961  Top_item_deleter, Top_item_copier, Chunk_struct,
962  Size_access>;
963 
970 
972 
973  tftree() {
974  ft = new ftree_type();
975  }
976 
977  tftree(const tftree& other) {
978  ft = new ftree_type(*(other.ft));
979  }
980 
982  delete ft;
983  }
984 
985  bool empty() const {
986  return ft->empty();
987  }
988 
990  return ft->__back()->item;
991  }
992 
994  return back();
995  }
996 
998  return ft->__front()->item;
999  }
1000 
1001  template <class M>
1002  void push_back(M, leaf_item_type item) {
1003  ft->___push_back(new leaf_node(item));
1004  }
1005 
1006  template <class M>
1007  void push_front(M, leaf_item_type item) {
1008  ft->___push_front(new leaf_node(item));
1009  }
1010 
1011  template <class M>
1013  leaf_node_type* p = ft->__back();
1014  ft->___pop_back();
1015  leaf_item_type item = p->item;
1016  delete p;
1017  return item;
1018  }
1019 
1020  template <class M>
1022  leaf_node_type* p = ft->__front();
1023  ft->___pop_front();
1024  leaf_item_type item = p->item;
1025  delete p;
1026  return item;
1027  }
1028 
1030  return ft->get_cached();
1031  }
1032 
1033  template <class Body>
1034  void for_each(const Body& body) const {
1035  auto _body = [&] (leaf_item_type item) {
1036  body(item);
1037  };
1038  ft->_for_each(_body);
1039  }
1040 
1041  void swap(tftree& other) {
1042  std::swap(ft, other.ft);
1043  }
1044 
1045  template <class Pred>
1047  const Top_item_base*& item) const {
1048  measured_type pr = prefix;
1049  const leaf_node* ptr = ft->search_aux(p, ft, pr);
1050  item = ptr->item;
1051  return pr;
1052  }
1053 
1054  template <class M, class Pred>
1055  measured_type split(M, const Pred& p, measured_type prefix,
1056  leaf_item_type& item, tftree& other) {
1057  if (empty())
1058  return prefix;
1059  measured_type pr = prefix;
1060  split_type r = ft->split_aux(p, pr, ft);
1061  ft = r.fr;
1062  delete other.ft;
1063  other.ft = r.bk;
1064  item = r.middle->item;
1065  delete r.middle;
1066  return algebra_type::combine(prefix, ft->get_cached());
1067  }
1068 
1069  template <class M>
1070  void concat(M, tftree& other) {
1071  ft = ft->concatenate(ft, other.ft);
1072  other.ft = new ftree_type();
1073  }
1074 
1075 };
1076 
1077 /***********************************************************************/
1078 
1079 } // end namespace
1080 } // end namespace
1081 } // end namespace
1082 
1083 #endif
void _push_front(digit d)
Definition: ftree.hpp:680
measured_type cached
Definition: ftree.hpp:488
void make_deep_copy(const ftree &other)
Definition: ftree.hpp:519
static digit concat3(digit d1, digit d2, digit d3)
Definition: ftree.hpp:420
measured_type search_for_chunk(const Pred &p, measured_type prefix, const Top_item_base *&item) const
Definition: ftree.hpp:1046
typename cache_type::algebra_type algebra_type
Definition: ftree.hpp:43
leaf_node_type * __back() const
Definition: ftree.hpp:808
typename ftree_type::algebra_type algebra_type
Definition: ftree.hpp:969
measured_type split(M, const Pred &p, measured_type prefix, leaf_item_type &item, tftree &other)
Definition: ftree.hpp:1055
void for_each(const Body &body) const
Definition: ftree.hpp:472
virtual measured_type get_cached() const =0
ftree< Top_item_base, Chunk_capacity, Cached_measure, Top_item_deleter, Top_item_copier, Chunk_struct, Size_access > ftree_type
Definition: ftree.hpp:962
Cached_measure cache_type
Definition: ftree.hpp:41
bool empty() const
Definition: ftree.hpp:560
ftree(const ftree &other)
Definition: ftree.hpp:879
measured_type get_cached() const
Definition: ftree.hpp:450
node_p _front() const
Definition: ftree.hpp:571
void swap(tftree &other)
Definition: ftree.hpp:1041
void swap(digit &other)
Definition: ftree.hpp:477
base::ringbuffer_ptr< base::heap_allocator< Item, Capacity+1 >> ringbuffer_ptr
void _push_front(node_p x)
Definition: ftree.hpp:595
leaf_item_type pop_front(M)
Definition: ftree.hpp:1021
node_p operator[](size_type ix) const
Definition: ftree.hpp:355
branch_node_p back_three() const
Definition: ftree.hpp:398
void ___push_front(leaf_node_type *x)
Definition: ftree.hpp:833
leaf_item_type cback() const
Definition: ftree.hpp:993
node_p get_branch(int i) const
Definition: ftree.hpp:250
leaf_node(const leaf_item_type &leaf)
Definition: ftree.hpp:158
static node * make_deep_copy_tree(node *n)
Definition: ftree.hpp:272
static const node * down(const Pred &p, const digit *d, measured_type &prefix)
Definition: ftree.hpp:458
leaf_item_type pop_back(M)
Definition: ftree.hpp:1012
leaf_node_type * __front() const
Definition: ftree.hpp:812
void assign(branch_node_p x)
Definition: ftree.hpp:387
size_type find(const Pred &p, measured_type i) const
Definition: ftree.hpp:408
leaf_node leaf_node_type
Definition: ftree.hpp:64
static const leaf_node * search_aux(const Pred &p, const ftree *start, measured_type &prefix)
Definition: ftree.hpp:850
void push_front(M, leaf_item_type item)
Definition: ftree.hpp:1007
tftree(const tftree &other)
Definition: ftree.hpp:977
static split_rec_type split_rec(const Pred &p, measured_type i, ftree_p f)
Definition: ftree.hpp:732
void _for_each(const Body &body) const
Definition: ftree.hpp:817
measured_type get_cached() const
Definition: ftree.hpp:166
branch_node(node_p t0, node_p t1, node_p t2)
Definition: ftree.hpp:230
void for_each(const Body &body) const
Definition: ftree.hpp:173
void for_each(const Body &body) const
Definition: ftree.hpp:264
branch_node_p front_three() const
Definition: ftree.hpp:393
bool deep() const
Definition: ftree.hpp:497
static ftree_p app3(ftree_p fr, digit m, ftree_p bk)
Definition: ftree.hpp:685
Definition: algebra.hpp:18
leaf_item_type back() const
Definition: ftree.hpp:989
Fixed capacity vectors.
node(const node &other)
Definition: ftree.hpp:90
leaf_node(const leaf_node &other)
Definition: ftree.hpp:163
typename cache_type::measure_type measure_type
Definition: ftree.hpp:44
ftree(digit fr, ftree_p middle, digit bk)
Definition: ftree.hpp:528
typename ftree_type::leaf_node leaf_node
Definition: ftree.hpp:968
static split_type split_aux(const Pred &p, measured_type prefix, ftree *f)
Definition: ftree.hpp:858
result_t res
Definition: bench.cpp:51
void _push_back(digit d)
Definition: ftree.hpp:675
static void node_for_each(const Body &body, const node *n)
Definition: ftree.hpp:284
size_type size() const
Definition: ftree.hpp:313
measured_type get_cached() const
Definition: ftree.hpp:888
typename ftree_type::measured_type measured_type
Definition: ftree.hpp:966
typename ftree_type::leaf_node_type leaf_node_type
Definition: ftree.hpp:965
void set_tag(tag_t _tag)
Definition: ftree.hpp:103
Top_item_base * leaf_item_type
Definition: ftree.hpp:65
node_p _back() const
Definition: ftree.hpp:564
bool is_front(const digit *d) const
Definition: ftree.hpp:717
typename ftree_type::split_type split_type
Definition: ftree.hpp:964
void push_back(M, leaf_item_type item)
Definition: ftree.hpp:1002
bool is_back(const digit *d) const
Definition: ftree.hpp:721
bool empty() const
Definition: ftree.hpp:985
leaf_item_type front() const
Definition: ftree.hpp:997
bool single() const
Definition: ftree.hpp:493
typename ftree_type::leaf_item_type leaf_item_type
Definition: ftree.hpp:967
void concat(M, tftree &other)
Definition: ftree.hpp:1070
void for_each(const Body &body) const
Definition: ftree.hpp:1034
typename cache_type::measured_type measured_type
Definition: ftree.hpp:42
branch_node(node_p t0, node_p t1)
Definition: ftree.hpp:222
static const leaf_node_type * down(const node *t, const Pred &p, measured_type &prefix)
void _push_back(node_p x)
Definition: ftree.hpp:576
void make_deep_copy(digit &dst) const
Definition: ftree.hpp:377
static ftree * concatenate(ftree *fr, ftree *bk)
Definition: ftree.hpp:865
static const digit * down(const ftree *ft, const Pred &p, measured_type &prefix)
Definition: ftree.hpp:787
void ___push_back(leaf_node_type *x)
Definition: ftree.hpp:829
measured_type get_cached() const
Definition: ftree.hpp:1029
measured_type get_cached() const
Definition: ftree.hpp:254
branch_node(const branch_node &other)
Definition: ftree.hpp:239
bytes_8 Item
Definition: do_fifo.cpp:107