chunkedseq
container library for large in-memory data sets
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
chunkedbag.hpp
Go to the documentation of this file.
1 
13 #include <cstddef>
14 #include <initializer_list>
15 
16 #include "fixedcapacity.hpp"
17 #include "chunk.hpp"
18 #include "cachedmeasure.hpp"
19 #include "bootchunkedseq.hpp"
20 #include "ftree.hpp"
21 #include "iterator.hpp"
22 #include "chunkedseqextras.hpp"
23 
24 #ifndef _PASL_DATA_CHUNKEDBAG_H_
25 #define _PASL_DATA_CHUNKEDBAG_H_
26 
27 namespace pasl {
28 namespace data {
29 namespace chunkedseq {
30 
31 /***********************************************************************/
32 
40 template <
41  class Configuration,
42  template <
43  class Chunkedseq,
44  class Configuration1
45  >
46  class Iterator=iterator::random_access
47 >
49 protected:
50 
51  using chunk_type = typename Configuration::chunk_type;
52  using chunk_search_type = typename Configuration::chunk_search_type;
53  using chunk_cache_type = typename Configuration::chunk_cache_type;
54  using chunk_measured_type = typename chunk_cache_type::measured_type;
55  using chunk_algebra_type = typename chunk_cache_type::algebra_type;
56  using chunk_measure_type = typename chunk_cache_type::measure_type;
58 
59  using middle_type = typename Configuration::middle_type;
60  using middle_cache_type = typename Configuration::middle_cache_type;
61  using middle_measured_type = typename middle_cache_type::measured_type;
62  using middle_algebra_type = typename middle_cache_type::algebra_type;
63  using middle_measure_type = typename middle_cache_type::measure_type;
64  using size_access = typename Configuration::size_access;
65 
67 
69 
70 public:
71 
72  /*---------------------------------------------------------------------*/
75  using config_type = Configuration;
78  using size_type = typename config_type::size_type;
79  using difference_type = typename config_type::difference_type;
80  using allocator_type = typename config_type::item_allocator_type;
82 
83  /*---------------------------------------------------------------------*/
86  using value_type = typename config_type::value_type;
89  using const_reference = const value_type&;
90  using pointer = value_type*;
91  using const_pointer = const value_type*;
92  using segment_type = typename config_type::segment_type;
94 
95  /*---------------------------------------------------------------------*/
100  using measured_type = typename cache_type::measured_type;
101  using algebra_type = typename cache_type::algebra_type;
102  using measure_type = typename cache_type::measure_type;
104 
105  using iterator = Iterator<self_type, config_type>;
106  friend iterator;
107 
108 protected:
109 
110  // representation of the structure: two chunks plus a middle sequence of chunks
111  chunk_type back_outer; // if outer is empty, then inner and middle must be empty
112  chunk_type back_inner; // inner is either empty or full
113  std::unique_ptr<middle_type> middle; // middle contains only full chunks
114 
117 
118  /*---------------------------------------------------------------------*/
119 
120  static inline chunk_pointer chunk_alloc() {
121  return new chunk_type();
122  }
123 
124  // only to free empty chunks
125  static inline void chunk_free(chunk_pointer c) {
126  assert(c->empty());
127  delete c;
128  }
129 
130  template <class Pred>
132  chunk_type& src, value_type& x, chunk_type& dst) {
133  chunk_search_type chunk_search;
134  return src.split(chunk_meas, p, chunk_search, middle_meas, prefix, x, dst);
135  }
136 
137  /*---------------------------------------------------------------------*/
138 
139  bool is_buffer(const chunk_type* c) const {
140  return c == &back_outer || c == &back_inner;
141  }
142 
143  // take a chunk "c" and push its content into the back of the middle sequence
144  // as a new chunk; leaving "c" empty.
147  c.swap(*d);
148  middle->push_back(middle_meas, d);
149  }
150 
151  // assumes that back_outer may be empty, while items may be stored elsewhere;
152  // ensures that some items are stored in the back_outer buffer
154  if (back_outer.empty()) {
155  if (! back_inner.empty()) {
156  back_inner.swap(back_outer);
157  } else if (! middle->empty()) {
158  chunk_pointer c = middle->pop_back(middle_meas);
159  back_outer.swap(*c);
160  chunk_free(c);
161  }
162  }
163  assert(! back_outer.empty() || (back_inner.empty() && middle->empty()) );
164  }
165 
166  // assumes that both back_inner and back_outer buffer may be partially filled,
167  // and ensure that the back_inner is either empty or full
169  size_t bisize = back_inner.size();
170  size_t bosize = back_outer.size();
171  if (bisize + bosize <= chunk_capacity) // if fits, put everything in back
172  back_inner.transfer_from_front_to_back(chunk_meas, back_outer, bisize);
173  else // if does not fit, fill up the inner buffer
174  back_outer.transfer_from_front_to_back(chunk_meas, back_inner, chunk_capacity - bisize);
175  }
176 
177  // ensures that back_inner is empty, by pushing it in the middle if it's full
179  if (! back_inner.empty()) {
181  back_inner.swap(*d);
182  middle->push_back(middle_meas, d);
183  }
184  }
185 
187 
189  if (! back_outer.empty())
190  return &back_outer;
191  if (! back_inner.empty())
192  return &back_inner;
193  if (! middle->empty())
194  return middle->cback();
195  return &back_outer;
196  }
197 
198  using position_type = enum {
199  found_back_outer,
200  found_back_inner,
201  found_middle,
202  found_nowhere
203  };
204 
205  template <class Pred>
206  middle_measured_type search(const Pred& p, middle_measured_type prefix, position_type& pos) const {
207  middle_measured_type cur = prefix; // prefix including current chunk
208  if (! middle->empty()) {
209  prefix = cur;
210  cur = middle_algebra_type::combine(cur, middle->get_cached());
211  if (p(cur)) {
212  pos = found_middle;
213  return prefix;
214  }
215  }
216  if (! back_inner.empty()) {
217  prefix = cur;
218  cur = middle_algebra_type::combine(cur, middle_meas(&back_inner));
219  if (p(cur)) {
220  pos = found_back_inner;
221  return prefix;
222  }
223  }
224  if (! back_outer.empty()) {
225  prefix = cur;
226  cur = middle_algebra_type::combine(cur, middle_meas(&back_outer));
227  if (p(cur)) {
228  pos = found_back_outer;
229  return prefix;
230  }
231  }
232  prefix = cur;
233  pos = found_nowhere;
234  return prefix;
235  }
236 
237  // set "found" to true or false depending on success of the search;
238  // and set "cur" to the chunk that contains the item searched,
239  // or to the chunk containing the last item of the sequence if the item was not found.
240  template <class Pred>
242  bool& found, const_chunk_pointer& cur) const {
243  position_type pos;
244  prefix = search(p, prefix, pos);
245  found = true; // default
246  switch (pos) {
247  case found_middle: {
248 #ifdef DEBUG_MIDDLE_SEQUENCE
249  assert(false);
250 #else
251  prefix = middle->search_for_chunk(p, prefix, cur);
252 #endif
253  break;
254  }
255  case found_back_inner: {
256  cur = &back_inner;
257  break;
258  }
259  case found_back_outer: {
260  cur = &back_outer;
261  break;
262  }
263  case found_nowhere: {
264  cur = &back_outer;
265  found = false;
266  break;
267  }
268  } // end switch
269  return prefix;
270  }
271 
272  // precondition: other is empty
273  template <class Pred>
275  assert(other.empty());
277  copy_measure_to(other);
278  position_type pos;
279  prefix = search(p, prefix, pos);
280  switch (pos) {
281  case found_middle: {
282  back_outer.swap(other.back_outer);
283  chunk_pointer c;
284  prefix = middle->split(middle_meas, p, prefix, c, *other.middle);
285  back_outer.swap(*c);
286  chunk_free(c);
287  prefix = chunk_split(p, prefix, back_outer, x, other.back_inner);
289  break;
290  }
291  case found_back_inner: {
292  assert(false); // thanks to the call to ensure_empty_back_inner()
293  break;
294  }
295  case found_back_outer: {
296  prefix = chunk_split(p, prefix, back_outer, x, other.back_outer);
297  break;
298  }
299  case found_nowhere: {
300  // don't split (item not found)
301  break;
302  }
303  } // end switch
306  return prefix;
307  }
308 
309  // precondition: other is empty
310  template <class Pred>
312  size_type sz_orig = size();
313  value_type x;
314  prefix = split_aux(p, prefix, x, other);
315  if (size_access::csize(prefix) < sz_orig)
316  other.push(x);
317  return prefix;
318  }
319 
320  void init() {
321  middle.reset(new middle_type());
322  }
323 
324 public:
325 
326  /*---------------------------------------------------------------------*/
329 
332  init();
333  }
334 
336  : chunk_meas(meas), middle_meas(meas) {
337  init();
338  }
339 
340  chunkedbagbase(const self_type& other)
341  : back_inner(other.back_inner),
342  back_outer(other.back_outer),
343  chunk_meas(other.chunk_meas),
344  middle_meas(other.middle_meas) {
345  middle.reset(new middle_type(*other.middle));
346  check();
347  }
348 
349  chunkedbagbase(std::initializer_list<value_type> l) {
350  init();
351  for (auto it = l.begin(); it != l.end(); it++)
352  push_back(*it);
353  }
354 
356 
357  /*---------------------------------------------------------------------*/
360 
362  bool empty() const {
363  return back_outer.empty();
364  }
365 
366  size_type size() const {
367  size_type sz = 0;
368  sz += size_access::csize(middle->get_cached());
369  sz += back_inner.size();
370  sz += back_outer.size();
371  return sz;
372  }
373 
375 
376  /*---------------------------------------------------------------------*/
379 
382  return back_outer.back();
383  }
384 
386  return back();
387  }
388 
390  return back();
391  }
392 
393  void backn(value_type* dst, size_type nb) const {
394  extras::backn(*this, dst, nb);
395  }
396 
397  void frontn(value_type* dst, size_type nb) const {
398  extras::frontn(*this, dst, nb);
399  }
400 
401  template <class Consumer>
402  void stream_backn(const Consumer& cons, size_type nb) const {
403  extras::stream_backn(*this, cons, nb);
404  }
405 
406  template <class Consumer>
407  void stream_frontn(const Consumer& cons, size_type nb) const {
408  extras::stream_frontn(*this, cons, nb);
409  }
410 
412  assert(n >= 0);
413  assert(n < size());
414  auto it = begin() + n;
415  assert(it.size() == n + 1);
416  return *it;
417  }
418 
420 
421  /*---------------------------------------------------------------------*/
424 
426  void push_back(const value_type& x) {
427  if (back_outer.full()) {
428  if (back_inner.full())
429  push_buffer_back(back_inner);
430  back_outer.swap(back_inner);
431  assert(back_outer.empty());
432  }
433  back_outer.push_back(chunk_meas, x);
434  }
435 
436  void push_front(const value_type& x) {
437  push_back(x);
438  }
439 
440  void push(const value_type& x) {
441  push_back(x);
442  }
443 
445  value_type x = back_outer.back();
446  back_outer.pop_back(chunk_meas);
448  return x;
449  }
450 
452  return pop_back();
453  }
454 
456  return pop_back();
457  }
458 
460  extras::pushn_back(*this, src, nb);
461  }
462 
464  extras::pushn_front(*this, src, nb);
465  }
466 
467  void pushn(const_pointer src, size_type nb) {
468  pushn_back(src, nb);
469  }
470 
472  auto c = [] (const_pointer, const_pointer) { };
473  stream_popn_front<typeof(c), false>(c, nb);
474  }
475 
476  void popn(size_type nb) {
477  popn_back(nb);
478  }
479 
480  void popn_back(size_type nb) {
481  auto c = [] (const_pointer, const_pointer) { };
482  stream_popn_back<typeof(c), false>(c, nb);
483  }
484 
485  void popn_back(value_type* dst, size_type nb) {
486  extras::popn_back(*this, dst, nb);
487  }
488 
489  void popn_front(value_type* dst, size_type nb) {
490  extras::popn_front(*this, dst, nb);
491  }
492 
493  void popn(value_type* dst, size_type nb) {
494  extras::popn_front(*this, dst, nb);
495  }
496 
497  template <class Producer>
498  void stream_pushn_back(const Producer& prod, size_type nb) {
499  if (nb == 0)
500  return;
501  size_type sz_orig = size();
503  chunk_type c;
504  c.swap(back_outer);
505  size_type i = 0;
506  while (i < nb) {
507  size_type cap = (size_type)chunk_capacity;
508  size_type m = std::min(cap, nb - i);
509  m = std::min(m, cap - c.size());
510  std::pair<const_pointer,const_pointer> rng = prod(i, m);
511  const_pointer lo = rng.first;
512  const_pointer hi = rng.second;
513  size_type nb = hi - lo;
514  c.pushn_back(chunk_meas, lo, nb);
515  push_buffer_back(c);
516  i += m;
517  }
519  assert(sz_orig + nb == size());
520  }
521 
522  template <class Producer>
523  void stream_pushn_front(const Producer& prod, size_type nb) {
524  stream_pushn_back(prod, nb);
525  }
526 
527  template <class Producer>
528  void stream_pushn(const Producer& prod, size_type nb) {
529  stream_pushn_back(prod, nb);
530  }
531 
532  template <class Consumer, bool should_consume=true>
533  void stream_popn_back(const Consumer& cons, size_type nb) {
534  size_type sz_orig = size();
535  assert(sz_orig >= nb);
536  size_type i = 0;
537  while (i < nb) {
539  size_type m = std::min(back_outer.size(), nb - i);
540  back_outer.template popn_back<Consumer,should_consume>(chunk_meas, cons, m);
541  i += m;
542  }
543  restore_back_outer_empty_iff_all_empty(); // to restore invariants
544  assert(sz_orig == size() + nb);
545  }
546 
547  template <class Consumer, bool should_consume=true>
548  void stream_popn_front(const Consumer& cons, size_type nb) {
549  stream_popn_back(cons, nb);
550  }
551 
552  template <class Consumer, bool should_consume=true>
553  void stream_popn(const Consumer& cons, size_type nb) {
554  stream_popn_back(cons, nb);
555  }
556 
557  // concatenate data from other; leaving other empty
558  void concat(self_type& other) {
559  if (other.size() == 0)
560  return;
561  if (size() == 0)
562  swap(other);
563  // push inner buffers into the middle sequences
565  other.ensure_empty_back_inner();
566  // merge outer buffer of other
567  back_inner.swap(other.back_outer);
569  // merge the middle sequences
570  middle->concat(middle_meas, *other.middle);
571  assert(other.empty());
572  }
573 
575  template <class Pred>
576  bool split(const Pred& p, reference middle_item, self_type& other) {
577  size_type sz_orig = size();
578  auto q = [&] (middle_measured_type m) {
579  return p(size_access::cclient(m));
580  };
581  middle_measured_type prefix = split_aux(q, middle_algebra_type::identity(), middle_item, other);
582  bool found = (size_access::csize(prefix) < sz_orig);
583  return found;
584  }
585 
587  template <class Pred>
588  void split(const Pred& p, self_type& other) {
589  value_type middle_item;
590  bool found = split(p, middle_item, other);
591  if (found)
592  other.push(middle_item);
593  }
594 
595  /* \brief Split by index
596  *
597  * The container is erased after and including the item at (zero-based) index `i`.
598  *
599  * The erased items are moved to the `other` container.
600  *
601  * \pre The `other` container is empty.
602  */
603  void split(size_type i, self_type& other) {
604  return extras::split_by_index(*this, i, other);
605  }
606 
607  /* The container is erased after and including the item at the
608  * specified `position`.
609  *
610  * The erased items are moved to the `other` container.
611  *
612  * \pre The `other` container is empty.
613  */
614  void split(iterator position, self_type& other) {
615  extras::split_by_iterator(*this, position, other);
616  }
617 
619  extras::split_approximate(*this, other);
620  }
621 
622  iterator insert(iterator position, const value_type& val) {
623  return extras::insert(*this, position, val);
624  }
625 
626  void clear() {
627  popn_back(size());
628  }
629 
630  void swap(self_type& other) {
631  std::swap(chunk_meas, other.chunk_meas);
632  std::swap(middle_meas, other.middle_meas);
633  middle.swap(other.middle);
634  back_inner.swap(other.back_inner);
635  back_outer.swap(other.back_outer);
636  }
637 
639 
640  friend void extras::split_by_index<self_type,size_type>(self_type& c, size_type i, self_type& other);
641 
642  /*---------------------------------------------------------------------*/
645 
647  iterator begin() const {
648  return iterator(this, middle_meas, chunkedseq::iterator::begin);
649  }
650 
651  iterator end() const {
652  return iterator(this, middle_meas, chunkedseq::iterator::end);
653  }
654 
655  template <class Body>
656  void for_each(const Body& f) const {
657  middle->for_each([&] (chunk_pointer p) {
658  p->for_each(f);
659  });
660  back_inner.for_each(f);
661  back_outer.for_each(f);
662  }
663 
664  template <class Body>
665  void for_each(iterator beg, iterator end, const Body& f) const {
666  extras::for_each(beg, end, f);
667  }
668 
669  template <class Body>
670  void for_each_segment(const Body& f) const {
671  middle->for_each([&] (chunk_pointer p) {
672  p->for_each_segment(f);
673  });
674  back_inner.for_each_segment(f);
675  back_outer.for_each_segment(f);
676  }
677 
678  template <class Body>
679  void for_each_segment(iterator begin, iterator end, const Body& f) const {
680  extras::for_each_segment(begin, end, f);
681  }
682 
684 
685  /*---------------------------------------------------------------------*/
688 
691  measured_type m = algebra_type::identity();
692  measured_type n = size_access::cclient(middle->get_cached());
693  m = algebra_type::combine(m, n);
694  m = algebra_type::combine(m, back_inner.get_cached());
695  m = algebra_type::combine(m, back_outer.get_cached());
696  return m;
697  }
698 
700  return chunk_meas;
701  }
702 
704  chunk_meas = meas;
705  middle_meas.set_client_measure(meas);
706  }
707 
708  void copy_measure_to(self_type& other) {
709  other.set_measure(get_measure());
710  }
711 
713 
714  /*---------------------------------------------------------------------*/
717 
719  // TODO: instead of taking this ItemPrinter argument, we could assume the ItemPrinter to be known from Item type
720  template <class ItemPrinter>
721  void print_chunk(const chunk_type& c) const {
722  printf("(");
723  c.for_each([&] (value_type& x) {
724  ItemPrinter::print(x);
725  printf(" ");
726  });
727  printf(")");
728  }
729 
730  // TODO: see whether we want to print cache
731  class DummyCachePrinter { };
732 
733  template <class ItemPrinter, class CachePrinter = DummyCachePrinter>
734  void print() const {
735  auto show = [&] (const chunk_type& c) {
736  print_chunk<ItemPrinter>(c); };
737  printf(" [");
738  middle->for_each([&] (chunk_pointer& c) {
739  show(*c);
740  printf(" ");
741  });
742  printf("] ");
743  show(back_inner);
744  printf(" ");
745  show(back_outer);
746  }
747 
748  void check_size() const {
749 #ifndef NDEBUG
750  size_type sz = 0;
751  middle->for_each([&] (chunk_pointer& c) {
752  sz += c->size();
753  });
754  assert(size_access::csize(middle->get_cached()) == sz);
755  size_type sz2 = 0;
756  for_each([&] (value_type&) {
757  sz2++;
758  });
759  size_type sz3 = size();
760  assert(sz2 == sz3);
761 #endif
762  }
763 
764  void check() const {
765 #ifndef NDEBUG
766  if (! back_inner.empty())
767  assert(back_inner.full());
768  if (back_outer.empty()) {
769  assert(back_inner.empty());
770  assert(middle->empty());
771  }
772  size_t sprev = -1;
773  middle->for_each([&sprev] (chunk_pointer& c) {
774  size_t scur = c->size();
775  if (sprev != -1)
776  assert(sprev + scur >= chunk_capacity);
777  sprev = scur;
778  });
779  check_size();
780 #endif
781  }
782 
784 
785 };
786 
787 /*---------------------------------------------------------------------*/
788 /* Place to put configuration classes for defining various
789  * instantiations of the chunked-sequence functor
790  */
791 
792 template <
793  class Item,
794  int Chunk_capacity=512,
795  class Client_cache=cachedmeasure::trivial<Item, size_t>,
796  template <
797  class Chunk_item,
798  int Cap,
799  class Item_alloc
800  >
802  template <
803  class Top_item_base,
804  int ___Chunk_capacity,
805  class ___Cached_measure,
806  class Top_item_deleter,
807  class Top_item_copier,
808  template <
809  class ___Item,
810  int ___Capacity,
811  class ___Item_alloc
812  >
813  class ___Chunk_struct,
814  class Size_access
815  >
816  class Middle_sequence = bootchunkedseq::cdeque,
817  class Item_alloc=std::allocator<Item>
818 >
820 public:
821 
822  using size_type = typename Client_cache::size_type;
823  using difference_type = ptrdiff_t; // later: check if this is ok
824 
825  using value_type = Item;
827 
828  static constexpr size_type chunk_capacity = size_type(Chunk_capacity);
829 
830  using item_allocator_type = Item_alloc;
831  using item_queue_type = Chunk_struct<value_type, Chunk_capacity, item_allocator_type>;
832 
833  using client_algebra_type = typename Client_cache::algebra_type;
837 
838 #ifdef DISABLE_RANDOM_ACCESS_ITERATOR
840 #else
842 #endif
843 #ifndef ENABLE_FINGER_SEARCH
845 #else
847 #endif
848 
849  using chunk_cache_type = Client_cache;
850  using chunk_measured_type = typename chunk_cache_type::measured_type;
852 
853 // using annotation_type = annotation::annotation_builder<annotation::with_measured<middle_measured_type>>;
855 
857  public:
858 
859  using size_type = typename Client_cache::size_type;
860  using value_type = const chunk_type*;
863 
864  class measure_type {
865  public:
866 
867  using client_measure_type = typename Client_cache::measure_type;
869 
870  private:
871 
872  client_measure_type client_meas;
873 
874  public:
875 
877 
878  measure_type(const client_measure_type& client_meas)
879  : client_meas(client_meas) { }
880 
883  m.value1 = size_type(1);
884  m.value2 = client_meas(v);
885  return m;
886  }
887 
890  for (auto p = lo; p < hi; p++)
891  m = algebra_type::combine(m, operator()(*p));
892  return m;
893  }
894 
897  m.value1 = p->size();
898  m.value2 = p->get_cached();
899  return m;
900  }
901 
902  measured_type operator()(const value_type* lo, const value_type* hi) const {
904  for (auto p = lo; p < hi; p++)
905  m = algebra_type::combine(m, operator()(*p));
906  return m;
907  }
908 
910  return client_meas;
911  }
912 
914  this->client_meas = client_meas;
915  }
916 
917  };
918 
919  static void swap(measured_type& x, measured_type& y) {
920  std::swap(x.value1, y.value1);
921  std::swap(x.value2, y.value2);
922  }
923 
924  };
925 
927 
928  class size_access {
929  public:
931 
932  static constexpr bool enable_index_optimization = true;
933 
935  return m.value1;
936  }
938  return m.value1;
939  }
941  return m.value2;
942  }
944  return m.value2;
945  }
946  };
947 
948 #ifdef DEBUG_MIDDLE_SEQUENCE
949  // use chunk as middle sequence; for the purpose of testing the chunkedbag functor in isolation.
950  static constexpr int middle_capacity = 1<<23;
952  using middle_annotation_type = annotation::annotation_builder<>;
953  using middle_type = chunk<chunk_pointer_queue_type, middle_cache_type,
954  middle_annotation_type, Pointer_deleter, Pointer_deep_copier, size_access>;
955 #else
956  static constexpr int middle_chunk_capacity = 32;
957  using middle_type = Middle_sequence<chunk_type, middle_chunk_capacity, middle_cache_type,
958  Pointer_deleter, Pointer_deep_copier, fixedcapacity::heap_allocated::ringbuffer_ptr, size_access>;
959 #endif
960 
962 
963 };
964 
965 /*---------------------------------------------------------------------*/
966 /* Instantiation for the bootstrapped chunked sequence */
967 
968 namespace bootstrapped {
969 
970 // Application of chunked bag to a configuration
971 
972 template <class Item,
973  int Chunk_capacity = 512,
975  class Item_alloc = std::allocator<Item>>
977 
978 } // end namespace
979 
980 /*---------------------------------------------------------------------*/
981 /* Instantiation for the finger tree */
982 
983 namespace ftree {
984 
985 template <
986  class Item,
987  int Chunk_capacity = 512,
989  class Item_alloc = std::allocator<Item>>
991 
992 } // end namespace
993 
994 /***********************************************************************/
995 
996 } // end namespace
997 } // end namespace
998 } // end namespace
999 
1000 #endif
measured_type operator()(const value_type *lo, const value_type *hi) const
Definition: chunkedbag.hpp:902
static void chunk_free(chunk_pointer c)
Definition: chunkedbag.hpp:125
void push_front(const value_type &x)
Definition: chunkedbag.hpp:436
middle_measured_type search(const Pred &p, middle_measured_type prefix, position_type &pos) const
Definition: chunkedbag.hpp:206
typename Client_cache::algebra_type client_algebra_type
Definition: chunkedbag.hpp:833
typename middle_algebra_type::value_type middle_measured_type
Definition: chunkedbag.hpp:836
void frontn(value_type *dst, size_type nb) const
Definition: chunkedbag.hpp:397
void stream_backn(const Consumer &cons, size_type nb) const
Definition: chunkedbag.hpp:402
typename middle_cache_type::algebra_type middle_algebra_type
Definition: chunkedbag.hpp:62
typename config_type::segment_type segment_type
Definition: chunkedbag.hpp:92
typename Configuration::middle_cache_type middle_cache_type
Definition: chunkedbag.hpp:60
static value_type identity()
Definition: algebra.hpp:120
static void swap(measured_type &x, measured_type &y)
Definition: chunkedbag.hpp:919
typename chunk_cache_type::algebra_type chunk_algebra_type
Definition: chunkedbag.hpp:55
base::ringbuffer_ptr< base::heap_allocator< Item, Capacity+1 >> ringbuffer_ptr
void stream_popn_back(const Consumer &cons, size_type nb)
Definition: chunkedbag.hpp:533
void stream_pushn_front(const Producer &prod, size_type nb)
Definition: chunkedbag.hpp:523
Segment descriptor.
Definition: segment.hpp:34
value_type operator[](size_type n) const
Definition: chunkedbag.hpp:411
const_chunk_pointer get_chunk_containing_last_item() const
Definition: chunkedbag.hpp:188
bootchunkseq< bootchunkseq_deque_config< Item, cachedmeasure::trivial< Item, size_t >, Capacity >> cdeque
typename middle_cache_type::measured_type middle_measured_type
Definition: chunkedbag.hpp:61
typename config_type::item_allocator_type allocator_type
Definition: chunkedbag.hpp:80
typename Configuration::size_access size_access
Definition: chunkedbag.hpp:64
chunkedbagbase(const self_type &other)
Definition: chunkedbag.hpp:340
iterator insert(iterator position, const value_type &val)
Definition: chunkedbag.hpp:622
bool is_buffer(const chunk_type *c) const
Definition: chunkedbag.hpp:139
static client_measured_type cclient(middle_measured_type m)
Definition: chunkedbag.hpp:943
void popn_back(value_type *dst, size_type nb)
Definition: chunkedbag.hpp:485
Fixed-capacity array along with cached measurement of array contents.
Definition: chunk.hpp:93
middle_measured_type split_aux(const Pred &p, middle_measured_type prefix, reference x, self_type &other)
Definition: chunkedbag.hpp:274
static value_type combine(value_type x, value_type y)
Definition: algebra.hpp:125
void stream_popn_front(const Consumer &cons, size_type nb)
Definition: chunkedbag.hpp:548
typename chunk_cache_type::measured_type chunk_measured_type
Definition: chunkedbag.hpp:850
void split_approximate(self_type &other)
Definition: chunkedbag.hpp:618
typename Configuration::chunk_cache_type chunk_cache_type
Definition: chunkedbag.hpp:53
void push(const value_type &x)
Definition: chunkedbag.hpp:440
void popn_back(Container &c, value_type *dst, size_type nb)
chunkedbagbase(std::initializer_list< value_type > l)
Definition: chunkedbag.hpp:349
enum{found_back_outer, found_back_inner, found_middle, found_nowhere} position_type
Definition: chunkedbag.hpp:203
typename config_type::difference_type difference_type
Definition: chunkedbag.hpp:79
iterator insert(Container &c, iterator position, const value_type &val)
void push_back(const value_type &x)
Definition: chunkedbag.hpp:426
Representation of a chunk.
middle_measured_type split_aux(const Pred &p, middle_measured_type prefix, self_type &other)
Definition: chunkedbag.hpp:311
void copy_measure_to(self_type &other)
Definition: chunkedbag.hpp:708
void pushn_front(Container &c, const_pointer src, size_type nb)
chunkedbagbase(const measure_type &meas)
Definition: chunkedbag.hpp:335
void for_each_segment(iterator begin, iterator end, const Body &f)
typename config_type::value_type value_type
Definition: chunkedbag.hpp:87
void stream_backn(const Container &c, const Consumer &cons, size_type nb)
chunk< item_queue_type, chunk_cache_type, annotation_type > chunk_type
Definition: chunkedbag.hpp:854
algebra::combiner< size_algebra_type, client_algebra_type > middle_algebra_type
Definition: chunkedbag.hpp:835
Hinze & Patterson's 2-3 finger tree.
typename Client_cache::size_type size_type
Definition: chunkedbag.hpp:822
void split_by_index(Container &c, size_type i, Container &other)
void stream_frontn(const Consumer &cons, size_type nb) const
Definition: chunkedbag.hpp:407
void for_each_segment(const Body &f) const
Definition: chunkedbag.hpp:670
void backn(const Container &c, value_type *dst, size_type nb)
void popn_front(Container &c, value_type *dst, size_type nb)
Definition: algebra.hpp:18
static chunk_pointer chunk_alloc()
Definition: chunkedbag.hpp:120
Fixed capacity vectors.
static size_type csize(middle_measured_type m)
Definition: chunkedbag.hpp:937
size_type size() const
Definition: chunk.hpp:245
void print_chunk(const chunk_type &c) const
Definition: chunkedbag.hpp:721
[int_group_under_addition_and_negation]
Definition: algebra.hpp:105
chunkedbagbase< config_type > self_type
Definition: chunkedbag.hpp:77
Definitions of a few cached-measurement policies.
measure::measured_pair< value1_type, value2_type > value_type
Definition: algebra.hpp:114
typename middle_cache_type::measure_type middle_measure_type
Definition: chunkedbag.hpp:926
void stream_frontn(const Container &c, const Consumer &cons, size_type nb)
typename queue_type::value_type value_type
Definition: chunk.hpp:101
typename Configuration::chunk_type chunk_type
Definition: chunkedbag.hpp:51
void pushn_back(const_pointer src, size_type nb)
Definition: chunkedbag.hpp:459
typename chunk_cache_type::measure_type chunk_measure_type
Definition: chunkedbag.hpp:56
void popn_front(value_type *dst, size_type nb)
Definition: chunkedbag.hpp:489
void split(const Pred &p, self_type &other)
Definition: chunkedbag.hpp:588
measured_type operator()(const client_value_type *lo, const client_value_type *hi) const
Definition: chunkedbag.hpp:888
void stream_popn(const Consumer &cons, size_type nb)
Definition: chunkedbag.hpp:553
Iterator< self_type, config_type > iterator
Definition: chunkedbag.hpp:105
void split_by_iterator(Container &c, iterator position, Container &other)
void for_each(iterator beg, iterator end, const Body &f) const
Definition: chunkedbag.hpp:665
typename Configuration::middle_type middle_type
Definition: chunkedbag.hpp:59
void pushn_front(const_pointer src, size_type nb)
Definition: chunkedbag.hpp:463
void split(size_type i, self_type &other)
Definition: chunkedbag.hpp:603
middle_measured_type chunk_split(const Pred &p, middle_measured_type prefix, chunk_type &src, value_type &x, chunk_type &dst)
Definition: chunkedbag.hpp:131
middle_measured_type search_for_chunk(const Pred &p, middle_measured_type prefix, bool &found, const_chunk_pointer &cur) const
Definition: chunkedbag.hpp:241
void split(iterator position, self_type &other)
Definition: chunkedbag.hpp:614
typename chunk_cache_type::measured_type chunk_measured_type
Definition: chunkedbag.hpp:54
typename config_type::size_type size_type
Definition: chunkedbag.hpp:78
typename middle_cache_type::measure_type middle_measure_type
Definition: chunkedbag.hpp:63
void stream_pushn(const Producer &prod, size_type nb)
Definition: chunkedbag.hpp:528
bool split(const Pred &p, reference middle_item, self_type &other)
Definition: chunkedbag.hpp:576
static client_measured_type & client(middle_measured_type &m)
Definition: chunkedbag.hpp:940
measured_type get_cached() const
Definition: chunk.hpp:254
Extra container operations to be shared by chunked structures.
void pushn(const_pointer src, size_type nb)
Definition: chunkedbag.hpp:467
void for_each(iterator beg, iterator end, const Body &f)
typename cache_type::measured_type measured_type
Definition: chunkedbag.hpp:100
void backn(value_type *dst, size_type nb) const
Definition: chunkedbag.hpp:393
typename cache_type::algebra_type algebra_type
Definition: chunkedbag.hpp:101
Middle_sequence< chunk_type, middle_chunk_capacity, middle_cache_type, Pointer_deleter, Pointer_deep_copier, fixedcapacity::heap_allocated::ringbuffer_ptr, size_access > middle_type
Definition: chunkedbag.hpp:958
typename cache_type::measure_type measure_type
Definition: chunkedbag.hpp:102
void split_approximate(Container &c, Container &other)
STL style iterators for our chunked sequences.
void pushn_back(Container &c, const_pointer src, size_type nb)
Representation of a chunk.
const int chunk_capacity
[weighted_split_example]
void stream_pushn_back(const Producer &prod, size_type nb)
Definition: chunkedbag.hpp:498
typename Configuration::chunk_search_type chunk_search_type
Definition: chunkedbag.hpp:52
void popn(value_type *dst, size_type nb)
Definition: chunkedbag.hpp:493
Chunk_struct< value_type, Chunk_capacity, item_allocator_type > item_queue_type
Definition: chunkedbag.hpp:831
void frontn(const Container &c, value_type *dst, size_type nb)
void for_each(const Body &f) const
Definition: chunkedbag.hpp:656
void set_measure(measure_type meas)
Definition: chunkedbag.hpp:703
static size_type & size(middle_measured_type &m)
Definition: chunkedbag.hpp:934
bytes_8 Item
Definition: do_fifo.cpp:107
std::unique_ptr< middle_type > middle
Definition: chunkedbag.hpp:113
void for_each_segment(iterator begin, iterator end, const Body &f) const
Definition: chunkedbag.hpp:679