STXXL  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vector.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/containers/vector.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2002-2008 Roman Dementiev <[email protected]>
7  * Copyright (C) 2007-2009 Johannes Singler <[email protected]>
8  * Copyright (C) 2008-2010 Andreas Beckmann <[email protected]>
9  * Copyright (C) 2013 Timo Bingmann <[email protected]>
10  *
11  * Distributed under the Boost Software License, Version 1.0.
12  * (See accompanying file LICENSE_1_0.txt or copy at
13  * http://www.boost.org/LICENSE_1_0.txt)
14  **************************************************************************/
15 
16 #ifndef STXXL_CONTAINERS_VECTOR_HEADER
17 #define STXXL_CONTAINERS_VECTOR_HEADER
18 
19 #include <vector>
20 #include <queue>
21 #include <algorithm>
22 
23 #include <stxxl/bits/deprecated.h>
33 
34 
36 
37 #define STXXL_VERBOSE_VECTOR(msg) STXXL_VERBOSE1("vector[" << static_cast<const void*>(this) << "]::" << msg)
38 
39 //! \defgroup stlcont Containers
40 //! \ingroup stllayer
41 //! Containers with STL-compatible interface
42 
43 
44 //! \defgroup stlcont_vector vector
45 //! \ingroup stlcont
46 //! Vector and support classes
47 //! \{
48 
49 template <typename size_type, size_type modulo2, size_type modulo1>
51 {
52  static const size_type modulo12 = modulo1 * modulo2;
53 
54  size_type pos;
55  unsigned_type block1, block2, offset;
56 
57  //! \invariant block2 * modulo12 + block1 * modulo1 + offset == pos && 0 <= block1 &lt; modulo2 && 0 <= offset &lt; modulo1
58 
59  void set(size_type pos)
60  {
61  this->pos = pos;
62  block2 = (int_type)(pos / modulo12);
63  pos -= block2 * modulo12;
64  block1 = (int_type)(pos / modulo1);
65  offset = (int_type)(pos - block1 * modulo1);
66 
67  assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
68  assert(/* 0 <= block1 && */ block1 < modulo2);
69  assert(/* 0 <= offset && */ offset < modulo1);
70  }
71 
72 public:
74  {
75  set(0);
76  }
77 
78  double_blocked_index(size_type pos)
79  {
80  set(pos);
81  }
82 
84  {
85  assert(/* 0 <= block1 && */ block1 < modulo2);
86  assert(/* 0 <= offset && */ offset < modulo1);
87 
88  this->block2 = block2;
89  this->block1 = block1;
90  this->offset = offset;
91  pos = block2 * modulo12 + block1 * modulo1 + offset;
92  }
93 
94  double_blocked_index& operator = (size_type pos)
95  {
96  set(pos);
97  return *this;
98  }
99 
100  //pre-increment operator
102  {
103  ++pos;
104  ++offset;
105  if (offset == modulo1)
106  {
107  offset = 0;
108  ++block1;
109  if (block1 == modulo2)
110  {
111  block1 = 0;
112  ++block2;
113  }
114  }
115 
116  assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
117  assert(/* 0 <= block1 && */ block1 < modulo2);
118  assert(/* 0 <= offset && */ offset < modulo1);
119 
120  return *this;
121  }
122 
123  //post-increment operator
125  {
126  double_blocked_index former(*this);
127  operator ++ ();
128  return former;
129  }
130 
131  //pre-increment operator
133  {
134  --pos;
135  if (offset == 0)
136  {
137  offset = modulo1;
138  if (block1 == 0)
139  {
140  block1 = modulo2;
141  --block2;
142  }
143  --block1;
144  }
145  --offset;
146 
147  assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
148  assert(/*0 <= block1 &&*/ block1 < modulo2);
149  assert(/*0 <= offset &&*/ offset < modulo1);
150 
151  return *this;
152  }
153 
154  //post-increment operator
156  {
157  double_blocked_index former(*this);
158  operator -- ();
159  return former;
160  }
161 
162  double_blocked_index operator + (size_type addend) const
163  {
164  return double_blocked_index(pos + addend);
165  }
166 
168  {
169  set(pos + addend);
170  return *this;
171  }
172 
173  double_blocked_index operator - (size_type addend) const
174  {
175  return double_blocked_index(pos - addend);
176  }
177 
178  size_type operator - (const double_blocked_index& dbi2) const
179  {
180  return pos - dbi2.pos;
181  }
182 
183  double_blocked_index& operator -= (size_type subtrahend)
184  {
185  set(pos - subtrahend);
186  return *this;
187  }
188 
189  bool operator == (const double_blocked_index& dbi2) const
190  {
191  return pos == dbi2.pos;
192  }
193 
194  bool operator != (const double_blocked_index& dbi2) const
195  {
196  return pos != dbi2.pos;
197  }
198 
199  bool operator < (const double_blocked_index& dbi2) const
200  {
201  return pos < dbi2.pos;
202  }
203 
204  bool operator <= (const double_blocked_index& dbi2) const
205  {
206  return pos <= dbi2.pos;
207  }
208 
209  bool operator > (const double_blocked_index& dbi2) const
210  {
211  return pos > dbi2.pos;
212  }
213 
214  bool operator >= (const double_blocked_index& dbi2) const
215  {
216  return pos >= dbi2.pos;
217  }
218 
219  double_blocked_index& operator >>= (size_type shift)
220  {
221  set(pos >> shift);
222  return *this;
223  }
224 
225  size_type get_pos() const
226  {
227  return pos;
228  }
229 
230  const unsigned_type & get_block2() const
231  {
232  return block2;
233  }
234 
235  const unsigned_type & get_block1() const
236  {
237  return block1;
238  }
239 
240  const unsigned_type & get_offset() const
241  {
242  return offset;
243  }
244 };
245 
246 ////////////////////////////////////////////////////////////////////////////
247 
248 template <
249  typename ValueType,
250  unsigned PageSize,
251  typename PagerType,
252  unsigned BlockSize,
253  typename AllocStr,
254  typename SizeType>
255 class vector;
256 
257 template <typename ValueType, typename AllocStr, typename SizeType, typename DiffType,
258  unsigned BlockSize, typename PagerType, unsigned PageSize>
260 
261 template <typename VectorIteratorType>
263 
264 template <typename VectorIteratorType>
266 
267 template <typename VectorIteratorType>
269 
270 ////////////////////////////////////////////////////////////////////////////
271 
272 //! External vector iterator, model of \c ext_random_access_iterator concept.
273 template <typename ValueType, typename AllocStr, typename SizeType, typename DiffType,
274  unsigned BlockSize, typename PagerType, unsigned PageSize>
276 {
279 
280  friend class const_vector_iterator<ValueType, AllocStr, SizeType, DiffType, BlockSize, PagerType, PageSize>;
281 
282 public:
283  //! \name Types
284  //! \{
285 
288 
289  typedef unsigned block_offset_type;
291  friend class vector<ValueType, PageSize, PagerType, BlockSize, AllocStr, SizeType>;
293  typedef typename bids_container_type::iterator bids_container_iterator;
297 
298  typedef std::random_access_iterator_tag iterator_category;
304  typedef typename vector_type::pointer pointer;
306 
307  //! \}
308 
309 protected:
312 
313 private:
314  //! private constructor for initializing other iterators
316  : offset(o), p_vector(v)
317  { }
318 
319 public:
320  //! constructs invalid iterator
322  : offset(0), p_vector(NULL)
323  { }
324  //! copy-constructor
326  : offset(a.offset),
327  p_vector(a.p_vector)
328  { }
329 
330  //! \name Iterator Properties
331  //! \{
332 
333  //! return pointer to vector containing iterator
335  {
336  return p_vector;
337  }
338  //! return block offset of current element
340  {
341  return static_cast<block_offset_type>(offset.get_offset());
342  }
343  //! return iterator to BID containg current element
345  {
346  return p_vector->bid(offset);
347  }
348 
349  //! \}
350 
351  //! \name Access Operators
352  //! \{
353 
354  //! return current element
355  reference operator * ()
356  {
357  return p_vector->element(offset);
358  }
359  //! return pointer to current element
360  pointer operator -> ()
361  {
362  return &(p_vector->element(offset));
363  }
364  //! return const reference to current element
365  const_reference operator * () const
366  {
367  return p_vector->const_element(offset);
368  }
369  //! return const pointer to current element
370  const_pointer operator -> () const
371  {
372  return &(p_vector->const_element(offset));
373  }
374  //! return mutable reference to element +i after the current element
375  reference operator [] (size_type i)
376  {
377  return p_vector->element(offset.get_pos() + i);
378  }
379 
380 #ifdef _LIBCPP_VERSION
381  //-tb 2013-11: libc++ defines std::reverse_iterator::operator[] in such a
382  // way that it expects vector_iterator::operator[] to return a (mutable)
383  // reference. Thus to remove confusion about the compiler error, we remove
384  // the operator[] const for libc++. The const_reference actually violates
385  // some version of the STL standard, but works well in gcc's libstdc++.
386 #else
387  //! return const reference to element +i after the current element
388  const_reference operator [] (size_type i) const
389  {
390  return p_vector->const_element(offset.get_pos() + i);
391  }
392 #endif
393  //! \}
394 
395  //! \name Relative Calculation of Iterators
396  //! \{
397 
398  //! calculate different between two iterator
399  difference_type operator - (const self_type& a) const
400  {
401  return offset - a.offset;
402  }
403  //! calculate different between two iterator
404  difference_type operator - (const const_self_type& a) const
405  {
406  return offset - a.offset;
407  }
408  //! return iterator advanced -i positions in the vector
409  self_type operator - (size_type i) const
410  {
411  return self_type(p_vector, offset.get_pos() - i);
412  }
413  //! return iterator advanced +i positions in the vector
414  self_type operator + (size_type i) const
415  {
416  return self_type(p_vector, offset.get_pos() + i);
417  }
418  //! advance this iterator -i positions in the vector
419  self_type& operator -= (size_type i)
420  {
421  offset -= i;
422  return *this;
423  }
424  //! advance this iterator +i positions in the vector
426  {
427  offset += i;
428  return *this;
429  }
430  //! advance this iterator to next position in the vector
432  {
433  offset++;
434  return *this;
435  }
436  //! advance this iterator to next position in the vector
438  {
439  self_type tmp = *this;
440  offset++;
441  return tmp;
442  }
443  //! advance this iterator to preceding position in the vector
445  {
446  offset--;
447  return *this;
448  }
449  //! advance this iterator to preceding position in the vector
451  {
452  self_type tmp = *this;
453  offset--;
454  return tmp;
455  }
456 
457  //! \}
458 
459  //! \name Comparison Operators
460  //! \{
461 
462  bool operator == (const self_type& a) const
463  {
464  assert(p_vector == a.p_vector);
465  return offset == a.offset;
466  }
467  bool operator != (const self_type& a) const
468  {
469  assert(p_vector == a.p_vector);
470  return offset != a.offset;
471  }
472  bool operator < (const self_type& a) const
473  {
474  assert(p_vector == a.p_vector);
475  return offset < a.offset;
476  }
477  bool operator <= (const self_type& a) const
478  {
479  assert(p_vector == a.p_vector);
480  return offset <= a.offset;
481  }
482  bool operator > (const self_type& a) const
483  {
484  assert(p_vector == a.p_vector);
485  return offset > a.offset;
486  }
487  bool operator >= (const self_type& a) const
488  {
489  assert(p_vector == a.p_vector);
490  return offset >= a.offset;
491  }
492 
493  bool operator == (const const_self_type& a) const
494  {
495  assert(p_vector == a.p_vector);
496  return offset == a.offset;
497  }
498  bool operator != (const const_self_type& a) const
499  {
500  assert(p_vector == a.p_vector);
501  return offset != a.offset;
502  }
503  bool operator < (const const_self_type& a) const
504  {
505  assert(p_vector == a.p_vector);
506  return offset < a.offset;
507  }
508  bool operator <= (const const_self_type& a) const
509  {
510  assert(p_vector == a.p_vector);
511  return offset <= a.offset;
512  }
513  bool operator > (const const_self_type& a) const
514  {
515  assert(p_vector == a.p_vector);
516  return offset > a.offset;
517  }
518  bool operator >= (const const_self_type& a) const
519  {
520  assert(p_vector == a.p_vector);
521  return offset >= a.offset;
522  }
523 
524  //! \}
525 
526  //! \name Flushing Operation
527  //! \{
528 
530  {
531  p_vector->block_externally_updated(offset);
532  }
533 
534  void flush()
535  {
536  p_vector->flush();
537  }
538 
539  //! \}
540 };
541 
542 ////////////////////////////////////////////////////////////////////////////
543 
544 //! Const external vector iterator, model of \c ext_random_access_iterator concept.
545 template <typename ValueType, typename AllocStr, typename SizeType, typename DiffType,
546  unsigned BlockSize, typename PagerType, unsigned PageSize>
547 class const_vector_iterator
548 {
551 
552  friend class vector_iterator<ValueType, AllocStr, SizeType, DiffType, BlockSize, PagerType, PageSize>;
553 
554 public:
555  //! \name Types
556  //! \{
557 
560 
561  typedef unsigned block_offset_type;
563  friend class vector<ValueType, PageSize, PagerType, BlockSize, AllocStr, SizeType>;
565  typedef typename bids_container_type::iterator bids_container_iterator;
569 
570  typedef std::random_access_iterator_tag iterator_category;
578 
579  //! \}
580 
581 protected:
584 
585 private:
586  //! private constructor for initializing other iterators
588  : offset(o), p_vector(v)
589  { }
590 
591 public:
592  //! constructs invalid iterator
594  : offset(0), p_vector(NULL)
595  { }
596  //! copy-constructor
598  : offset(a.offset), p_vector(a.p_vector)
599  { }
600  //! copy-constructor from mutable iterator
602  : offset(a.offset), p_vector(a.p_vector)
603  { }
604 
605  //! \name Iterator Properties
606  //! \{
607 
608  //! return pointer to vector containing iterator
609  const vector_type * parent_vector() const
610  {
611  return p_vector;
612  }
613  //! return block offset of current element
615  {
616  return static_cast<block_offset_type>(offset.get_offset());
617  }
618  //! return iterator to BID containg current element
620  {
621  return ((vector_type*)p_vector)->bid(offset);
622  }
623 
624  //! \}
625 
626  //! \name Access Operators
627  //! \{
628 
629  //! return current element
630  const_reference operator * () const
631  {
632  return p_vector->const_element(offset);
633  }
634  //! return pointer to current element
635  const_pointer operator -> () const
636  {
637  return &(p_vector->const_element(offset));
638  }
639  //! return const reference to element +i after the current element
640  const_reference operator [] (size_type i) const
641  {
642  return p_vector->const_element(offset.get_pos() + i);
643  }
644 
645  //! \}
646 
647  //! \name Relative Calculation of Iterators
648  //! \{
649 
650  //! calculate different between two iterator
651  difference_type operator - (const self_type& a) const
652  {
653  return offset - a.offset;
654  }
655  //! calculate different between two iterator
656  difference_type operator - (const mutable_self_type& a) const
657  {
658  return offset - a.offset;
659  }
660  //! return iterator advanced -i positions in the vector
661  self_type operator - (size_type i) const
662  {
663  return self_type(p_vector, offset.get_pos() - i);
664  }
665  //! return iterator advanced +i positions in the vector
666  self_type operator + (size_type i) const
667  {
668  return self_type(p_vector, offset.get_pos() + i);
669  }
670  //! advance this iterator -i positions in the vector
671  self_type& operator -= (size_type i)
672  {
673  offset -= i;
674  return *this;
675  }
676  //! advance this iterator +i positions in the vector
678  {
679  offset += i;
680  return *this;
681  }
682  //! advance this iterator to next position in the vector
684  {
685  offset++;
686  return *this;
687  }
688  //! advance this iterator to next position in the vector
690  {
691  self_type tmp_ = *this;
692  offset++;
693  return tmp_;
694  }
695  //! advance this iterator to preceding position in the vector
697  {
698  offset--;
699  return *this;
700  }
701  //! advance this iterator to preceding position in the vector
703  {
704  self_type tmp = *this;
705  offset--;
706  return tmp;
707  }
708 
709  //! \}
710 
711  //! \name Comparison Operators
712  //! \{
713 
714  bool operator == (const self_type& a) const
715  {
716  assert(p_vector == a.p_vector);
717  return offset == a.offset;
718  }
719  bool operator != (const self_type& a) const
720  {
721  assert(p_vector == a.p_vector);
722  return offset != a.offset;
723  }
724  bool operator < (const self_type& a) const
725  {
726  assert(p_vector == a.p_vector);
727  return offset < a.offset;
728  }
729  bool operator <= (const self_type& a) const
730  {
731  assert(p_vector == a.p_vector);
732  return offset <= a.offset;
733  }
734  bool operator > (const self_type& a) const
735  {
736  assert(p_vector == a.p_vector);
737  return offset > a.offset;
738  }
739  bool operator >= (const self_type& a) const
740  {
741  assert(p_vector == a.p_vector);
742  return offset >= a.offset;
743  }
744 
745  bool operator == (const mutable_self_type& a) const
746  {
747  assert(p_vector == a.p_vector);
748  return offset == a.offset;
749  }
750  bool operator != (const mutable_self_type& a) const
751  {
752  assert(p_vector == a.p_vector);
753  return offset != a.offset;
754  }
755  bool operator < (const mutable_self_type& a) const
756  {
757  assert(p_vector == a.p_vector);
758  return offset < a.offset;
759  }
760  bool operator <= (const mutable_self_type& a) const
761  {
762  assert(p_vector == a.p_vector);
763  return offset <= a.offset;
764  }
765  bool operator > (const mutable_self_type& a) const
766  {
767  assert(p_vector == a.p_vector);
768  return offset > a.offset;
769  }
770  bool operator >= (const mutable_self_type& a) const
771  {
772  assert(p_vector == a.p_vector);
773  return offset >= a.offset;
774  }
775 
776  //! \}
777 
778  //! \name Flushing Operation
779  //! \{
780 
782  {
783  p_vector->block_externally_updated(offset);
784  }
785 
786  void flush()
787  {
788  p_vector->flush();
789  }
790 
791  //! \}
792 };
793 
794 ////////////////////////////////////////////////////////////////////////////
795 
796 //! \brief External vector container. \n
797 //! <b>Introduction</b> to vector container: see \ref tutorial_vector tutorial. \n
798 //! <b>Design and Internals</b> of vector container: see \ref design_vector
799 //!
800 //! For semantics of the methods see documentation of the STL std::vector
801 //! \tparam ValueType type of contained objects (POD with no references to internal memory)
802 //! \tparam PageSize number of blocks in a page
803 //! \tparam PagerType pager type, \c random_pager<x> or \c lru_pager<x>, where x is the default number of pages,
804 //! default is \c lru_pager<8>
805 //! \tparam BlockSize external block size in bytes, default is 2 MiB
806 //! \tparam AllocStr one of allocation strategies: \c striping , \c RC , \c SR , or \c FR
807 //! default is RC
808 //!
809 //! Memory consumption: BlockSize*x*PageSize bytes
810 //! \warning Do not store references to the elements of an external vector. Such references
811 //! might be invalidated during any following access to elements of the vector
812 template <
813  typename ValueType,
814  unsigned PageSize = 4,
815  typename PagerType = lru_pager<8>,
816  unsigned BlockSize = STXXL_DEFAULT_BLOCK_SIZE(ValueType),
817  typename AllocStr = STXXL_DEFAULT_ALLOC_STRATEGY,
818  typename SizeType = stxxl::uint64 // will be deprecated soon
819  >
820 class vector
821 {
822 public:
823  //! \name Standard Types
824  //! \{
825 
826  //! The type of elements stored in the vector.
827  typedef ValueType value_type;
828  //! reference to value_type
830  //! constant reference to value_type
831  typedef const value_type& const_reference;
832  //! pointer to value_type
833  typedef value_type* pointer;
834  //! constant pointer to value_type
835  typedef const value_type* const_pointer;
836  //! an unsigned 64-bit integral type
837  typedef SizeType size_type;
839 
840  typedef PagerType pager_type;
841  typedef AllocStr alloc_strategy_type;
842 
843  enum constants {
844  block_size = BlockSize,
845  page_size = PageSize,
846  on_disk = -1
847  };
848 
849  //! iterator used to iterate through a vector, see \ref design_vector_notes.
850  typedef vector_iterator<value_type, alloc_strategy_type, size_type,
851  difference_type, block_size, pager_type, page_size> iterator;
853 
854  //! constant iterator used to iterate through a vector, see \ref design_vector_notes.
858  typedef std::reverse_iterator<iterator> reverse_iterator;
859  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
860 
861  //! \}
862 
863  //! \name Extra Types
864  //! \{
865 
866  //! vector_bufwriter compatible with this vector
868 
869  //! vector_bufreader compatible with this vector
871 
872  //! vector_bufreader compatible with this vector
874 
875  //! \internal
876  class bid_vector : public std::vector<BID<block_size> >
877  {
878  public:
879  typedef std::vector<BID<block_size> > super_type;
880  typedef typename super_type::size_type size_type;
881  typedef typename super_type::value_type bid_type;
882 
884  { }
885  };
886 
887  typedef bid_vector bids_container_type;
888  typedef typename bids_container_type::iterator bids_container_iterator;
889  typedef typename bids_container_type::const_iterator const_bids_container_iterator;
890 
891  //! type of the block used in disk-memory transfers
893  //! double-index type to reference individual elements in a block
895 
896  //! \}
897 
898 private:
903 
904  // enum specifying status of a page of the vector
905  enum { valid_on_disk = 0, uninitialized = 1, dirty = 2 };
906  //! status of each page (valid_on_disk, uninitialized or dirty)
907  mutable std::vector<unsigned char> m_page_status;
908  mutable std::vector<int_type> m_page_to_slot;
910  mutable std::queue<int_type> m_free_slots;
915 
917  {
918  stxxl::uint64 blocks_fit = file_length / stxxl::uint64(block_type::raw_size);
919  size_type cur_size = blocks_fit * stxxl::uint64(block_type::size);
920  stxxl::uint64 rest = file_length - blocks_fit * stxxl::uint64(block_type::raw_size);
921  return (cur_size + rest / stxxl::uint64(sizeof(value_type)));
922  }
923 
925  {
926  typedef stxxl::uint64 file_size_type;
927  size_type cur_size = size();
928  size_type num_full_blocks = cur_size / block_type::size;
929  if (cur_size % block_type::size != 0)
930  {
931  size_type rest = cur_size - num_full_blocks * block_type::size;
932  return file_size_type(num_full_blocks) * block_type::raw_size + rest * sizeof(value_type);
933  }
934  return file_size_type(num_full_blocks) * block_type::raw_size;
935  }
936 
937 public:
938  //! \name Constructors/Destructors
939  //! \{
940 
941  //! Constructs external vector with n elements.
942  //!
943  //! \param n Number of elements.
944  //! \param npages Number of cached pages.
945  vector(size_type n = 0, unsigned_type npages = pager_type().size())
946  : m_size(n),
947  m_bids((size_t)div_ceil(n, block_type::size)),
948  m_pager(npages),
949  m_page_status(div_ceil(m_bids.size(), page_size)),
950  m_page_to_slot(div_ceil(m_bids.size(), page_size)),
951  m_slot_to_page(npages),
952  m_cache(NULL),
953  m_from(NULL),
954  m_exported(false)
955  {
956  m_bm = block_manager::get_instance();
957 
958  allocate_page_cache();
959 
960  for (size_t i = 0; i < m_page_status.size(); ++i)
961  {
962  m_page_status[i] = uninitialized;
963  m_page_to_slot[i] = on_disk;
964  }
965 
966  for (unsigned_type i = 0; i < numpages(); ++i)
967  m_free_slots.push(i);
968 
969  m_bm->new_blocks(m_alloc_strategy, m_bids.begin(), m_bids.end(), 0);
970  }
971 
972  //! \}
973 
974  //! \name Modifier
975  //! \{
976 
977  //! swap content
978  void swap(vector& obj)
979  {
980  std::swap(m_alloc_strategy, obj.m_alloc_strategy);
981  std::swap(m_size, obj.m_size);
982  std::swap(m_bids, obj.m_bids);
983  std::swap(m_pager, obj.m_pager);
984  std::swap(m_page_status, obj.m_page_status);
985  std::swap(m_page_to_slot, obj.m_page_to_slot);
986  std::swap(m_slot_to_page, obj.m_slot_to_page);
987  std::swap(m_free_slots, obj.m_free_slots);
988  std::swap(m_cache, obj.m_cache);
989  std::swap(m_from, obj.m_from);
990  std::swap(m_exported, obj.m_exported);
991  }
992 
993  //! \}
994 
995  //! \name Miscellaneous
996  //! \{
997 
998  //! Allocate page cache, must be called to allow access to elements.
999  void allocate_page_cache() const
1000  {
1001  // numpages() might be zero
1002  if (!m_cache && numpages() > 0)
1003  m_cache = new simple_vector<block_type>(numpages() * page_size);
1004  }
1005 
1006  //! allows to free the cache, but you may not access any element until call
1007  //! allocate_page_cache() again
1009  {
1010  flush();
1011  delete m_cache;
1012  m_cache = NULL;
1013  }
1014 
1015  //! \name Size and Capacity
1016  //! \{
1017 
1018  //! return the size of the vector.
1019  size_type size() const
1020  {
1021  return m_size;
1022  }
1023  //! true if the vector's size is zero.
1024  bool empty() const
1025  {
1026  return (!m_size);
1027  }
1028 
1029  //! Return the number of elelemtsn for which \a external memory has been
1030  //! allocated. capacity() is always greator than or equal to size().
1032  {
1033  return size_type(m_bids.size()) * block_type::size;
1034  }
1035  //! Returns the number of bytes that the vector has allocated on disks.
1037  {
1038  return size_type(m_bids.size()) * block_type::raw_size;
1039  }
1040 
1041  /*! \brief Reserves at least n elements in external memory.
1042  *
1043  * If n is less than or equal to capacity(), this call has no
1044  * effect. Otherwise, it is a request for allocation of additional \b
1045  * external memory. If the request is successful, then capacity() is
1046  * greater than or equal to n; otherwise capacity() is unchanged. In either
1047  * case, size() is unchanged.
1048  */
1050  {
1051  if (n <= capacity())
1052  return;
1053 
1054  unsigned_type old_bids_size = m_bids.size();
1055  unsigned_type new_bids_size = (unsigned_type)div_ceil(n, block_type::size);
1056  unsigned_type new_pages = div_ceil(new_bids_size, page_size);
1057  m_page_status.resize(new_pages, uninitialized);
1058  m_page_to_slot.resize(new_pages, on_disk);
1059 
1060  m_bids.resize(new_bids_size);
1061  if (m_from == NULL)
1062  {
1063  m_bm->new_blocks(m_alloc_strategy,
1064  m_bids.begin() + old_bids_size, m_bids.end(),
1065  old_bids_size);
1066  }
1067  else
1068  {
1069  size_type offset = size_type(old_bids_size) * size_type(block_type::raw_size);
1070  for (bids_container_iterator it = m_bids.begin() + old_bids_size;
1071  it != m_bids.end(); ++it, offset += size_type(block_type::raw_size))
1072  {
1073  (*it).storage = m_from;
1074  (*it).offset = offset;
1075  }
1076  STXXL_VERBOSE_VECTOR("reserve(): Changing size of file " <<
1077  ((void*)m_from) << " to " << offset);
1078  m_from->set_size(offset);
1079  }
1080  }
1081 
1082  //! Resize vector contents to n items.
1083  //! \warning this will not call the constructor of objects in external memory!
1085  {
1086  _resize(n);
1087  }
1088 
1089  //! Resize vector contents to n items, and allow the allocated external
1090  //! memory to shrink. Internal memory allocation remains unchanged.
1091  //! \warning this will not call the constructor of objects in external memory!
1092  void resize(size_type n, bool shrink_capacity)
1093  {
1094  if (shrink_capacity)
1095  _resize_shrink_capacity(n);
1096  else
1097  _resize(n);
1098  }
1099 
1100  //! \}
1101 
1102 private:
1103  //! Resize vector, only allow capacity growth.
1105  {
1106  reserve(n);
1107  if (n < m_size) {
1108  // mark excess pages as uninitialized and evict them from cache
1109  unsigned_type first_page_to_evict = (unsigned_type)div_ceil(n, block_type::size * page_size);
1110  for (size_t i = first_page_to_evict; i < m_page_status.size(); ++i) {
1111  if (m_page_to_slot[i] != on_disk) {
1112  m_free_slots.push(m_page_to_slot[i]);
1113  m_page_to_slot[i] = on_disk;
1114  }
1115  m_page_status[i] = uninitialized;
1116  }
1117  }
1118  m_size = n;
1119  }
1120 
1121  //! Resize vector, also allow reduction of external memory capacity.
1123  {
1124  unsigned_type old_bids_size = m_bids.size();
1125  unsigned_type new_bids_size = div_ceil(n, block_type::size);
1126 
1127  if (new_bids_size > old_bids_size)
1128  {
1129  reserve(n);
1130  }
1131  else if (new_bids_size < old_bids_size)
1132  {
1133  unsigned_type new_pages_size = div_ceil(new_bids_size, page_size);
1134 
1135  STXXL_VERBOSE_VECTOR("shrinking from " << old_bids_size << " to " <<
1136  new_bids_size << " blocks = from " <<
1137  m_page_status.size() << " to " <<
1138  new_pages_size << " pages");
1139 
1140  // release blocks
1141  if (m_from != NULL)
1142  m_from->set_size(new_bids_size * block_type::raw_size);
1143  else
1144  m_bm->delete_blocks(m_bids.begin() + old_bids_size, m_bids.end());
1145 
1146  m_bids.resize(new_bids_size);
1147 
1148  // don't resize m_page_to_slot or m_page_status, because it is
1149  // still needed to check page status and match the mapping
1150  // m_slot_to_page
1151 
1152  // clear dirty flag, so these pages will be never written
1153  std::fill(m_page_status.begin() + new_pages_size,
1154  m_page_status.end(), (unsigned char)valid_on_disk);
1155  }
1156 
1157  m_size = n;
1158  }
1159 
1160 public:
1161  //! \name Modifiers
1162  //! \{
1163 
1164  //! Erases all of the elements and deallocates all external memory that is
1165  //! occupied.
1166  void clear()
1167  {
1168  m_size = 0;
1169  if (m_from == NULL)
1170  m_bm->delete_blocks(m_bids.begin(), m_bids.end());
1171 
1172  m_bids.clear();
1173  m_page_status.clear();
1174  m_page_to_slot.clear();
1175  while (!m_free_slots.empty())
1176  m_free_slots.pop();
1177 
1178  for (unsigned_type i = 0; i < numpages(); ++i)
1179  m_free_slots.push(i);
1180  }
1181 
1182  //! \name Front and Back Access
1183  //! \{
1184 
1185  //! Append a new element at the end.
1187  {
1188  size_type old_size = m_size;
1189  resize(old_size + 1);
1190  element(old_size) = obj;
1191  }
1192  //! Removes the last element (without returning it, see back()).
1193  void pop_back()
1194  {
1195  resize(m_size - 1);
1196  }
1197 
1198  //! \}
1199 
1200  //! \name Operators
1201  //! \{
1202 
1203  //! Returns a reference to the last element, see \ref design_vector_notes.
1205  {
1206  return element(m_size - 1);
1207  }
1208  //! Returns a reference to the first element, see \ref design_vector_notes.
1210  {
1211  return element(0);
1212  }
1213  //! Returns a constant reference to the last element, see \ref design_vector_notes.
1215  {
1216  return const_element(m_size - 1);
1217  }
1218  //! Returns a constant reference to the first element, see \ref design_vector_notes.
1220  {
1221  return const_element(0);
1222  }
1223 
1224  //! \}
1225 
1226  //! \name Constructors/Destructors
1227  //! \{
1228 
1229  //! Construct vector from a file.
1230  //! \param from file to be constructed from
1231  //! \param size Number of elements.
1232  //! \param npages Number of cached pages.
1233  //! \warning Only one \c vector can be assigned to a particular (physical) file.
1234  //! The block size of the vector must be a multiple of the element size
1235  //! \c sizeof(ValueType) and the page size (4096).
1236  vector(file* from, size_type size = size_type(-1), unsigned_type npages = pager_type().size())
1237  : m_size((size == size_type(-1)) ? size_from_file_length(from->size()) : size),
1238  m_bids((size_t)div_ceil(m_size, size_type(block_type::size))),
1239  m_pager(npages),
1240  m_page_status(div_ceil(m_bids.size(), page_size)),
1241  m_page_to_slot(div_ceil(m_bids.size(), page_size)),
1242  m_slot_to_page(npages),
1243  m_cache(NULL),
1244  m_from(from),
1245  m_exported(false)
1246  {
1247  // initialize from file
1248  if (!block_type::has_only_data)
1249  {
1250  std::ostringstream str;
1251  str << "The block size for a vector that is mapped to a file must be a multiple of the element size (" <<
1252  sizeof(value_type) << ") and the page size (4096).";
1253  throw std::runtime_error(str.str());
1254  }
1255 
1256  m_bm = block_manager::get_instance();
1257 
1258  allocate_page_cache();
1259 
1260  for (size_t i = 0; i < m_page_status.size(); ++i)
1261  {
1262  m_page_status[i] = valid_on_disk;
1263  m_page_to_slot[i] = on_disk;
1264  }
1265 
1266  for (unsigned_type i = 0; i < numpages(); ++i)
1267  m_free_slots.push(i);
1268 
1269 
1270  // allocate blocks equidistantly and in-order
1271  size_type offset = 0;
1272  for (bids_container_iterator it = m_bids.begin();
1273  it != m_bids.end(); ++it, offset += size_type(block_type::raw_size))
1274  {
1275  (*it).storage = from;
1276  (*it).offset = offset;
1277  }
1278  from->set_size(offset);
1279  }
1280 
1281  //! copy-constructor
1282  vector(const vector& obj)
1283  : m_size(obj.size()),
1284  m_bids((size_t)div_ceil(obj.size(), block_type::size)),
1285  m_pager(obj.numpages()),
1286  m_page_status(div_ceil(m_bids.size(), page_size)),
1287  m_page_to_slot(div_ceil(m_bids.size(), page_size)),
1288  m_slot_to_page(obj.numpages()),
1289  m_cache(NULL),
1290  m_from(NULL),
1291  m_exported(false)
1292  {
1293  assert(!obj.m_exported);
1294  m_bm = block_manager::get_instance();
1295 
1296  allocate_page_cache();
1297 
1298  for (size_t i = 0; i < m_page_status.size(); ++i)
1299  {
1300  m_page_status[i] = uninitialized;
1301  m_page_to_slot[i] = on_disk;
1302  }
1303 
1304  for (unsigned_type i = 0; i < numpages(); ++i)
1305  m_free_slots.push(i);
1306 
1307  m_bm->new_blocks(m_alloc_strategy, m_bids.begin(), m_bids.end(), 0);
1308 
1309  const_iterator inbegin = obj.begin();
1310  const_iterator inend = obj.end();
1311  std::copy(inbegin, inend, begin());
1312  }
1313 
1314  //! \}
1315 
1316  //! \name Operators
1317  //! \{
1318 
1319  //! assignment operator
1320  vector& operator = (const vector& obj)
1321  {
1322  if (&obj != this)
1323  {
1324  vector tmp(obj);
1325  this->swap(tmp);
1326  }
1327  return *this;
1328  }
1329 
1330  //! \}
1331 
1332  //! \name Iterator Construction
1333  //! \{
1334 
1335  //! returns an iterator pointing to the beginning of the vector, see \ref design_vector_notes.
1337  {
1338  return iterator(this, 0);
1339  }
1340  //! returns a const_iterator pointing to the beginning of the vector, see \ref design_vector_notes.
1342  {
1343  return const_iterator(this, 0);
1344  }
1345  //! returns a const_iterator pointing to the beginning of the vector, see \ref design_vector_notes.
1347  {
1348  return begin();
1349  }
1350  //! returns an iterator pointing beyond the end of the vector, see \ref design_vector_notes.
1352  {
1353  return iterator(this, m_size);
1354  }
1355  //! returns a const_iterator pointing beyond the end of the vector, see \ref design_vector_notes.
1357  {
1358  return const_iterator(this, m_size);
1359  }
1360  //! returns a const_iterator pointing beyond the end of the vector, see \ref design_vector_notes.
1362  {
1363  return end();
1364  }
1365 
1366  //! returns a reverse_iterator pointing to the end of the vector.
1368  {
1369  return reverse_iterator(end());
1370  }
1371  //! returns a reverse_iterator pointing to the end of the vector.
1373  {
1374  return const_reverse_iterator(end());
1375  }
1376  //! returns a reverse_iterator pointing to the end of the vector.
1378  {
1379  return const_reverse_iterator(end());
1380  }
1381  //! returns a reverse_iterator pointing beyond the beginning of the vector.
1383  {
1384  return reverse_iterator(begin());
1385  }
1386  //! returns a reverse_iterator pointing beyond the beginning of the vector.
1388  {
1389  return const_reverse_iterator(begin());
1390  }
1391  //! returns a reverse_iterator pointing beyond the beginning of the vector.
1393  {
1394  return const_reverse_iterator(begin());
1395  }
1396 
1397  //! \}
1398 
1399  //! \name Direct Element Access
1400  //! \{
1401 
1402  //! access the element at the given vector's offset
1403  reference operator [] (size_type offset)
1404  {
1405  return element(offset);
1406  }
1407  //! access the element at the given vector's offset
1408  const_reference operator [] (size_type offset) const
1409  {
1410  return const_element(offset);
1411  }
1412 
1413  //! access the element at the given vector's offset
1415  {
1416  assert(offset < (size_type)size());
1417  return element(offset);
1418  }
1419  //! access the element at the given vector's offset
1421  {
1422  assert(offset < (size_type)size());
1423  return const_element(offset);
1424  }
1425 
1426  //! return true if the given vector offset is in cache
1427  bool is_element_cached(size_type offset) const
1428  {
1429  return is_page_cached(blocked_index_type(offset));
1430  }
1431 
1432  //! \}
1433 
1434  //! \name Modifiers
1435  //! \{
1436 
1437  //! Flushes the cache pages to the external memory.
1438  void flush() const
1439  {
1440  simple_vector<bool> non_free_slots(numpages());
1441 
1442  for (unsigned_type i = 0; i < numpages(); i++)
1443  non_free_slots[i] = true;
1444 
1445  while (!m_free_slots.empty())
1446  {
1447  non_free_slots[m_free_slots.front()] = false;
1448  m_free_slots.pop();
1449  }
1450 
1451  for (unsigned_type i = 0; i < numpages(); i++)
1452  {
1453  m_free_slots.push(i);
1454  int_type page_no = m_slot_to_page[i];
1455  if (non_free_slots[i])
1456  {
1457  STXXL_VERBOSE_VECTOR("flush(): flushing page " << i << " at address " <<
1458  (int64(page_no) * int64(block_type::size) * int64(page_size)));
1459  write_page(page_no, i);
1460 
1461  m_page_to_slot[page_no] = on_disk;
1462  }
1463  }
1464  }
1465 
1466  //! \}
1467 
1468  //! \name Constructors/Destructors
1469  //! \{
1470 
1472  {
1473  STXXL_VERBOSE_VECTOR("~vector()");
1474  try
1475  {
1476  flush();
1477  }
1478  catch (io_error e)
1479  {
1480  STXXL_ERRMSG("io_error thrown in ~vector(): " << e.what());
1481  }
1482  catch (...)
1483  {
1484  STXXL_ERRMSG("Exception thrown in ~vector()");
1485  }
1486 
1487  if (!m_exported)
1488  {
1489  if (m_from == NULL) {
1490  m_bm->delete_blocks(m_bids.begin(), m_bids.end());
1491  }
1492  else // file must be truncated
1493  {
1494  STXXL_VERBOSE_VECTOR("~vector(): Changing size of file " <<
1495  ((void*)m_from) << " to " << file_length());
1496  STXXL_VERBOSE_VECTOR("~vector(): size of the vector is " << size());
1497  try
1498  {
1499  m_from->set_size(file_length());
1500  }
1501  catch (...)
1502  {
1503  STXXL_ERRMSG("Exception thrown in ~vector()...set_size()");
1504  }
1505  }
1506  }
1507  delete m_cache;
1508  }
1509 
1510  //! \}
1511 
1512  //! \name Miscellaneous
1513  //! \{
1514 
1515  //! Export data such that it is persistent on the file system. Resulting
1516  //! files will be numbered ascending.
1517  void export_files(std::string filename_prefix)
1518  {
1519  int64 no = 0;
1520  for (bids_container_iterator i = m_bids.begin(); i != m_bids.end(); ++i) {
1521  std::ostringstream number;
1522  number << std::setw(9) << std::setfill('0') << no;
1523  size_type current_block_size =
1524  ((i + 1) == m_bids.end() && m_size % block_type::size > 0) ?
1525  (m_size % block_type::size) * sizeof(value_type) :
1526  block_type::size * sizeof(value_type);
1527  (*i).storage->export_files((*i).offset, current_block_size, filename_prefix + number.str());
1528  ++no;
1529  }
1530  m_exported = true;
1531  }
1532 
1533  //! Get the file associated with this vector, or NULL.
1534  file * get_file() const
1535  {
1536  return m_from;
1537  }
1538 
1539  //! \}
1540 
1541  //! \name Capacity
1542  //! \{
1543 
1544  //! Set the blocks and the size of this container explicitly.
1545  //! The vector must be completely empty before.
1546  template <typename ForwardIterator>
1547  void set_content(const ForwardIterator& bid_begin, const ForwardIterator& bid_end, size_type n)
1548  {
1549  unsigned_type new_bids_size = div_ceil(n, block_type::size);
1550  m_bids.resize(new_bids_size);
1551  std::copy(bid_begin, bid_end, m_bids.begin());
1552  unsigned_type new_pages = div_ceil(new_bids_size, page_size);
1553  m_page_status.resize(new_pages, valid_on_disk);
1554  m_page_to_slot.resize(new_pages, on_disk);
1555  m_size = n;
1556  }
1557 
1558  //! Number of pages used by the pager.
1559  inline unsigned_type numpages() const
1560  {
1561  return m_pager.size();
1562  }
1563 
1564  //! \}
1565 
1566 private:
1568  {
1569  return (m_bids.begin() +
1570  static_cast<typename bids_container_type::size_type>
1571  (offset / block_type::size));
1572  }
1574  {
1575  return (m_bids.begin() +
1576  static_cast<typename bids_container_type::size_type>
1577  (offset.get_block2() * PageSize + offset.get_block1()));
1578  }
1580  {
1581  return (m_bids.begin() +
1582  static_cast<typename bids_container_type::size_type>
1583  (offset / block_type::size));
1584  }
1586  {
1587  return (m_bids.begin() +
1588  static_cast<typename bids_container_type::size_type>
1589  (offset.get_block2() * PageSize + offset.get_block1()));
1590  }
1591 
1592  void read_page(int_type page_no, int_type cache_slot) const
1593  {
1594  assert(page_no < (int_type)m_page_status.size());
1595  if (m_page_status[page_no] == uninitialized)
1596  return;
1597  STXXL_VERBOSE_VECTOR("read_page(): page_no=" << page_no << " cache_slot=" << cache_slot);
1598  request_ptr* reqs = new request_ptr[page_size];
1599  int_type block_no = page_no * page_size;
1600  int_type last_block = STXXL_MIN(block_no + page_size, int_type(m_bids.size()));
1601  int_type i = cache_slot * page_size, j = 0;
1602  for ( ; block_no < last_block; ++block_no, ++i, ++j)
1603  {
1604  reqs[j] = (*m_cache)[i].read(m_bids[block_no]);
1605  }
1606  assert(last_block - page_no * page_size > 0);
1607  wait_all(reqs, last_block - page_no * page_size);
1608  delete[] reqs;
1609  }
1610  void write_page(int_type page_no, int_type cache_slot) const
1611  {
1612  assert(page_no < (int_type)m_page_status.size());
1613  if (!(m_page_status[page_no] & dirty))
1614  return;
1615  STXXL_VERBOSE_VECTOR("write_page(): page_no=" << page_no << " cache_slot=" << cache_slot);
1616  request_ptr* reqs = new request_ptr[page_size];
1617  int_type block_no = page_no * page_size;
1618  int_type last_block = STXXL_MIN(block_no + page_size, int_type(m_bids.size()));
1619  assert(block_no < last_block);
1620  int_type i = cache_slot * page_size, j = 0;
1621  for ( ; block_no < last_block; ++block_no, ++i, ++j)
1622  {
1623  reqs[j] = (*m_cache)[i].write(m_bids[block_no]);
1624  }
1625  m_page_status[page_no] = valid_on_disk;
1626  assert(last_block - page_no * page_size > 0);
1627  wait_all(reqs, last_block - page_no * page_size);
1628  delete[] reqs;
1629  }
1630 
1632  {
1633 #ifdef STXXL_RANGE_CHECK
1634  assert(offset < (size_type)size());
1635 #endif
1636  return element(blocked_index_type(offset));
1637  }
1638 
1640  {
1641 #ifdef STXXL_RANGE_CHECK
1642  assert(offset.get_pos() < size());
1643 #endif
1644  unsigned_type page_no = offset.get_block2();
1645  assert(page_no < m_page_to_slot.size()); // fails if offset is too large, out of bound access
1646  int_type cache_slot = m_page_to_slot[page_no];
1647  if (cache_slot < 0) // == on_disk
1648  {
1649  if (m_free_slots.empty()) // has to kick
1650  {
1651  int_type kicked_slot = m_pager.kick();
1652  m_pager.hit(kicked_slot);
1653  int_type old_page_no = m_slot_to_page[kicked_slot];
1654  m_page_to_slot[page_no] = kicked_slot;
1655  m_page_to_slot[old_page_no] = on_disk;
1656  m_slot_to_page[kicked_slot] = page_no;
1657 
1658  write_page(old_page_no, kicked_slot);
1659  read_page(page_no, kicked_slot);
1660 
1661  m_page_status[page_no] = dirty;
1662 
1663  return (*m_cache)[kicked_slot * page_size + offset.get_block1()][offset.get_offset()];
1664  }
1665  else
1666  {
1667  int_type free_slot = m_free_slots.front();
1668  m_free_slots.pop();
1669  m_pager.hit(free_slot);
1670  m_page_to_slot[page_no] = free_slot;
1671  m_slot_to_page[free_slot] = page_no;
1672 
1673  read_page(page_no, free_slot);
1674 
1675  m_page_status[page_no] = dirty;
1676 
1677  return (*m_cache)[free_slot * page_size + offset.get_block1()][offset.get_offset()];
1678  }
1679  }
1680  else
1681  {
1682  m_page_status[page_no] = dirty;
1683  m_pager.hit(cache_slot);
1684  return (*m_cache)[cache_slot * page_size + offset.get_block1()][offset.get_offset()];
1685  }
1686  }
1687 
1688  // don't forget to first flush() the vector's cache before updating pages externally
1690  {
1691  // fails if offset is too large, out of bound access
1692  assert(page_no < m_page_status.size());
1693  // "A dirty page has been marked as newly initialized. The page content will be lost."
1694  assert(!(m_page_status[page_no] & dirty));
1695  if (m_page_to_slot[page_no] != on_disk) {
1696  // remove page from cache
1697  m_free_slots.push(m_page_to_slot[page_no]);
1698  m_page_to_slot[page_no] = on_disk;
1699  STXXL_VERBOSE_VECTOR("page_externally_updated(): page_no=" << page_no << " flushed from cache.");
1700  }
1701  else {
1702  STXXL_VERBOSE_VECTOR("page_externally_updated(): page_no=" << page_no << " no need to flush.");
1703  }
1704  m_page_status[page_no] = valid_on_disk;
1705  }
1706 
1708  {
1709  page_externally_updated(offset / (block_type::size * page_size));
1710  }
1711 
1713  {
1714  page_externally_updated(offset.get_block2());
1715  }
1716 
1718  {
1719  return const_element(blocked_index_type(offset));
1720  }
1721 
1723  {
1724  unsigned_type page_no = offset.get_block2();
1725  assert(page_no < m_page_to_slot.size()); // fails if offset is too large, out of bound access
1726  int_type cache_slot = m_page_to_slot[page_no];
1727  if (cache_slot < 0) // == on_disk
1728  {
1729  if (m_free_slots.empty()) // has to kick
1730  {
1731  int_type kicked_slot = m_pager.kick();
1732  m_pager.hit(kicked_slot);
1733  int_type old_page_no = m_slot_to_page[kicked_slot];
1734  m_page_to_slot[page_no] = kicked_slot;
1735  m_page_to_slot[old_page_no] = on_disk;
1736  m_slot_to_page[kicked_slot] = page_no;
1737 
1738  write_page(old_page_no, kicked_slot);
1739  read_page(page_no, kicked_slot);
1740 
1741  return (*m_cache)[kicked_slot * page_size + offset.get_block1()][offset.get_offset()];
1742  }
1743  else
1744  {
1745  int_type free_slot = m_free_slots.front();
1746  m_free_slots.pop();
1747  m_pager.hit(free_slot);
1748  m_page_to_slot[page_no] = free_slot;
1749  m_slot_to_page[free_slot] = page_no;
1750 
1751  read_page(page_no, free_slot);
1752 
1753  return (*m_cache)[free_slot * page_size + offset.get_block1()][offset.get_offset()];
1754  }
1755  }
1756  else
1757  {
1758  m_pager.hit(cache_slot);
1759  return (*m_cache)[cache_slot * page_size + offset.get_block1()][offset.get_offset()];
1760  }
1761  }
1762 
1763  bool is_page_cached(const blocked_index_type& offset) const
1764  {
1765  unsigned_type page_no = offset.get_block2();
1766  assert(page_no < m_page_to_slot.size()); // fails if offset is too large, out of bound access
1767  int_type cache_slot = m_page_to_slot[page_no];
1768  return (cache_slot >= 0); // on_disk == -1
1769  }
1770 };
1771 
1772 template <
1773  typename ValueType,
1774  unsigned PageSize,
1775  typename PagerType,
1776  unsigned BlockSize,
1777  typename AllocStr,
1778  typename SizeType>
1779 inline bool operator == (stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1780  AllocStr, SizeType>& a,
1781  stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1782  AllocStr, SizeType>& b)
1783 {
1784  return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
1785 }
1786 
1787 template <
1788  typename ValueType,
1789  unsigned PageSize,
1790  typename PagerType,
1791  unsigned BlockSize,
1792  typename AllocStr,
1793  typename SizeType>
1794 inline bool operator != (stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1795  AllocStr, SizeType>& a,
1796  stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1797  AllocStr, SizeType>& b)
1798 {
1799  return !(a == b);
1800 }
1801 
1802 template <
1803  typename ValueType,
1804  unsigned PageSize,
1805  typename PagerType,
1806  unsigned BlockSize,
1807  typename AllocStr,
1808  typename SizeType>
1809 inline bool operator < (stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1810  AllocStr, SizeType>& a,
1811  stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1812  AllocStr, SizeType>& b)
1813 {
1814  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
1815 }
1816 
1817 template <
1818  typename ValueType,
1819  unsigned PageSize,
1820  typename PagerType,
1821  unsigned BlockSize,
1822  typename AllocStr,
1823  typename SizeType>
1824 inline bool operator > (stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1825  AllocStr, SizeType>& a,
1826  stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1827  AllocStr, SizeType>& b)
1828 {
1829  return b < a;
1830 }
1831 
1832 template <
1833  typename ValueType,
1834  unsigned PageSize,
1835  typename PagerType,
1836  unsigned BlockSize,
1837  typename AllocStr,
1838  typename SizeType>
1839 inline bool operator <= (stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1840  AllocStr, SizeType>& a,
1841  stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1842  AllocStr, SizeType>& b)
1843 {
1844  return !(b < a);
1845 }
1846 
1847 template <
1848  typename ValueType,
1849  unsigned PageSize,
1850  typename PagerType,
1851  unsigned BlockSize,
1852  typename AllocStr,
1853  typename SizeType>
1854 inline bool operator >= (stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1855  AllocStr, SizeType>& a,
1856  stxxl::vector<ValueType, PageSize, PagerType, BlockSize,
1857  AllocStr, SizeType>& b)
1858 {
1859  return !(a < b);
1860 }
1861 
1862 ////////////////////////////////////////////////////////////////////////////
1863 
1864 // specialization for stxxl::vector, to use only const_iterators
1865 template <typename ValueType, typename AllocStr, typename SizeType, typename DiffType,
1866  unsigned BlockSize, typename PagerType, unsigned PageSize>
1870 {
1871  return is_sorted_helper(
1874 }
1875 
1876 template <typename ValueType, typename AllocStr, typename SizeType, typename DiffType,
1877  unsigned BlockSize, typename PagerType, unsigned PageSize, typename _StrictWeakOrdering>
1881  _StrictWeakOrdering __comp)
1882 {
1883  return is_sorted_helper(
1886  __comp);
1887 }
1888 
1889 ////////////////////////////////////////////////////////////////////////////
1890 
1891 template <typename VectorBufReaderType>
1893 
1894 /*!
1895  * Buffered sequential reader from a vector using overlapped I/O.
1896  *
1897  * This buffered reader can be used to read a large sequential region of a
1898  * vector using overlapped I/O. The object is created from an iterator range,
1899  * which can then be read to using operator<<(), or with operator*() and
1900  * operator++().
1901  *
1902  * The interface also fulfills all requirements of a stream. Actually most of
1903  * the code is identical to stream::vector_iterator2stream.
1904  *
1905  * Note that this buffered reader is inefficient for reading small ranges. This
1906  * is intentional, as one can just use operator[] on the vector for that.
1907  *
1908  * See \ref tutorial_vector_buf
1909  */
1910 template <typename VectorIterator>
1911 class vector_bufreader : public noncopyable
1912 {
1913 public:
1914  //! template parameter: the vector iterator type
1915  typedef VectorIterator vector_iterator;
1916 
1917  //! value type of the output vector
1919 
1920  //! block type used in the vector
1922 
1923  //! type of the input vector
1925 
1926  //! block identifier iterator of the vector
1928 
1929  //! construct output buffered stream used for overlapped reading
1931 
1932  //! construct an iterator for vector_bufreader (for C++11 range-based for loop)
1934 
1935 protected:
1936  //! iterator to the beginning of the range.
1938 
1939  //! internal "current" iterator into the vector.
1941 
1942  //! iterator to the end of the range.
1944 
1945  //! buffered input stream used to overlapped I/O.
1947 
1948  //! number of blocks to use as buffers.
1950 
1951  //! allow vector_bufreader_iterator to check m_iter against its current value
1953 
1954 public:
1955  //! Create overlapped reader for the given iterator range.
1956  //! \param begin iterator to position were to start reading in vector
1957  //! \param end iterator to position were to end reading in vector
1958  //! \param nbuffers number of buffers used for overlapped I/O (>= 2*D recommended)
1960  : m_begin(begin), m_end(end),
1961  m_bufin(NULL),
1962  m_nbuffers(nbuffers)
1963  {
1964  m_begin.flush(); // flush container
1965 
1966  if (m_nbuffers == 0)
1967  m_nbuffers = 2 * config::get_instance()->disks_number();
1968 
1969  rewind();
1970  }
1971 
1972  //! Create overlapped reader for the whole vector's content.
1973  //! \param vec vector to read
1974  //! \param nbuffers number of buffers used for overlapped I/O (>= 2*D recommended)
1975  vector_bufreader(const vector_type& vec, unsigned_type nbuffers = 0)
1976  : m_begin(vec.begin()), m_end(vec.end()),
1977  m_bufin(NULL),
1978  m_nbuffers(nbuffers)
1979  {
1980  m_begin.flush(); // flush container
1981 
1982  if (m_nbuffers == 0)
1983  m_nbuffers = 2 * config::get_instance()->disks_number();
1984 
1985  rewind();
1986  }
1987 
1988  //! Rewind stream back to begin. Note that this recreates the buffered
1989  //! reader and is thus not cheap.
1990  void rewind()
1991  {
1992  m_iter = m_begin;
1993  if (empty()) return;
1994 
1995  if (m_bufin) delete m_bufin;
1996 
1997  // find last bid to read
1998  bids_container_iterator end_bid = m_end.bid() + (m_end.block_offset() ? 1 : 0);
1999 
2000  // construct buffered istream for range
2001  m_bufin = new buf_istream_type(m_begin.bid(), end_bid, m_nbuffers);
2002 
2003  // skip the beginning of the block, up to real beginning
2004  vector_iterator curr = m_begin - m_begin.block_offset();
2005 
2006  for ( ; curr != m_begin; ++curr)
2007  ++(*m_bufin);
2008  }
2009 
2010  //! Finish reading and free buffered reader.
2012  {
2013  if (m_bufin) delete m_bufin;
2014  }
2015 
2016  //! Return constant reference to current item
2017  const value_type& operator * () const
2018  {
2019  return *(*m_bufin);
2020  }
2021 
2022  //! Return constant pointer to current item
2023  const value_type* operator -> () const
2024  {
2025  return &(*(*m_bufin));
2026  }
2027 
2028  //! Advance to next item (asserts if !empty()).
2030  {
2031  assert(!empty());
2032  ++m_iter;
2033  ++(*m_bufin);
2034 
2035  if (UNLIKELY(empty())) {
2036  delete m_bufin;
2037  m_bufin = NULL;
2038  }
2039 
2040  return *this;
2041  }
2042 
2043  //! Read current item into variable and advance to next one.
2044  vector_bufreader& operator >> (value_type& v)
2045  {
2046  v = operator * ();
2047  operator ++ ();
2048 
2049  return *this;
2050  }
2051 
2052  //! Return remaining size.
2053  size_t size() const
2054  {
2055  assert(m_begin <= m_iter && m_iter <= m_end);
2056  return (m_end - m_iter);
2057  }
2058 
2059  //! Returns true once the whole range has been read.
2060  bool empty() const
2061  {
2062  return (m_iter == m_end);
2063  }
2064 
2065  //! Return vector_bufreader_iterator for C++11 range-based for loop
2067  {
2068  return bufreader_iterator(*this, m_begin);
2069  }
2070 
2071  //! Return vector_bufreader_iterator for C++11 range-based for loop
2073  {
2074  return bufreader_iterator(*this, m_end);
2075  }
2076 };
2077 
2078 ////////////////////////////////////////////////////////////////////////////
2079 
2080 /*!
2081  * Adapter for vector_bufreader to match iterator requirements of C++11
2082  * range-based loop construct.
2083  *
2084  * Since vector_bufreader itself points to only one specific item, this
2085  * iterator is merely a counter facade. The functions operator*() and
2086  * operator++() must only be called when it is in _sync_ with the bufreader
2087  * object. This is generally only the case for an iterator constructed with
2088  * begin() and then advanced with operator++(). The class checks this using
2089  * asserts(), the operators will fail if used wrong.
2090  *
2091  * See \ref tutorial_vector_buf
2092  */
2093 template <typename VectorBufReaderType>
2094 class vector_bufreader_iterator
2095 {
2096 public:
2097  //! The underlying buffered reader type
2098  typedef VectorBufReaderType vector_bufreader_type;
2099 
2100  //! Value type of vector
2101  typedef typename vector_bufreader_type::value_type value_type;
2102 
2103  //! Use vector_iterator to reference a point in the vector.
2104  typedef typename vector_bufreader_type::vector_iterator vector_iterator;
2105 
2106 protected:
2107  //! Buffered reader used to access elements in vector
2109 
2110  //! Use vector_iterator to reference a point in the vector.
2112 
2113 public:
2114  //! Construct iterator using vector_iterator
2116  : m_bufreader(bufreader), m_iter(iter)
2117  { }
2118 
2119  //! Return constant reference to current item
2120  const value_type& operator * () const
2121  {
2122  assert(m_bufreader.m_iter == m_iter);
2123  return m_bufreader.operator * ();
2124  }
2125 
2126  //! Return constant pointer to current item
2127  const value_type* operator -> () const
2128  {
2129  assert(m_bufreader.m_iter == m_iter);
2130  return m_bufreader.operator -> ();
2131  }
2132 
2133  //! Make bufreader advance to next item (asserts if !empty() or if iterator
2134  //! does not point to current).
2136  {
2137  assert(m_bufreader.m_iter == m_iter);
2138  m_bufreader.operator ++ ();
2139  m_iter++;
2140  return *this;
2141  }
2142 
2143  //! Equality comparison operator
2145  {
2146  assert(&m_bufreader == &vbi.m_bufreader);
2147  return (m_iter == vbi.m_iter);
2148  }
2149 
2150  //! Inequality comparison operator
2152  {
2153  assert(&m_bufreader == &vbi.m_bufreader);
2154  return (m_iter != vbi.m_iter);
2155  }
2156 };
2157 
2158 ////////////////////////////////////////////////////////////////////////////
2159 
2160 /*!
2161  * Buffered sequential reverse reader from a vector using overlapped I/O.
2162  *
2163  * This buffered reader can be used to read a large sequential region of a
2164  * vector _in_reverse_ using overlapped I/O. The object is created from an
2165  * iterator range, which can then be read to using operator<<(), or with
2166  * operator*() and operator++(), where ++ actually goes to the preceding
2167  * element.
2168  *
2169  * The interface also fulfills all requirements of a stream. Actually most of
2170  * the code is identical to stream::vector_iterator2stream.
2171  *
2172  * Note that this buffered reader is inefficient for reading small ranges. This
2173  * is intentional, as one can just use operator[] on the vector for that.
2174  *
2175  * See \ref tutorial_vector_buf
2176  */
2177 template <typename VectorIterator>
2178 class vector_bufreader_reverse : public noncopyable
2179 {
2180 public:
2181  //! template parameter: the vector iterator type
2182  typedef VectorIterator vector_iterator;
2183 
2184  //! value type of the output vector
2186 
2187  //! block type used in the vector
2189 
2190  //! type of the input vector
2192 
2193  //! block identifier iterator of the vector
2195 
2196  //! construct output buffered stream used for overlapped reading
2198 
2199 protected:
2200  //! iterator to the beginning of the range.
2202 
2203  //! internal "current" iterator into the vector.
2205 
2206  //! iterator to the end of the range.
2208 
2209  //! buffered input stream used to overlapped I/O.
2211 
2212  //! number of blocks to use as buffers.
2214 
2215 public:
2216  //! Create overlapped reader for the given iterator range.
2217  //! \param begin iterator to position were to start reading in vector
2218  //! \param end iterator to position were to end reading in vector
2219  //! \param nbuffers number of buffers used for overlapped I/O (>= 2*D recommended)
2221  : m_begin(begin), m_end(end),
2222  m_bufin(NULL),
2223  m_nbuffers(nbuffers)
2224  {
2225  m_begin.flush(); // flush container
2226 
2227  if (m_nbuffers == 0)
2228  m_nbuffers = 2 * config::get_instance()->disks_number();
2229 
2230  rewind();
2231  }
2232 
2233  //! Create overlapped reader for the whole vector's content.
2234  //! \param vec vector to read
2235  //! \param nbuffers number of buffers used for overlapped I/O (>= 2*D recommended)
2237  : m_begin(vec.begin()), m_end(vec.end()),
2238  m_bufin(NULL),
2239  m_nbuffers(nbuffers)
2240  {
2241  m_begin.flush(); // flush container
2242 
2243  if (m_nbuffers == 0)
2244  m_nbuffers = 2 * config::get_instance()->disks_number();
2245 
2246  rewind();
2247  }
2248 
2249  //! Rewind stream back to begin. Note that this recreates the buffered
2250  //! reader and is thus not cheap.
2251  void rewind()
2252  {
2253  m_iter = m_end;
2254  if (empty()) return;
2255 
2256  if (m_bufin) delete m_bufin;
2257 
2258  // find last bid to read
2259  bids_container_iterator end_bid = m_end.bid() + (m_end.block_offset() ? 1 : 0);
2260 
2261  // construct buffered istream_reverse for range
2262  m_bufin = new buf_istream_type(m_begin.bid(), end_bid, m_nbuffers);
2263 
2264  // skip to beginning of reverse sequence.
2265  stxxl::int_type endoff = m_end.block_offset();
2266  if (endoff == 0) {
2267  // nothing to skip
2268  }
2269  else {
2270  // else, let ifstream_reverse skip last elements at end of block,
2271  // up to real end
2272  for ( ; endoff != block_type::size; endoff++)
2273  ++(*m_bufin);
2274  }
2275  }
2276 
2277  //! Finish reading and free buffered reader.
2279  {
2280  if (m_bufin) delete m_bufin;
2281  }
2282 
2283  //! Return constant reference to current item
2284  const value_type& operator * () const
2285  {
2286  return *(*m_bufin);
2287  }
2288 
2289  //! Return constant pointer to current item
2290  const value_type* operator -> () const
2291  {
2292  return &(*(*m_bufin));
2293  }
2294 
2295  //! Advance to next item (asserts if !empty()).
2297  {
2298  assert(!empty());
2299  --m_iter;
2300  ++(*m_bufin);
2301 
2302  if (UNLIKELY(empty())) {
2303  delete m_bufin;
2304  m_bufin = NULL;
2305  }
2306 
2307  return *this;
2308  }
2309 
2310  //! Read current item into variable and advance to next one.
2312  {
2313  v = operator * ();
2314  operator ++ ();
2315 
2316  return *this;
2317  }
2318 
2319  //! Return remaining size.
2320  size_t size() const
2321  {
2322  assert(m_begin <= m_iter && m_iter <= m_end);
2323  return (m_iter - m_begin);
2324  }
2325 
2326  //! Returns true once the whole range has been read.
2327  bool empty() const
2328  {
2329  return (m_iter == m_begin);
2330  }
2331 };
2332 
2333 ////////////////////////////////////////////////////////////////////////////
2334 
2335 /*!
2336  * Buffered sequential writer to a vector using overlapped I/O.
2337  *
2338  * This buffered writer can be used to write a large sequential region of a
2339  * vector using overlapped I/O. The object is created from an iterator range,
2340  * which can then be written to using operator << (), or with operator * () and
2341  * operator ++ ().
2342  *
2343  * The buffered writer is given one iterator in the constructor. When writing,
2344  * this iterator advances in the vector and will \b enlarge the vector once it
2345  * reaches the end(). The vector size is doubled each time; nevertheless, it is
2346  * better to preinitialize the vector's size using stxxl::vector::resize().
2347  *
2348  * See \ref tutorial_vector_buf
2349  */
2350 template <typename VectorIterator>
2351 class vector_bufwriter : public noncopyable
2352 {
2353 public:
2354  //! template parameter: the vector iterator type
2355  typedef VectorIterator iterator;
2356 
2357  //! type of the output vector
2358  typedef typename iterator::vector_type vector_type;
2359 
2360  //! value type of the output vector
2361  typedef typename iterator::value_type value_type;
2362 
2363  //! block type used in the vector
2364  typedef typename iterator::block_type block_type;
2365 
2366  //! block identifier iterator of the vector
2367  typedef typename iterator::bids_container_iterator bids_container_iterator;
2368 
2369  //! iterator type of vector
2370  typedef typename iterator::iterator vector_iterator;
2371  typedef typename iterator::const_iterator vector_const_iterator;
2372 
2373  //! construct output buffered stream used for overlapped writing
2375 
2376 protected:
2377  //! internal iterator into the vector.
2379 
2380  //! iterator to the current end of the vector.
2382 
2383  //! boolean whether the vector was grown, will shorten at finish().
2384  bool m_grown;
2385 
2386  //! iterator into vector of the last block accessed (used to issue updates
2387  //! when the block is switched).
2389 
2390  //! buffered output stream used to overlapped I/O.
2392 
2393  //! number of blocks to use as buffers.
2395 
2396 public:
2397  //! Create overlapped writer beginning at the given iterator.
2398  //! \param begin iterator to position were to start writing in vector
2399  //! \param nbuffers number of buffers used for overlapped I/O (>= 2D recommended)
2401  unsigned_type nbuffers = 0)
2402  : m_iter(begin),
2403  m_end(m_iter.parent_vector()->end()),
2404  m_grown(false),
2405  m_bufout(NULL),
2406  m_nbuffers(nbuffers)
2407  {
2408  if (m_nbuffers == 0)
2409  m_nbuffers = 2 * config::get_instance()->disks_number();
2410 
2411  assert(m_iter <= m_end);
2412  }
2413 
2414  //! Create overlapped writer for the vector's beginning
2415  //! \param vec vector to write
2416  //! \param nbuffers number of buffers used for overlapped I/O (>= 2D recommended)
2418  unsigned_type nbuffers = 0)
2419  : m_iter(vec.begin()),
2420  m_end(m_iter.parent_vector()->end()),
2421  m_grown(false),
2422  m_bufout(NULL),
2423  m_nbuffers(nbuffers)
2424  {
2425  if (m_nbuffers == 0)
2426  m_nbuffers = 2 * config::get_instance()->disks_number();
2427 
2428  assert(m_iter <= m_end);
2429  }
2430 
2431  //! Finish writing and flush output back to vector.
2433  {
2434  finish();
2435  }
2436 
2437  //! Return mutable reference to item at the position of the internal
2438  //! iterator.
2439  value_type& operator * ()
2440  {
2441  if (UNLIKELY(m_iter == m_end))
2442  {
2443  // iterator points to end of vector -> double vector's size
2444 
2445  if (m_bufout) {
2446  m_bufout->flush(); // flush overlap buffers
2447  delete m_bufout;
2448  m_bufout = NULL;
2449 
2450  if (m_iter.block_offset() != 0)
2451  m_iter.block_externally_updated();
2452  }
2453 
2454  vector_type& v = *m_iter.parent_vector();
2455  if (v.size() < 2 * block_type::size) {
2456  v.resize(2 * block_type::size);
2457  }
2458  else {
2459  v.resize(2 * v.size());
2460  }
2461  m_end = v.end();
2462  m_grown = true;
2463  }
2464 
2465  assert(m_iter < m_end);
2466 
2467  if (UNLIKELY(m_bufout == NULL))
2468  {
2469  if (m_iter.block_offset() != 0)
2470  {
2471  // output position is not at the start of the block, we
2472  // continue to use the iterator initially passed to the
2473  // constructor.
2474  return *m_iter;
2475  }
2476  else
2477  {
2478  // output position is start of block: create buffered writer
2479 
2480  m_iter.flush(); // flush container
2481 
2482  // create buffered write stream for blocks
2483  m_bufout = new buf_ostream_type(m_iter.bid(), m_nbuffers);
2484  m_prevblk = m_iter;
2485 
2486  // drop through to normal output into buffered writer
2487  }
2488  }
2489 
2490  // if the pointer has finished a block, then we inform the vector that
2491  // this block has been updated.
2492  if (UNLIKELY(m_iter.block_offset() == 0)) {
2493  if (m_prevblk != m_iter) {
2494  m_prevblk.block_externally_updated();
2495  m_prevblk = m_iter;
2496  }
2497  }
2498 
2499  return m_bufout->operator * ();
2500  }
2501 
2502  //! Advance internal iterator.
2504  {
2505  // always advance internal iterator
2506  ++m_iter;
2507 
2508  // if buf_ostream active, advance that too
2509  if (LIKELY(m_bufout != NULL)) m_bufout->operator ++ ();
2510 
2511  return *this;
2512  }
2513 
2514  //! Write value to the current position and advance the internal iterator.
2516  {
2517  operator * () = v;
2518  operator ++ ();
2519 
2520  return *this;
2521  }
2522 
2523  //! Finish writing and flush output back to vector.
2524  void finish()
2525  {
2526  if (m_bufout)
2527  {
2528  // must finish the block started in the buffered writer: fill it with
2529  // the data in the vector
2530  vector_const_iterator const_out = m_iter;
2531 
2532  while (const_out.block_offset() != 0)
2533  {
2534  m_bufout->operator * () = *const_out;
2535  m_bufout->operator ++ ();
2536  ++const_out;
2537  }
2538 
2539  // inform the vector that the block has been updated.
2540  if (m_prevblk != m_iter) {
2541  m_prevblk.block_externally_updated();
2542  m_prevblk = m_iter;
2543  }
2544 
2545  delete m_bufout;
2546  m_bufout = NULL;
2547  }
2548 
2549  if (m_grown)
2550  {
2551  vector_type& v = *m_iter.parent_vector();
2552  v.resize(m_iter - v.begin());
2553 
2554  m_grown = false;
2555  }
2556  }
2557 };
2558 
2559 ////////////////////////////////////////////////////////////////////////////
2560 
2561 //! \brief External vector type generator.
2562 //!
2563 //! \tparam ValueType element type of contained objects (POD with no references to internal memory)
2564 //! \tparam PageSize number of blocks in a page, default: \b 4 (recommended >= D)
2565 //! \tparam CachePages number of pages in cache, default: \b 8 (recommended >= 2)
2566 //! \tparam BlockSize external block size \a B in bytes, default: <b>2 MiB</b>
2567 //! \tparam AllocStr parallel disk allocation strategies: \c striping, RC, SR, or FR. default: \b RC.
2568 //! \tparam Pager pager type: \c random or \c lru, default: \b lru.
2569 //!
2570 //! \warning Do not store references to the elements of an external vector. Such references
2571 //! might be invalidated during any following access to elements of the vector
2572 template <
2573  typename ValueType,
2574  unsigned PageSize = 4,
2575  unsigned CachePages = 8,
2576  unsigned BlockSize = STXXL_DEFAULT_BLOCK_SIZE(ValueType),
2577  typename AllocStr = STXXL_DEFAULT_ALLOC_STRATEGY,
2578  pager_type Pager = lru
2579  >
2581 {
2582  typedef typename IF<Pager == lru,
2584 
2586 };
2587 
2588 //! \}
2589 
2591 
2592 namespace std {
2593 
2594 template <
2595  typename ValueType,
2596  unsigned PageSize,
2597  typename PagerType,
2598  unsigned BlockSize,
2599  typename AllocStr,
2600  typename SizeType>
2603 {
2604  a.swap(b);
2605 }
2606 
2607 } // namespace std
2608 
2609 #endif // !STXXL_CONTAINERS_VECTOR_HEADER
2610 // vim: et:ts=4:sw=4
vector_bufreader< const_iterator > bufreader_type
vector_bufreader compatible with this vector
Definition: vector.h:870
vector_type::reference reference
Definition: vector.h:302
vector_iterator m_end
iterator to the end of the range.
Definition: vector.h:1943
vector_bufreader_reverse(vector_iterator begin, vector_iterator end, unsigned_type nbuffers=0)
Create overlapped reader for the given iterator range.
Definition: vector.h:2220
const_reverse_iterator crbegin() const
returns a reverse_iterator pointing to the end of the vector.
Definition: vector.h:1377
block_manager * m_bm
Definition: vector.h:913
const Tp & STXXL_MIN(const Tp &a, const Tp &b)
Definition: utils.h:147
const unsigned_type & get_offset() const
Definition: vector.h:240
bids_container_type::bid_type bid_type
Definition: vector.h:294
Const external vector iterator, model of ext_random_access_iterator concept.
Definition: vector.h:259
vector_iterator()
constructs invalid iterator
Definition: vector.h:321
void _resize(size_type n)
Resize vector, only allow capacity growth.
Definition: vector.h:1104
void read_page(int_type page_no, int_type cache_slot) const
Definition: vector.h:1592
size_type capacity() const
Return the number of elelemtsn for which external memory has been allocated. capacity() is always gre...
Definition: vector.h:1031
#define STXXL_DEFAULT_BLOCK_SIZE(type)
virtual void set_size(offset_type newsize)=0
Changes the size of the file.
std::random_access_iterator_tag iterator_category
Definition: vector.h:298
bids_container_iterator bid(const size_type &offset)
Definition: vector.h:1567
value_type & reference
reference to value_type
Definition: vector.h:829
bool empty() const
true if the vector&#39;s size is zero.
Definition: vector.h:1024
~vector_bufreader_reverse()
Finish reading and free buffered reader.
Definition: vector.h:2278
#define LIKELY(c)
Definition: utils.h:220
friend std::ostream & operator<<(std::ostream &os, const uint_pair &a)
make a uint_pair outputtable via iostreams, using unsigned long long.
Definition: uint_types.h:231
iterator::vector_type vector_type
type of the output vector
Definition: vector.h:2358
vector< ValueType, PageSize, PagerType, BlockSize, AllocStr, SizeType > vector_type
Definition: vector.h:290
vector_iterator< ValueType, AllocStr, SizeType, DiffType, BlockSize, PagerType, PageSize > mutable_self_type
Definition: vector.h:550
std::vector< unsigned char > m_page_status
status of each page (valid_on_disk, uninitialized or dirty)
Definition: vector.h:907
std::vector< BID< block_size > > super_type
Definition: vector.h:879
const unsigned_type & get_block1() const
Definition: vector.h:235
Buffered sequential reverse reader from a vector using overlapped I/O.
Definition: vector.h:265
~vector_bufwriter()
Finish writing and flush output back to vector.
Definition: vector.h:2432
vector_iterator::bids_container_iterator bids_container_iterator
block identifier iterator of the vector
Definition: vector.h:1927
vector_iterator::value_type value_type
value type of the output vector
Definition: vector.h:2185
Block manager class.
Definition: block_manager.h:63
bool is_sorted(_ForwardIter __first, _ForwardIter __last)
Definition: is_sorted.h:54
iterator end()
returns an iterator pointing beyond the end of the vector, see More Notes.
Definition: vector.h:1351
const_vector_iterator< ValueType, AllocStr, SizeType, DiffType, BlockSize, PagerType, PageSize > self_type
Definition: vector.h:549
void export_files(std::string filename_prefix)
Export data such that it is persistent on the file system. Resulting files will be numbered ascending...
Definition: vector.h:1517
file * get_file() const
Get the file associated with this vector, or NULL.
Definition: vector.h:1534
long long int int64
Definition: types.h:40
vector_iterator::block_type block_type
block type used in the vector
Definition: vector.h:2188
super_type::size_type size_type
Definition: vector.h:880
vector_iterator m_begin
iterator to the beginning of the range.
Definition: vector.h:1937
#define STXXL_VERBOSE_VECTOR(msg)
Definition: vector.h:37
void clear()
Erases all of the elements and deallocates all external memory that is occupied.
Definition: vector.h:1166
block_offset_type block_offset() const
return block offset of current element
Definition: vector.h:614
unsigned long long int uint64
Definition: types.h:41
vector_type::blocked_index_type blocked_index_type
Definition: vector.h:296
iterator::iterator vector_iterator
iterator type of vector
Definition: vector.h:2370
ValueType value_type
The type of elements stored in the vector.
Definition: vector.h:827
const value_type & const_reference
constant reference to value_type
Definition: vector.h:831
vector_bufreader(vector_iterator begin, vector_iterator end, unsigned_type nbuffers=0)
Create overlapped reader for the given iterator range.
Definition: vector.h:1959
void rewind()
Rewind stream back to begin. Note that this recreates the buffered reader and is thus not cheap...
Definition: vector.h:2251
const_vector_iterator< ValueType, AllocStr, SizeType, DiffType, BlockSize, PagerType, PageSize > const_self_type
Definition: vector.h:278
vector_iterator::vector_type vector_type
type of the input vector
Definition: vector.h:2191
const vector_type * p_vector
Definition: vector.h:583
vector_iterator m_iter
Use vector_iterator to reference a point in the vector.
Definition: vector.h:2111
vector_bufreader_reverse(const vector_type &vec, unsigned_type nbuffers=0)
Create overlapped reader for the whole vector&#39;s content.
Definition: vector.h:2236
reverse_iterator rend()
returns a reverse_iterator pointing beyond the beginning of the vector.
Definition: vector.h:1382
vector(file *from, size_type size=size_type(-1), unsigned_type npages=pager_type().size())
Construct vector from a file.
Definition: vector.h:1236
const_iterator end() const
returns a const_iterator pointing beyond the end of the vector, see More Notes.
Definition: vector.h:1356
Buffered sequential writer to a vector using overlapped I/O.
Definition: vector.h:268
bids_container_type m_bids
Definition: vector.h:901
const_reference at(size_type offset) const
access the element at the given vector&#39;s offset
Definition: vector.h:1420
file * m_from
Definition: vector.h:912
#define STXXL_DEFAULT_ALLOC_STRATEGY
Definition: block_alloc.h:259
iterator::block_type block_type
block type used in the vector
Definition: vector.h:2364
Adapter for vector_bufreader to match iterator requirements of C++11 range-based loop construct...
Definition: vector.h:1892
vector_iterator m_iter
internal &quot;current&quot; iterator into the vector.
Definition: vector.h:2204
size_type size() const
return the size of the vector.
Definition: vector.h:1019
vector_type::size_type size_type
Definition: vector.h:571
size_t size() const
Return remaining size.
Definition: vector.h:2053
Buffered sequential reader from a vector using overlapped I/O.
Definition: vector.h:262
vector_bufreader(const vector_type &vec, unsigned_type nbuffers=0)
Create overlapped reader for the whole vector&#39;s content.
Definition: vector.h:1975
const_iterator cend() const
returns a const_iterator pointing beyond the end of the vector, see More Notes.
Definition: vector.h:1361
External vector container. Introduction to vector container: see STXXL Vector tutorial. Design and Internals of vector container: see Vector.
Definition: vector.h:255
std::reverse_iterator< iterator > reverse_iterator
Definition: vector.h:858
vector(size_type n=0, unsigned_type npages=pager_type().size())
Constructs external vector with n elements.
Definition: vector.h:945
Buffered output stream.
Definition: buf_ostream.h:31
unsigned_type m_nbuffers
number of blocks to use as buffers.
Definition: vector.h:2394
Pager with random replacement strategy.
Definition: pager.h:38
bool is_page_cached(const blocked_index_type &offset) const
Definition: vector.h:1763
bool empty() const
Returns true once the whole range has been read.
Definition: vector.h:2060
vector_iterator::vector_type vector_type
type of the input vector
Definition: vector.h:1924
uint_pair & operator++()
prefix increment operator (directly manipulates the integer parts)
Definition: uint_types.h:166
bids_container_type::const_iterator const_bids_container_iterator
Definition: vector.h:889
vector< ValueType, PageSize, PagerType, BlockSize, AllocStr, SizeType > vector_type
Definition: vector.h:562
std::random_access_iterator_tag iterator_category
Definition: vector.h:570
void reserve(size_type n)
Reserves at least n elements in external memory.
Definition: vector.h:1049
iterator::value_type value_type
value type of the output vector
Definition: vector.h:2361
void wait_all(request_iterator_ reqs_begin, request_iterator_ reqs_end)
Collection of functions to track statuses of a number of requests.
vector_bufwriter< iterator > bufwriter_type
vector_bufwriter compatible with this vector
Definition: vector.h:867
vector_type * parent_vector() const
return pointer to vector containing iterator
Definition: vector.h:334
std::vector< int_type > m_page_to_slot
Definition: vector.h:908
const_reference const_element(const blocked_index_type &offset) const
Definition: vector.h:1722
vector_iterator< value_type, alloc_strategy_type, size_type, difference_type, block_size, pager_type, page_size > iterator
iterator used to iterate through a vector, see More Notes.
Definition: vector.h:851
void resize(size_type n)
Resize vector contents to n items.
Definition: vector.h:1084
void page_externally_updated(unsigned_type page_no) const
Definition: vector.h:1689
vector_type::blocked_index_type blocked_index_type
Definition: vector.h:568
void pop_back()
Removes the last element (without returning it, see back()).
Definition: vector.h:1193
vector_type::const_pointer pointer
Definition: vector.h:576
bids_container_type::bid_type bid_type
Definition: vector.h:566
vector_const_iterator m_end
iterator to the current end of the vector.
Definition: vector.h:2381
void resize(size_type n, bool shrink_capacity)
Resize vector contents to n items, and allow the allocated external memory to shrink. Internal memory allocation remains unchanged.
Definition: vector.h:1092
vector_type::const_reference const_reference
Definition: vector.h:303
unsigned_type offset
Definition: vector.h:55
bids_container_type::iterator bids_container_iterator
Definition: vector.h:565
vector(const vector &obj)
copy-constructor
Definition: vector.h:1282
void allocate_page_cache() const
Allocate page cache, must be called to allow access to elements.
Definition: vector.h:999
const_vector_iterator()
constructs invalid iterator
Definition: vector.h:593
void block_externally_updated(const blocked_index_type &offset) const
Definition: vector.h:1712
const_bids_container_iterator bid(const blocked_index_type &offset) const
Definition: vector.h:1585
const vector_type * parent_vector() const
return pointer to vector containing iterator
Definition: vector.h:609
uint_pair & operator+=(const uint_pair &b)
addition operator (uses 64-bit arithmetic)
Definition: uint_types.h:186
vector_iterator(vector_type *v, size_type o)
private constructor for initializing other iterators
Definition: vector.h:315
iterator begin()
returns an iterator pointing to the beginning of the vector, see More Notes.
Definition: vector.h:1336
typed_block< BlockSize, ValueType > block_type
type of the block used in disk-memory transfers
Definition: vector.h:892
const_reverse_iterator rbegin() const
returns a reverse_iterator pointing to the end of the vector.
Definition: vector.h:1372
double_blocked_index< SizeType, PageSize, block_type::size > blocked_index_type
double-index type to reference individual elements in a block
Definition: vector.h:894
Block containing elements of fixed length.
Definition: typed_block.h:238
reverse_iterator rbegin()
returns a reverse_iterator pointing to the end of the vector.
Definition: vector.h:1367
unsigned block_offset_type
Definition: vector.h:289
size_type m_size
Definition: vector.h:900
VectorIterator iterator
template parameter: the vector iterator type
Definition: vector.h:2355
~vector_bufreader()
Finish reading and free buffered reader.
Definition: vector.h:2011
Defines interface of file.
Definition: file.h:52
pager_type m_pager
Definition: vector.h:902
void deallocate_page_cache() const
allows to free the cache, but you may not access any element until call allocate_page_cache() again ...
Definition: vector.h:1008
bufreader_iterator end()
Return vector_bufreader_iterator for C++11 range-based for loop.
Definition: vector.h:2072
vector_type::pointer pointer
Definition: vector.h:304
vector_iterator m_iter
internal &quot;current&quot; iterator into the vector.
Definition: vector.h:1940
bool operator!=(const uint_pair &b) const
inequality checking operator
Definition: uint_types.h:201
bid_vector(size_type sz)
Definition: vector.h:883
bool operator<=(const uint_pair &b) const
less-or-equal comparison operator
Definition: uint_types.h:213
vector_type::size_type size_type
Definition: vector.h:299
choose_int_types< my_pointer_size >::int_type int_type
Definition: types.h:66
bool operator>(const uint_pair &b) const
greater comparison operator
Definition: uint_types.h:219
vector_type::block_type block_type
Definition: vector.h:567
iterator::const_iterator vector_const_iterator
Definition: vector.h:2371
const value_type * const_pointer
constant pointer to value_type
Definition: vector.h:835
size_type raw_capacity() const
Returns the number of bytes that the vector has allocated on disks.
Definition: vector.h:1036
blocked_index_type offset
Definition: vector.h:310
super_type::value_type bid_type
Definition: vector.h:881
Buffered input stream, reading the items in the blocks in reverse order.
vector_type::bids_container_type bids_container_type
Definition: vector.h:564
#define UNLIKELY(c)
Definition: utils.h:226
vector_type::bids_container_type bids_container_type
Definition: vector.h:292
alloc_strategy_type m_alloc_strategy
Definition: vector.h:899
unsigned_type numpages() const
Number of pages used by the pager.
Definition: vector.h:1559
vector_type * p_vector
Definition: vector.h:311
bool operator>=(const uint_pair &b) const
greater-or-equal comparison operator
Definition: uint_types.h:225
pager_type
Definition: pager.h:30
const unsigned_type & get_block2() const
Definition: vector.h:230
const_reverse_iterator crend() const
returns a reverse_iterator pointing beyond the beginning of the vector.
Definition: vector.h:1392
void rewind()
Rewind stream back to begin. Note that this recreates the buffered reader and is thus not cheap...
Definition: vector.h:1990
vector_type::value_type value_type
Definition: vector.h:573
bool operator<(const uint_pair &b) const
less-than comparison operator
Definition: uint_types.h:207
vector_type::difference_type difference_type
Definition: vector.h:572
size_t size() const
Return remaining size.
Definition: vector.h:2320
buf_ostream_type * m_bufout
buffered output stream used to overlapped I/O.
Definition: vector.h:2391
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
vector_iterator::bids_container_iterator bids_container_iterator
block identifier iterator of the vector
Definition: vector.h:2194
bids_container_type::iterator bids_container_iterator
Definition: vector.h:293
mutable_self_type iterator
Definition: vector.h:559
vector_bufwriter(vector_iterator begin, unsigned_type nbuffers=0)
Create overlapped writer beginning at the given iterator.
Definition: vector.h:2400
const_vector_iterator(const mutable_self_type &a)
copy-constructor from mutable iterator
Definition: vector.h:601
uint_pair & operator--()
prefix decrement operator (directly manipulates the integer parts)
Definition: uint_types.h:176
bids_container_type::iterator bids_container_iterator
Definition: vector.h:888
Buffered input stream.
Definition: buf_istream.h:37
vector_type::difference_type difference_type
Definition: vector.h:300
bids_container_iterator bid() const
return iterator to BID containg current element
Definition: vector.h:619
vector_bufreader_reverse< const_iterator > bufreader_reverse_type
vector_bufreader compatible with this vector
Definition: vector.h:873
vector_iterator::value_type value_type
value type of the output vector
Definition: vector.h:1918
double_blocked_index(unsigned_type block2, unsigned_type block1, unsigned_type offset)
Definition: vector.h:83
size_type get_pos() const
Definition: vector.h:225
AllocStr alloc_strategy_type
Definition: vector.h:841
reference element(size_type offset)
Definition: vector.h:1631
void push_back(const_reference obj)
Append a new element at the end.
Definition: vector.h:1186
bufreader_iterator begin()
Return vector_bufreader_iterator for C++11 range-based for loop.
Definition: vector.h:2066
vector_type::const_reference reference
Definition: vector.h:574
External vector iterator, model of ext_random_access_iterator concept.
Definition: vector.h:275
vector_iterator m_begin
iterator to the beginning of the range.
Definition: vector.h:2201
value_type * pointer
pointer to value_type
Definition: vector.h:833
vector_bufreader_type & m_bufreader
Buffered reader used to access elements in vector.
Definition: vector.h:2108
buf_istream< block_type, bids_container_iterator > buf_istream_type
construct output buffered stream used for overlapped reading
Definition: vector.h:1930
buf_istream_type * m_bufin
buffered input stream used to overlapped I/O.
Definition: vector.h:2210
vector_iterator(const self_type &a)
copy-constructor
Definition: vector.h:325
stxxl::int64 difference_type
Definition: vector.h:838
unsigned_type m_nbuffers
number of blocks to use as buffers.
Definition: vector.h:1949
buf_ostream< block_type, bids_container_iterator > buf_ostream_type
construct output buffered stream used for overlapped writing
Definition: vector.h:2374
VectorBufReaderType vector_bufreader_type
The underlying buffered reader type.
Definition: vector.h:2098
PagerType pager_type
Definition: vector.h:840
vector_iterator m_end
iterator to the end of the range.
Definition: vector.h:2207
blocked_index_type offset
Definition: vector.h:582
bids_container_iterator bid() const
return iterator to BID containg current element
Definition: vector.h:344
#define STXXL_ERRMSG(x)
Definition: verbose.h:79
vector_bufreader_iterator(vector_bufreader_type &bufreader, const vector_iterator &iter)
Construct iterator using vector_iterator.
Definition: vector.h:2115
const_vector_iterator< value_type, alloc_strategy_type, size_type, difference_type, block_size, pager_type, page_size > const_iterator
constant iterator used to iterate through a vector, see More Notes.
Definition: vector.h:856
vector_type::const_reference const_reference
Definition: vector.h:575
bids_container_iterator bid(const blocked_index_type &offset)
Definition: vector.h:1573
Pager with LRU replacement strategy.
Definition: pager.h:67
iterator::bids_container_iterator bids_container_iterator
block identifier iterator of the vector
Definition: vector.h:2367
void write_page(int_type page_no, int_type cache_slot) const
Definition: vector.h:1610
void set(size_type pos)
Definition: vector.h:59
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
Definition: types.h:67
block_offset_type block_offset() const
return block offset of current element
Definition: vector.h:339
self_type iterator
Definition: vector.h:286
bool m_exported
Definition: vector.h:914
compat::remove_const< Integral >::type div_ceil(Integral __n, Integral2 __d)
Definition: utils.h:200
bool empty() const
Returns true once the whole range has been read.
Definition: vector.h:2327
const_reference back() const
Returns a constant reference to the last element, see More Notes.
Definition: vector.h:1214
reference at(size_type offset)
access the element at the given vector&#39;s offset
Definition: vector.h:1414
IF< Pager==lru, lru_pager< CachePages >, random_pager< CachePages > >::result PagerType
Definition: vector.h:2583
void _resize_shrink_capacity(size_type n)
Resize vector, also allow reduction of external memory capacity.
Definition: vector.h:1122
vector_iterator::block_type block_type
block type used in the vector
Definition: vector.h:1921
SizeType size_type
an unsigned 64-bit integral type
Definition: vector.h:837
void finish()
Finish writing and flush output back to vector.
Definition: vector.h:2524
vector_type::block_type block_type
Definition: vector.h:295
vector_bufreader_type::value_type value_type
Value type of vector.
Definition: vector.h:2101
vector< ValueType, PageSize, PagerType, BlockSize, AllocStr > result
Definition: vector.h:2585
const_reference const_element(size_type offset) const
Definition: vector.h:1717
const_reverse_iterator rend() const
returns a reverse_iterator pointing beyond the beginning of the vector.
Definition: vector.h:1387
IF template metaprogramming statement.
Definition: tmeta.h:31
const_iterator cbegin() const
returns a const_iterator pointing to the beginning of the vector, see More Notes. ...
Definition: vector.h:1346
bool is_sorted_helper(_ForwardIter __first, _ForwardIter __last)
Definition: is_sorted.h:23
void block_externally_updated()
Definition: vector.h:529
const_self_type const_iterator
Definition: vector.h:287
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: vector.h:859
VectorIterator vector_iterator
template parameter: the vector iterator type
Definition: vector.h:2182
vector_type::const_pointer const_pointer
Definition: vector.h:305
bid_vector bids_container_type
Definition: vector.h:887
const_vector_iterator(const self_type &a)
copy-constructor
Definition: vector.h:597
vector_bufwriter(vector_type &vec, unsigned_type nbuffers=0)
Create overlapped writer for the vector&#39;s beginning.
Definition: vector.h:2417
VectorIterator vector_iterator
template parameter: the vector iterator type
Definition: vector.h:1915
stxxl::uint64 file_length() const
Definition: vector.h:924
void set_content(const ForwardIterator &bid_begin, const ForwardIterator &bid_end, size_type n)
Set the blocks and the size of this container explicitly. The vector must be completely empty before...
Definition: vector.h:1547
std::queue< int_type > m_free_slots
Definition: vector.h:910
bool is_element_cached(size_type offset) const
return true if the given vector offset is in cache
Definition: vector.h:1427
buf_istream_reverse< block_type, bids_container_iterator > buf_istream_type
construct output buffered stream used for overlapped reading
Definition: vector.h:2197
vector_bufreader_iterator< vector_bufreader > bufreader_iterator
construct an iterator for vector_bufreader (for C++11 range-based for loop)
Definition: vector.h:1933
unsigned_type m_nbuffers
number of blocks to use as buffers.
Definition: vector.h:2213
void block_externally_updated(size_type offset) const
Definition: vector.h:1707
const_vector_iterator(const vector_type *v, size_type o)
private constructor for initializing other iterators
Definition: vector.h:587
vector_type::value_type value_type
Definition: vector.h:301
size_type size_from_file_length(stxxl::uint64 file_length) const
Definition: vector.h:916
reference element(const blocked_index_type &offset)
Definition: vector.h:1639
vector_iterator m_iter
internal iterator into the vector.
Definition: vector.h:2378
External vector type generator.
Definition: vector.h:2580
simple_vector< int_type > m_slot_to_page
Definition: vector.h:909
const_bids_container_iterator bid(const size_type &offset) const
Definition: vector.h:1579
reference back()
Returns a reference to the last element, see More Notes.
Definition: vector.h:1204
bool m_grown
boolean whether the vector was grown, will shorten at finish().
Definition: vector.h:2384
void flush() const
Flushes the cache pages to the external memory.
Definition: vector.h:1438
vector_type::const_pointer const_pointer
Definition: vector.h:577
bool operator==(const uint_pair &b) const
equality checking operator
Definition: uint_types.h:195
vector_const_iterator m_prevblk
iterator into vector of the last block accessed (used to issue updates when the block is switched)...
Definition: vector.h:2388
reference front()
Returns a reference to the first element, see More Notes.
Definition: vector.h:1209
const_reference front() const
Returns a constant reference to the first element, see More Notes.
Definition: vector.h:1219
#define STXXL_END_NAMESPACE
Definition: namespace.h:17
simple_vector< block_type > * m_cache
Definition: vector.h:911
const_iterator begin() const
returns a const_iterator pointing to the beginning of the vector, see More Notes. ...
Definition: vector.h:1341
vector_iterator< ValueType, AllocStr, SizeType, DiffType, BlockSize, PagerType, PageSize > self_type
Definition: vector.h:277
vector_bufreader_type::vector_iterator vector_iterator
Use vector_iterator to reference a point in the vector.
Definition: vector.h:2104
buf_istream_type * m_bufin
buffered input stream used to overlapped I/O.
Definition: vector.h:1946
double_blocked_index(size_type pos)
Definition: vector.h:78
void swap(vector &obj)
swap content
Definition: vector.h:978