Stxxl  1.3.2
vector.h
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  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef STXXL_VECTOR_HEADER
16 #define STXXL_VECTOR_HEADER
17 
18 #include <vector>
19 #include <queue>
20 #include <algorithm>
21 
22 #include <stxxl/bits/deprecated.h>
23 #include <stxxl/bits/io/request_operations.h>
24 #include <stxxl/bits/mng/mng.h>
25 #include <stxxl/bits/mng/typed_block.h>
26 #include <stxxl/bits/common/tmeta.h>
27 #include <stxxl/bits/containers/pager.h>
28 #include <stxxl/bits/common/is_sorted.h>
29 
30 
31 __STXXL_BEGIN_NAMESPACE
32 
36 
37 
41 
42 template <typename size_type, size_type modulo2, size_type modulo1>
43 class double_blocked_index
44 {
45  static const size_type modulo12 = modulo1 * modulo2;
46 
47  size_type pos, block1, block2, offset;
48 
50 
51  void set(size_type pos)
52  {
53  this->pos = pos;
54  block2 = pos / modulo12;
55  pos -= block2 * modulo12;
56  block1 = pos / modulo1;
57  offset = (pos - block1 * modulo1);
58 
59  assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
60  assert(/* 0 <= block1 && */ block1 < modulo2);
61  assert(/* 0 <= offset && */ offset < modulo1);
62  }
63 
64 public:
65  double_blocked_index()
66  {
67  set(0);
68  }
69 
70  double_blocked_index(size_type pos)
71  {
72  set(pos);
73  }
74 
75  double_blocked_index(size_type block2, size_type block1, size_type offset)
76  {
77  assert(/* 0 <= block1 && */ block1 < modulo2);
78  assert(/* 0 <= offset && */ offset < modulo1);
79 
80  this->block2 = block2;
81  this->block1 = block1;
82  this->offset = offset;
83  pos = block2 * modulo12 + block1 * modulo1 + offset;
84  }
85 
86  double_blocked_index & operator = (size_type pos)
87  {
88  set(pos);
89  return *this;
90  }
91 
92  //pre-increment operator
93  double_blocked_index & operator ++ ()
94  {
95  ++pos;
96  ++offset;
97  if (offset == modulo1)
98  {
99  offset = 0;
100  ++block1;
101  if (block1 == modulo2)
102  {
103  block1 = 0;
104  ++block2;
105  }
106  }
107 
108  assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
109  assert(/* 0 <= block1 && */ block1 < modulo2);
110  assert(/* 0 <= offset && */ offset < modulo1);
111 
112  return *this;
113  }
114 
115  //post-increment operator
116  double_blocked_index operator ++ (int)
117  {
118  double_blocked_index former(*this);
119  operator ++ ();
120  return former;
121  }
122 
123  //pre-increment operator
124  double_blocked_index & operator -- ()
125  {
126  --pos;
127  if (offset == 0)
128  {
129  offset = modulo1;
130  if (block1 == 0)
131  {
132  block1 = modulo2;
133  --block2;
134  }
135  --block1;
136  }
137  --offset;
138 
139  assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
140  assert(/*0 <= block1 &&*/ block1 < modulo2);
141  assert(/*0 <= offset &&*/ offset < modulo1);
142 
143  return *this;
144  }
145 
146  //post-increment operator
147  double_blocked_index operator -- (int)
148  {
149  double_blocked_index former(*this);
150  operator -- ();
151  return former;
152  }
153 
154  double_blocked_index operator + (size_type addend) const
155  {
156  return double_blocked_index(pos + addend);
157  }
158 
159  double_blocked_index & operator += (size_type addend)
160  {
161  set(pos + addend);
162  return *this;
163  }
164 
165  double_blocked_index operator - (size_type addend) const
166  {
167  return double_blocked_index(pos - addend);
168  }
169 
170  size_type operator - (const double_blocked_index & dbi2) const
171  {
172  return pos - dbi2.pos;
173  }
174 
175  double_blocked_index & operator -= (size_type subtrahend)
176  {
177  set(pos - subtrahend);
178  return *this;
179  }
180 
181  bool operator == (const double_blocked_index & dbi2) const
182  {
183  return pos == dbi2.pos;
184  }
185 
186  bool operator != (const double_blocked_index & dbi2) const
187  {
188  return pos != dbi2.pos;
189  }
190 
191  bool operator < (const double_blocked_index & dbi2) const
192  {
193  return pos < dbi2.pos;
194  }
195 
196  bool operator <= (const double_blocked_index & dbi2) const
197  {
198  return pos <= dbi2.pos;
199  }
200 
201  bool operator > (const double_blocked_index & dbi2) const
202  {
203  return pos > dbi2.pos;
204  }
205 
206  bool operator >= (const double_blocked_index & dbi2) const
207  {
208  return pos >= dbi2.pos;
209  }
210 
211  double_blocked_index & operator >>= (size_type shift)
212  {
213  set(pos >> shift);
214  return *this;
215  }
216 
217  size_type get_pos() const
218  {
219  return pos;
220  }
221 
222  const size_type & get_block2() const
223  {
224  return block2;
225  }
226 
227  const size_type & get_block1() const
228  {
229  return block1;
230  }
231 
232  const size_type & get_offset() const
233  {
234  return offset;
235  }
236 };
237 
238 
239 template <unsigned BlkSize_>
240 class bid_vector : public std::vector<BID<BlkSize_> >
241 {
242 public:
243  typedef std::vector<BID<BlkSize_> > _Derived;
244  typedef typename _Derived::size_type size_type;
245  typedef typename _Derived::value_type bid_type;
246 
247  bid_vector(size_type _sz) : _Derived(_sz)
248  { }
249 };
250 
251 
252 template <
253  typename Tp_,
254  unsigned PgSz_,
255  typename PgTp_,
256  unsigned BlkSize_,
257  typename AllocStr_,
258  typename SzTp_>
259 class vector;
260 
261 
262 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
263  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
265 
266 
268 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
269  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
271 {
274 
275  friend class const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>;
276 
277 public:
278  typedef _CIterator const_iterator;
279  typedef _Self iterator;
280 
281  typedef unsigned block_offset_type;
283  friend class vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_>;
284  typedef typename vector_type::bids_container_type bids_container_type;
285  typedef typename bids_container_type::iterator bids_container_iterator;
286  typedef typename bids_container_type::bid_type bid_type;
287  typedef typename vector_type::block_type block_type;
288  typedef typename vector_type::blocked_index_type blocked_index_type;
289 
290  typedef std::random_access_iterator_tag iterator_category;
291  typedef typename vector_type::size_type size_type;
292  typedef typename vector_type::difference_type difference_type;
293  typedef typename vector_type::value_type value_type;
294  typedef typename vector_type::reference reference;
295  typedef typename vector_type::const_reference const_reference;
296  typedef typename vector_type::pointer pointer;
297  typedef typename vector_type::const_pointer const_pointer;
298 
299 protected:
300  blocked_index_type offset;
301  vector_type * p_vector;
302 
303 private:
304  vector_iterator(vector_type * v, size_type o) : offset(o),
305  p_vector(v)
306  { }
307 
308 public:
309  vector_iterator() : offset(0), p_vector(NULL) { }
310  vector_iterator(const _Self & a) :
311  offset(a.offset),
312  p_vector(a.p_vector) { }
313 
314  block_offset_type block_offset() const
315  {
316  return static_cast<block_offset_type>(offset.get_offset());
317  }
318  bids_container_iterator bid() const
319  {
320  return p_vector->bid(offset);
321  }
322 
323  difference_type operator - (const _Self & a) const
324  {
325  return offset - a.offset;
326  }
327 
328  difference_type operator - (const const_iterator & a) const
329  {
330  return offset - a.offset;
331  }
332 
333  _Self operator - (size_type op) const
334  {
335  return _Self(p_vector, offset.get_pos() - op);
336  }
337 
338  _Self operator + (size_type op) const
339  {
340  return _Self(p_vector, offset.get_pos() + op);
341  }
342 
343  _Self & operator -= (size_type op)
344  {
345  offset -= op;
346  return *this;
347  }
348 
349  _Self & operator += (size_type op)
350  {
351  offset += op;
352  return *this;
353  }
354 
355  reference operator * ()
356  {
357  return p_vector->element(offset);
358  }
359 
360  pointer operator -> ()
361  {
362  return &(p_vector->element(offset));
363  }
364 
365  const_reference operator * () const
366  {
367  return p_vector->const_element(offset);
368  }
369 
370  const_pointer operator -> () const
371  {
372  return &(p_vector->const_element(offset));
373  }
374 
375  reference operator [] (size_type op)
376  {
377  return p_vector->element(offset.get_pos() + op);
378  }
379 
380  const_reference operator [] (size_type op) const
381  {
382  return p_vector->const_element(offset.get_pos() + op);
383  }
384 
385  void block_externally_updated()
386  {
387  p_vector->block_externally_updated(offset);
388  }
389 
390  _STXXL_DEPRECATED(void touch())
391  {
392  block_externally_updated();
393  }
394 
395  _Self & operator ++ ()
396  {
397  offset++;
398  return *this;
399  }
400  _Self operator ++ (int)
401  {
402  _Self __tmp = *this;
403  offset++;
404  return __tmp;
405  }
406  _Self & operator -- ()
407  {
408  offset--;
409  return *this;
410  }
411  _Self operator -- (int)
412  {
413  _Self __tmp = *this;
414  offset--;
415  return __tmp;
416  }
417  bool operator == (const _Self & a) const
418  {
419  assert(p_vector == a.p_vector);
420  return offset == a.offset;
421  }
422  bool operator != (const _Self & a) const
423  {
424  assert(p_vector == a.p_vector);
425  return offset != a.offset;
426  }
427  bool operator < (const _Self & a) const
428  {
429  assert(p_vector == a.p_vector);
430  return offset < a.offset;
431  }
432  bool operator <= (const _Self & a) const
433  {
434  assert(p_vector == a.p_vector);
435  return offset <= a.offset;
436  }
437  bool operator > (const _Self & a) const
438  {
439  assert(p_vector == a.p_vector);
440  return offset > a.offset;
441  }
442  bool operator >= (const _Self & a) const
443  {
444  assert(p_vector == a.p_vector);
445  return offset >= a.offset;
446  }
447 
448  bool operator == (const const_iterator & a) const
449  {
450  assert(p_vector == a.p_vector);
451  return offset == a.offset;
452  }
453  bool operator != (const const_iterator & a) const
454  {
455  assert(p_vector == a.p_vector);
456  return offset != a.offset;
457  }
458  bool operator < (const const_iterator & a) const
459  {
460  assert(p_vector == a.p_vector);
461  return offset < a.offset;
462  }
463  bool operator <= (const const_iterator & a) const
464  {
465  assert(p_vector == a.p_vector);
466  return offset <= a.offset;
467  }
468  bool operator > (const const_iterator & a) const
469  {
470  assert(p_vector == a.p_vector);
471  return offset > a.offset;
472  }
473  bool operator >= (const const_iterator & a) const
474  {
475  assert(p_vector == a.p_vector);
476  return offset >= a.offset;
477  }
478 
479  void flush()
480  {
481  p_vector->flush();
482  }
483 #if 0
484  std::ostream & operator << (std::ostream & o) const
485  {
486  o << "vectorpointer: " << ((void *)p_vector) << " offset: " << offset;
487  return o;
488  }
489 #endif
490 };
491 
493 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
494  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
496 {
499 
500  friend class vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>;
501 
502 public:
503  typedef _Self const_iterator;
504  typedef _NonConstIterator iterator;
505 
506  typedef unsigned block_offset_type;
508  friend class vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_>;
509  typedef typename vector_type::bids_container_type bids_container_type;
510  typedef typename bids_container_type::iterator bids_container_iterator;
511  typedef typename bids_container_type::bid_type bid_type;
512  typedef typename vector_type::block_type block_type;
513  typedef typename vector_type::blocked_index_type blocked_index_type;
514 
515  typedef std::random_access_iterator_tag iterator_category;
516  typedef typename vector_type::size_type size_type;
517  typedef typename vector_type::difference_type difference_type;
518  typedef typename vector_type::value_type value_type;
519  typedef typename vector_type::const_reference reference;
520  typedef typename vector_type::const_reference const_reference;
521  typedef typename vector_type::const_pointer pointer;
522  typedef typename vector_type::const_pointer const_pointer;
523 
524 protected:
525  blocked_index_type offset;
526  const vector_type * p_vector;
527 
528 private:
529  const_vector_iterator(const vector_type * v, size_type o) : offset(o),
530  p_vector(v)
531  { }
532 
533 public:
534  const_vector_iterator() : offset(0), p_vector(NULL)
535  { }
536  const_vector_iterator(const _Self & a) :
537  offset(a.offset),
538  p_vector(a.p_vector)
539  { }
540 
541  const_vector_iterator(const iterator & a) :
542  offset(a.offset),
543  p_vector(a.p_vector)
544  { }
545 
546  block_offset_type block_offset() const
547  {
548  return static_cast<block_offset_type>(offset.get_offset());
549  }
550  bids_container_iterator bid() const
551  {
552  return ((vector_type *)p_vector)->bid(offset);
553  }
554 
555  difference_type operator - (const _Self & a) const
556  {
557  return offset - a.offset;
558  }
559 
560  difference_type operator - (const iterator & a) const
561  {
562  return offset - a.offset;
563  }
564 
565  _Self operator - (size_type op) const
566  {
567  return _Self(p_vector, offset.get_pos() - op);
568  }
569 
570  _Self operator + (size_type op) const
571  {
572  return _Self(p_vector, offset.get_pos() + op);
573  }
574 
575  _Self & operator -= (size_type op)
576  {
577  offset -= op;
578  return *this;
579  }
580 
581  _Self & operator += (size_type op)
582  {
583  offset += op;
584  return *this;
585  }
586 
587  const_reference operator * () const
588  {
589  return p_vector->const_element(offset);
590  }
591 
592  const_pointer operator -> () const
593  {
594  return &(p_vector->const_element(offset));
595  }
596 
597  const_reference operator [] (size_type op) const
598  {
599  return p_vector->const_element(offset.get_pos() + op);
600  }
601 
602  void block_externally_updated()
603  {
604  p_vector->block_externally_updated(offset);
605  }
606 
607  _STXXL_DEPRECATED(void touch())
608  {
609  block_externally_updated();
610  }
611 
612  _Self & operator ++ ()
613  {
614  offset++;
615  return *this;
616  }
617  _Self operator ++ (int)
618  {
619  _Self tmp_ = *this;
620  offset++;
621  return tmp_;
622  }
623  _Self & operator -- ()
624  {
625  offset--;
626  return *this;
627  }
628  _Self operator -- (int)
629  {
630  _Self __tmp = *this;
631  offset--;
632  return __tmp;
633  }
634  bool operator == (const _Self & a) const
635  {
636  assert(p_vector == a.p_vector);
637  return offset == a.offset; // or (offset + stxxl::int64(p_vector))
638  }
639  bool operator != (const _Self & a) const
640  {
641  assert(p_vector == a.p_vector);
642  return offset != a.offset;
643  }
644  bool operator < (const _Self & a) const
645  {
646  assert(p_vector == a.p_vector);
647  return offset < a.offset;
648  }
649  bool operator <= (const _Self & a) const
650  {
651  assert(p_vector == a.p_vector);
652  return offset <= a.offset;
653  }
654  bool operator > (const _Self & a) const
655  {
656  assert(p_vector == a.p_vector);
657  return offset > a.offset;
658  }
659  bool operator >= (const _Self & a) const
660  {
661  assert(p_vector == a.p_vector);
662  return offset >= a.offset;
663  }
664 
665  bool operator == (const iterator & a) const
666  {
667  assert(p_vector == a.p_vector);
668  return offset == a.offset; // or (offset + stxxl::int64(p_vector))
669  }
670  bool operator != (const iterator & a) const
671  {
672  assert(p_vector == a.p_vector);
673  return offset != a.offset;
674  }
675  bool operator < (const iterator & a) const
676  {
677  assert(p_vector == a.p_vector);
678  return offset < a.offset;
679  }
680  bool operator <= (const iterator & a) const
681  {
682  assert(p_vector == a.p_vector);
683  return offset <= a.offset;
684  }
685  bool operator > (const iterator & a) const
686  {
687  assert(p_vector == a.p_vector);
688  return offset > a.offset;
689  }
690  bool operator >= (const iterator & a) const
691  {
692  assert(p_vector == a.p_vector);
693  return offset >= a.offset;
694  }
695 
696  void flush()
697  {
698  p_vector->flush();
699  }
700 
701 #if 0
702  std::ostream & operator << (std::ostream & o) const
703  {
704  o << "vector pointer: " << ((void *)p_vector) << " offset: " << offset;
705  return o;
706  }
707 #endif
708 };
709 
710 
712 
725 template <
726  typename Tp_,
727  unsigned PgSz_ = 4,
728  typename PgTp_ = lru_pager<8>,
729  unsigned BlkSize_ = STXXL_DEFAULT_BLOCK_SIZE(Tp_),
730  typename AllocStr_ = STXXL_DEFAULT_ALLOC_STRATEGY,
731  typename SzTp_ = stxxl::uint64 // will be deprecated soon
732  >
733 class vector
734 {
735 public:
736  typedef Tp_ value_type;
737  typedef value_type & reference;
738  typedef const value_type & const_reference;
739  typedef value_type * pointer;
740  typedef SzTp_ size_type;
741  typedef stxxl::int64 difference_type;
742  typedef const value_type * const_pointer;
743 
744  typedef PgTp_ pager_type;
745  typedef AllocStr_ alloc_strategy_type;
746 
747  enum constants {
748  block_size = BlkSize_,
749  page_size = PgSz_,
750  n_pages = pager_type::n_pages,
751  on_disk = -1
752  };
753 
754  typedef vector_iterator<value_type, alloc_strategy_type, size_type,
755  difference_type, block_size, pager_type, page_size> iterator;
756  friend class vector_iterator<value_type, alloc_strategy_type, size_type, difference_type, block_size, pager_type, page_size>;
757  typedef const_vector_iterator<value_type, alloc_strategy_type,
758  size_type, difference_type, block_size, pager_type, page_size> const_iterator;
759  friend class const_vector_iterator<value_type, alloc_strategy_type, size_type, difference_type, block_size, pager_type, page_size>;
760  typedef std::reverse_iterator<iterator> reverse_iterator;
761  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
762 
763  typedef bid_vector<block_size> bids_container_type;
764  typedef typename bids_container_type::iterator bids_container_iterator;
765  typedef typename bids_container_type::const_iterator const_bids_container_iterator;
766 
767  typedef typed_block<BlkSize_, Tp_> block_type;
768  typedef double_blocked_index<SzTp_, PgSz_, block_type::size> blocked_index_type;
769 
770 private:
771  alloc_strategy_type alloc_strategy;
772  size_type _size;
773  bids_container_type _bids;
774  mutable pager_type pager;
775 
776  enum { valid_on_disk = 0, uninitialized = 1, dirty = 2 };
777  mutable std::vector<unsigned char> _page_status;
778  mutable std::vector<int_type> _page_to_slot;
779  mutable simple_vector<int_type> _slot_to_page;
780  mutable std::queue<int_type> _free_slots;
781  mutable simple_vector<block_type> * _cache;
782  file * _from;
783  block_manager * bm;
784  config * cfg;
785  bool exported;
786 
787  size_type size_from_file_length(stxxl::uint64 file_length) const
788  {
789  stxxl::uint64 blocks_fit = file_length / stxxl::uint64(block_type::raw_size);
790  size_type cur_size = blocks_fit * stxxl::uint64(block_type::size);
791  stxxl::uint64 rest = file_length - blocks_fit * stxxl::uint64(block_type::raw_size);
792  return (cur_size + rest / stxxl::uint64(sizeof(value_type)));
793  }
794 
795  stxxl::uint64 file_length() const
796  {
797  typedef stxxl::uint64 file_size_type;
798  size_type cur_size = size();
799  size_type num_full_blocks = cur_size / block_type::size;
800  if (cur_size % block_type::size != 0)
801  {
802  size_type rest = cur_size - num_full_blocks * block_type::size;
803  return file_size_type(num_full_blocks) * block_type::raw_size + rest * sizeof(value_type);
804  }
805  return file_size_type(num_full_blocks) * block_type::raw_size;
806  }
807 
808 public:
809  vector(size_type n = 0) :
810  _size(n),
811  _bids(div_ceil(n, block_type::size)),
812  _page_status(div_ceil(_bids.size(), page_size)),
813  _page_to_slot(div_ceil(_bids.size(), page_size)),
814  _slot_to_page(n_pages),
815  _cache(NULL),
816  _from(NULL),
817  exported(false)
818  {
819  bm = block_manager::get_instance();
820  cfg = config::get_instance();
821 
822  allocate_page_cache();
823  int_type all_pages = div_ceil(_bids.size(), page_size);
824  int_type i = 0;
825  for ( ; i < all_pages; ++i)
826  {
827  _page_status[i] = uninitialized;
828  _page_to_slot[i] = on_disk;
829  }
830 
831  for (i = 0; i < n_pages; ++i)
832  _free_slots.push(i);
833 
834  bm->new_blocks(alloc_strategy, _bids.begin(), _bids.end(), 0);
835  }
836 
837  void swap(vector & obj)
838  {
839  std::swap(alloc_strategy, obj.alloc_strategy);
840  std::swap(_size, obj._size);
841  std::swap(_bids, obj._bids);
842  std::swap(pager, obj.pager);
843  std::swap(_page_status, obj._page_status);
844  std::swap(_page_to_slot, obj._page_to_slot);
845  std::swap(_slot_to_page, obj._slot_to_page);
846  std::swap(_free_slots, obj._free_slots);
847  std::swap(_cache, obj._cache);
848  std::swap(_from, obj._from);
849  std::swap(exported, obj.exported);
850  }
851 
852  void allocate_page_cache() const
853  {
854  if (!_cache)
855  _cache = new simple_vector<block_type>(n_pages * page_size);
856  }
857 
858  // allows to free the cache, but you may not access any element until call allocate_pacge_cache() again
859  void deallocate_page_cache() const
860  {
861  flush();
862  delete _cache;
863  _cache = NULL;
864  }
865 
866  size_type capacity() const
867  {
868  return size_type(_bids.size()) * block_type::size;
869  }
871  size_type raw_capacity() const
872  {
873  return size_type(_bids.size()) * block_type::raw_size;
874  }
875 
876  void reserve(size_type n)
877  {
878  if (n <= capacity())
879  return;
880 
881  unsigned_type old_bids_size = _bids.size();
882  unsigned_type new_bids_size = div_ceil(n, block_type::size);
883  unsigned_type new_pages = div_ceil(new_bids_size, page_size);
884  _page_status.resize(new_pages, uninitialized);
885  _page_to_slot.resize(new_pages, on_disk);
886 
887  _bids.resize(new_bids_size);
888  if (_from == NULL)
889  {
890  bm->new_blocks(alloc_strategy, _bids.begin() + old_bids_size, _bids.end(), old_bids_size);
891  }
892  else
893  {
894  size_type offset = size_type(old_bids_size) * size_type(block_type::raw_size);
895  bids_container_iterator it = _bids.begin() + old_bids_size;
896  for ( ; it != _bids.end(); ++it, offset += size_type(block_type::raw_size))
897  {
898  (*it).storage = _from;
899  (*it).offset = offset;
900  }
901  STXXL_VERBOSE1("vector::reserve(): Changing size of file " << ((void *)_from) << " to "
902  << offset);
903  _from->set_size(offset);
904  }
905  }
906 
907  void resize(size_type n)
908  {
909  _resize(n);
910  }
911 
912  void resize(size_type n, bool shrink_capacity)
913  {
914  if (shrink_capacity)
915  _resize_shrink_capacity(n);
916  else
917  _resize(n);
918  }
919 
920 private:
921  void _resize(size_type n)
922  {
923  reserve(n);
924  if (n < _size) {
925  // mark excess pages as uninitialized and evict them from cache
926  unsigned_type first_page_to_evict = div_ceil(n, block_type::size * page_size);
927  for (unsigned_type i = first_page_to_evict; i < _page_status.size(); ++i) {
928  if (_page_to_slot[i] != on_disk) {
929  _free_slots.push(_page_to_slot[i]);
930  _page_to_slot[i] = on_disk;
931  }
932  _page_status[i] = uninitialized;
933  }
934  }
935  _size = n;
936  }
937 
938  void _resize_shrink_capacity(size_type n)
939  {
940  unsigned_type old_bids_size = _bids.size();
941  unsigned_type new_bids_size = div_ceil(n, block_type::size);
942 
943  if (new_bids_size > old_bids_size)
944  {
945  reserve(n);
946  }
947  else if (new_bids_size < old_bids_size)
948  {
949  if (_from != NULL)
950  _from->set_size(new_bids_size * block_type::raw_size);
951  else
952  bm->delete_blocks(_bids.begin() + old_bids_size, _bids.end());
953 
954  _bids.resize(new_bids_size);
955  unsigned_type new_pages = div_ceil(new_bids_size, page_size);
956  _page_status.resize(new_pages);
957 
958  unsigned_type first_page_to_evict = div_ceil(new_bids_size, page_size);
959  // clear dirty flag, so these pages will be never written
960  std::fill(_page_status.begin() + first_page_to_evict,
961  _page_status.end(), (unsigned char)valid_on_disk);
962  }
963 
964  _size = n;
965  }
966 
967 public:
968  void clear()
969  {
970  _size = 0;
971  if (_from == NULL)
972  bm->delete_blocks(_bids.begin(), _bids.end());
973 
974  _bids.clear();
975  _page_status.clear();
976  _page_to_slot.clear();
977  while (!_free_slots.empty())
978  _free_slots.pop();
979 
980 
981  for (int_type i = 0; i < n_pages; ++i)
982  _free_slots.push(i);
983  }
984 
985  void push_back(const_reference obj)
986  {
987  size_type old_size = _size;
988  resize(old_size + 1);
989  element(old_size) = obj;
990  }
991  void pop_back()
992  {
993  resize(_size - 1);
994  }
995 
996  reference back()
997  {
998  return element(_size - 1);
999  }
1000  reference front()
1001  {
1002  return element(0);
1003  }
1004  const_reference back() const
1005  {
1006  return const_element(_size - 1);
1007  }
1008  const_reference front() const
1009  {
1010  return const_element(0);
1011  }
1012 
1018  vector(file * from, size_type size = size_type(-1)) :
1019  _size((size == size_type(-1)) ? size_from_file_length(from->size()) : size),
1020  _bids(div_ceil(_size, size_type(block_type::size))),
1021  _page_status(div_ceil(_bids.size(), page_size)),
1022  _page_to_slot(div_ceil(_bids.size(), page_size)),
1023  _slot_to_page(n_pages),
1024  _cache(NULL),
1025  _from(from),
1026  exported(false)
1027  {
1028  // initialize from file
1030  {
1031  std::ostringstream str_;
1032  str_ << "The block size for a vector that is mapped to a file must be a multiple of the element size (" <<
1033  sizeof(value_type) << ") and the page size (4096).";
1034  throw std::runtime_error(str_.str());
1035  }
1036 
1037  bm = block_manager::get_instance();
1038  cfg = config::get_instance();
1039 
1040  allocate_page_cache();
1041  int_type all_pages = div_ceil(_bids.size(), page_size);
1042  int_type i = 0;
1043  for ( ; i < all_pages; ++i)
1044  {
1045  _page_status[i] = valid_on_disk;
1046  _page_to_slot[i] = on_disk;
1047  }
1048 
1049  for (i = 0; i < n_pages; ++i)
1050  _free_slots.push(i);
1051 
1052 
1053  //allocate blocks equidistantly and in-order
1054  size_type offset = 0;
1055  bids_container_iterator it = _bids.begin();
1056  for ( ; it != _bids.end(); ++it, offset += size_type(block_type::raw_size))
1057  {
1058  (*it).storage = from;
1059  (*it).offset = offset;
1060  }
1061  from->set_size(offset);
1062  }
1063 
1064  vector(const vector & obj) :
1065  _size(obj.size()),
1066  _bids(div_ceil(obj.size(), block_type::size)),
1067  _page_status(div_ceil(_bids.size(), page_size)),
1068  _page_to_slot(div_ceil(_bids.size(), page_size)),
1069  _slot_to_page(n_pages),
1070  _cache(NULL),
1071  _from(NULL),
1072  exported(false)
1073  {
1074  assert(!obj.exported);
1075  bm = block_manager::get_instance();
1076  cfg = config::get_instance();
1077 
1078  allocate_page_cache();
1079  int_type all_pages = div_ceil(_bids.size(), page_size);
1080  int_type i = 0;
1081  for ( ; i < all_pages; ++i)
1082  {
1083  _page_status[i] = uninitialized;
1084  _page_to_slot[i] = on_disk;
1085  }
1086 
1087  for (i = 0; i < n_pages; ++i)
1088  _free_slots.push(i);
1089 
1090  bm->new_blocks(alloc_strategy, _bids.begin(), _bids.end(), 0);
1091 
1092  const_iterator inbegin = obj.begin();
1093  const_iterator inend = obj.end();
1094  std::copy(inbegin, inend, begin());
1095  }
1096 
1097  vector & operator = (const vector & obj)
1098  {
1099  if (&obj != this)
1100  {
1101  vector tmp(obj);
1102  this->swap(tmp);
1103  }
1104  return *this;
1105  }
1106 
1107  size_type size() const
1108  {
1109  return _size;
1110  }
1111  bool empty() const
1112  {
1113  return (!_size);
1114  }
1115  iterator begin()
1116  {
1117  return iterator(this, 0);
1118  }
1119  const_iterator begin() const
1120  {
1121  return const_iterator(this, 0);
1122  }
1123  const_iterator cbegin() const
1124  {
1125  return begin();
1126  }
1127  iterator end()
1128  {
1129  return iterator(this, _size);
1130  }
1131  const_iterator end() const
1132  {
1133  return const_iterator(this, _size);
1134  }
1135  const_iterator cend() const
1136  {
1137  return end();
1138  }
1139 
1140  reverse_iterator rbegin()
1141  {
1142  return reverse_iterator(end());
1143  }
1144  const_reverse_iterator rbegin() const
1145  {
1146  return const_reverse_iterator(end());
1147  }
1148  const_reverse_iterator crbegin() const
1149  {
1150  return const_reverse_iterator(end());
1151  }
1152  reverse_iterator rend()
1153  {
1154  return reverse_iterator(begin());
1155  }
1156  const_reverse_iterator rend() const
1157  {
1158  return const_reverse_iterator(begin());
1159  }
1160  const_reverse_iterator crend() const
1161  {
1162  return const_reverse_iterator(begin());
1163  }
1164 
1165  reference operator [] (size_type offset)
1166  {
1167  return element(offset);
1168  }
1169  const_reference operator [] (size_type offset) const
1170  {
1171  return const_element(offset);
1172  }
1173 
1174  bool is_element_cached(size_type offset) const
1175  {
1176  return is_page_cached(blocked_index_type(offset));
1177  }
1178 
1179  void flush() const
1180  {
1181  simple_vector<bool> non_free_slots(n_pages);
1182  int_type i = 0;
1183  for ( ; i < n_pages; i++)
1184  non_free_slots[i] = true;
1185 
1186  while (!_free_slots.empty())
1187  {
1188  non_free_slots[_free_slots.front()] = false;
1189  _free_slots.pop();
1190  }
1191 
1192  for (i = 0; i < n_pages; i++)
1193  {
1194  _free_slots.push(i);
1195  int_type page_no = _slot_to_page[i];
1196  if (non_free_slots[i])
1197  {
1198  STXXL_VERBOSE1("vector: flushing page " << i << " at address "
1199  << (int64(page_no) * int64(block_type::size) * int64(page_size)));
1200  write_page(page_no, i);
1201 
1202  _page_to_slot[page_no] = on_disk;
1203  }
1204  }
1205  }
1206 
1207  ~vector()
1208  {
1209  STXXL_VERBOSE("~vector()");
1210  try
1211  {
1212  flush();
1213  }
1214  catch (io_error e)
1215  {
1216  STXXL_ERRMSG("io_error thrown in ~vector(): " << e.what());
1217  }
1218  catch (...)
1219  {
1220  STXXL_ERRMSG("Exception thrown in ~vector()");
1221  }
1222 
1223  if (!exported)
1224  {
1225  if (_from == NULL)
1226  bm->delete_blocks(_bids.begin(), _bids.end());
1227  else // file must be truncated
1228  {
1229  STXXL_VERBOSE1("~vector(): Changing size of file " << ((void *)_from) << " to "
1230  << file_length());
1231  STXXL_VERBOSE1("~vector(): size of the vector is " << size());
1232  try
1233  {
1234  _from->set_size(file_length());
1235  }
1236  catch (...)
1237  {
1238  STXXL_ERRMSG("Exception thrown in ~vector()...set_size()");
1239  }
1240  }
1241  }
1242  delete _cache;
1243  }
1244 
1247  void export_files(std::string filename_prefix)
1248  {
1249  int64 no = 0;
1250  for (bids_container_iterator i = _bids.begin(); i != _bids.end(); ++i) {
1251  std::ostringstream number;
1252  number << std::setw(9) << std::setfill('0') << no;
1253  size_type current_block_size =
1254  ((i + 1) == _bids.end() && _size % block_type::size > 0) ?
1255  (_size % block_type::size) * sizeof(value_type) :
1256  block_type::size * sizeof(value_type);
1257  (*i).storage->export_files((*i).offset, current_block_size, filename_prefix + number.str());
1258  ++no;
1259  }
1260  exported = true;
1261  }
1262 
1264  file * get_file() const
1265  {
1266  return _from;
1267  }
1268 
1271  template <typename ForwardIterator>
1272  void set_content(const ForwardIterator & bid_begin, const ForwardIterator & bid_end, size_type n)
1273  {
1274  unsigned_type new_bids_size = div_ceil(n, block_type::size);
1275  _bids.resize(new_bids_size);
1276  std::copy(bid_begin, bid_end, _bids.begin());
1277  unsigned_type new_pages = div_ceil(new_bids_size, page_size);
1278  _page_status.resize(new_pages, valid_on_disk);
1279  _page_to_slot.resize(new_pages, on_disk);
1280  _size = n;
1281  }
1282 
1283 private:
1284  bids_container_iterator bid(const size_type & offset)
1285  {
1286  return (_bids.begin() +
1287  static_cast<typename bids_container_type::size_type>
1288  (offset / block_type::size));
1289  }
1290  bids_container_iterator bid(const blocked_index_type & offset)
1291  {
1292  return (_bids.begin() +
1293  static_cast<typename bids_container_type::size_type>
1294  (offset.get_block2() * PgSz_ + offset.get_block1()));
1295  }
1296  const_bids_container_iterator bid(const size_type & offset) const
1297  {
1298  return (_bids.begin() +
1299  static_cast<typename bids_container_type::size_type>
1300  (offset / block_type::size));
1301  }
1302  const_bids_container_iterator bid(const blocked_index_type & offset) const
1303  {
1304  return (_bids.begin() +
1305  static_cast<typename bids_container_type::size_type>
1306  (offset.get_block2() * PgSz_ + offset.get_block1()));
1307  }
1308 
1309  void read_page(int_type page_no, int_type cache_slot) const
1310  {
1311  if (_page_status[page_no] == uninitialized)
1312  return;
1313  STXXL_VERBOSE1("vector " << this << ": reading page_no=" << page_no << " cache_slot=" << cache_slot);
1314  request_ptr * reqs = new request_ptr[page_size];
1315  int_type block_no = page_no * page_size;
1316  int_type last_block = STXXL_MIN(block_no + page_size, int_type(_bids.size()));
1317  int_type i = cache_slot * page_size, j = 0;
1318  for ( ; block_no < last_block; ++block_no, ++i, ++j)
1319  {
1320  reqs[j] = (*_cache)[i].read(_bids[block_no]);
1321  }
1322  assert(last_block - page_no * page_size > 0);
1323  wait_all(reqs, last_block - page_no * page_size);
1324  delete[] reqs;
1325  }
1326  void write_page(int_type page_no, int_type cache_slot) const
1327  {
1328  if (!(_page_status[page_no] & dirty))
1329  return;
1330  STXXL_VERBOSE1("vector " << this << ": writing page_no=" << page_no << " cache_slot=" << cache_slot);
1331  request_ptr * reqs = new request_ptr[page_size];
1332  int_type block_no = page_no * page_size;
1333  int_type last_block = STXXL_MIN(block_no + page_size, int_type(_bids.size()));
1334  int_type i = cache_slot * page_size, j = 0;
1335  for ( ; block_no < last_block; ++block_no, ++i, ++j)
1336  {
1337  reqs[j] = (*_cache)[i].write(_bids[block_no]);
1338  }
1339  _page_status[page_no] = valid_on_disk;
1340  assert(last_block - page_no * page_size > 0);
1341  wait_all(reqs, last_block - page_no * page_size);
1342  delete[] reqs;
1343  }
1344 
1345  reference element(size_type offset)
1346  {
1347  #ifdef STXXL_RANGE_CHECK
1348  assert(offset < size());
1349  #endif
1350  return element(blocked_index_type(offset));
1351  }
1352 
1353  reference element(const blocked_index_type & offset)
1354  {
1355  #ifdef STXXL_RANGE_CHECK
1356  assert(offset.get_pos() < size());
1357  #endif
1358  int_type page_no = offset.get_block2();
1359  assert(page_no < int_type(_page_to_slot.size())); // fails if offset is too large, out of bound access
1360  int_type cache_slot = _page_to_slot[page_no];
1361  if (cache_slot < 0) // == on_disk
1362  {
1363  if (_free_slots.empty()) // has to kick
1364  {
1365  int_type kicked_slot = pager.kick();
1366  pager.hit(kicked_slot);
1367  int_type old_page_no = _slot_to_page[kicked_slot];
1368  _page_to_slot[page_no] = kicked_slot;
1369  _page_to_slot[old_page_no] = on_disk;
1370  _slot_to_page[kicked_slot] = page_no;
1371 
1372  write_page(old_page_no, kicked_slot);
1373  read_page(page_no, kicked_slot);
1374 
1375  _page_status[page_no] = dirty;
1376 
1377  return (*_cache)[kicked_slot * page_size + offset.get_block1()][offset.get_offset()];
1378  }
1379  else
1380  {
1381  int_type free_slot = _free_slots.front();
1382  _free_slots.pop();
1383  pager.hit(free_slot);
1384  _page_to_slot[page_no] = free_slot;
1385  _slot_to_page[free_slot] = page_no;
1386 
1387  read_page(page_no, free_slot);
1388 
1389  _page_status[page_no] = dirty;
1390 
1391  return (*_cache)[free_slot * page_size + offset.get_block1()][offset.get_offset()];
1392  }
1393  }
1394  else
1395  {
1396  _page_status[page_no] = dirty;
1397  pager.hit(cache_slot);
1398  return (*_cache)[cache_slot * page_size + offset.get_block1()][offset.get_offset()];
1399  }
1400  }
1401 
1402  // don't forget to first flush() the vector's cache before updating pages externally
1403  void page_externally_updated(unsigned_type page_no) const
1404  {
1405  // fails if offset is too large, out of bound access
1406  assert(page_no < _page_status.size());
1407  // "A dirty page has been marked as newly initialized. The page content will be lost."
1408  assert(!(_page_status[page_no] & dirty));
1409  if (_page_to_slot[page_no] != on_disk) {
1410  // remove page from cache
1411  _free_slots.push(_page_to_slot[page_no]);
1412  _page_to_slot[page_no] = on_disk;
1413  }
1414  _page_status[page_no] = valid_on_disk;
1415  }
1416 
1417  void block_externally_updated(size_type offset) const
1418  {
1419  page_externally_updated(offset / (block_type::size * page_size));
1420  }
1421 
1422  void block_externally_updated(const blocked_index_type & offset) const
1423  {
1424  page_externally_updated(offset.get_block2());
1425  }
1426 
1427  _STXXL_DEPRECATED(void touch(size_type offset) const)
1428  {
1429  page_externally_updated(offset / (block_type::size * page_size));
1430  }
1431 
1432  _STXXL_DEPRECATED(void touch(const blocked_index_type & offset) const)
1433  {
1434  page_externally_updated(offset.get_block2());
1435  }
1436 
1437  const_reference const_element(size_type offset) const
1438  {
1439  return const_element(blocked_index_type(offset));
1440  }
1441 
1442  const_reference const_element(const blocked_index_type & offset) const
1443  {
1444  int_type page_no = offset.get_block2();
1445  assert(page_no < int_type(_page_to_slot.size())); // fails if offset is too large, out of bound access
1446  int_type cache_slot = _page_to_slot[page_no];
1447  if (cache_slot < 0) // == on_disk
1448  {
1449  if (_free_slots.empty()) // has to kick
1450  {
1451  int_type kicked_slot = pager.kick();
1452  pager.hit(kicked_slot);
1453  int_type old_page_no = _slot_to_page[kicked_slot];
1454  _page_to_slot[page_no] = kicked_slot;
1455  _page_to_slot[old_page_no] = on_disk;
1456  _slot_to_page[kicked_slot] = page_no;
1457 
1458  write_page(old_page_no, kicked_slot);
1459  read_page(page_no, kicked_slot);
1460 
1461  return (*_cache)[kicked_slot * page_size + offset.get_block1()][offset.get_offset()];
1462  }
1463  else
1464  {
1465  int_type free_slot = _free_slots.front();
1466  _free_slots.pop();
1467  pager.hit(free_slot);
1468  _page_to_slot[page_no] = free_slot;
1469  _slot_to_page[free_slot] = page_no;
1470 
1471  read_page(page_no, free_slot);
1472 
1473  return (*_cache)[free_slot * page_size + offset.get_block1()][offset.get_offset()];
1474  }
1475  }
1476  else
1477  {
1478  pager.hit(cache_slot);
1479  return (*_cache)[cache_slot * page_size + offset.get_block1()][offset.get_offset()];
1480  }
1481  }
1482 
1483  bool is_page_cached(const blocked_index_type & offset) const
1484  {
1485  int_type page_no = offset.get_block2();
1486  assert(page_no < int_type(_page_to_slot.size())); // fails if offset is too large, out of bound access
1487  int_type cache_slot = _page_to_slot[page_no];
1488  return (cache_slot >= 0); // on_disk == -1
1489  }
1490 };
1491 
1492 template <
1493  typename Tp_,
1494  unsigned PgSz_,
1495  typename PgTp_,
1496  unsigned BlkSize_,
1497  typename AllocStr_,
1498  typename SzTp_>
1499 inline bool operator == (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1500  AllocStr_, SzTp_> & a,
1501  stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1502  AllocStr_, SzTp_> & b)
1503 {
1504  return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
1505 }
1506 
1507 template <
1508  typename Tp_,
1509  unsigned PgSz_,
1510  typename PgTp_,
1511  unsigned BlkSize_,
1512  typename AllocStr_,
1513  typename SzTp_>
1514 inline bool operator != (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1515  AllocStr_, SzTp_> & a,
1516  stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1517  AllocStr_, SzTp_> & b)
1518 {
1519  return !(a == b);
1520 }
1521 
1522 template <
1523  typename Tp_,
1524  unsigned PgSz_,
1525  typename PgTp_,
1526  unsigned BlkSize_,
1527  typename AllocStr_,
1528  typename SzTp_>
1529 inline bool operator < (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1530  AllocStr_, SzTp_> & a,
1531  stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1532  AllocStr_, SzTp_> & b)
1533 {
1534  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
1535 }
1536 
1537 template <
1538  typename Tp_,
1539  unsigned PgSz_,
1540  typename PgTp_,
1541  unsigned BlkSize_,
1542  typename AllocStr_,
1543  typename SzTp_>
1544 inline bool operator > (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1545  AllocStr_, SzTp_> & a,
1546  stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1547  AllocStr_, SzTp_> & b)
1548 {
1549  return b < a;
1550 }
1551 
1552 template <
1553  typename Tp_,
1554  unsigned PgSz_,
1555  typename PgTp_,
1556  unsigned BlkSize_,
1557  typename AllocStr_,
1558  typename SzTp_>
1559 inline bool operator <= (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1560  AllocStr_, SzTp_> & a,
1561  stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1562  AllocStr_, SzTp_> & b)
1563 {
1564  return !(b < a);
1565 }
1566 
1567 template <
1568  typename Tp_,
1569  unsigned PgSz_,
1570  typename PgTp_,
1571  unsigned BlkSize_,
1572  typename AllocStr_,
1573  typename SzTp_>
1574 inline bool operator >= (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1575  AllocStr_, SzTp_> & a,
1576  stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
1577  AllocStr_, SzTp_> & b)
1578 {
1579  return !(a < b);
1580 }
1581 
1583 
1585 
1586 // specialization for stxxl::vector, to use only const_iterators
1587 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
1588  unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
1589 bool is_sorted(
1590  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> __first,
1591  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> __last)
1592 {
1593  return is_sorted_helper(
1594  stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>(__first),
1595  stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>(__last));
1596 }
1597 
1598 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
1599  unsigned BlkSize_, typename PgTp_, unsigned PgSz_, typename _StrictWeakOrdering>
1600 bool is_sorted(
1601  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> __first,
1602  stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> __last,
1603  _StrictWeakOrdering __comp)
1604 {
1605  return is_sorted_helper(
1606  stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>(__first),
1607  stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>(__last),
1608  __comp);
1609 }
1610 
1612 
1615 
1617 
1639 template <
1640  typename Tp_,
1641  unsigned PgSz_ = 4,
1642  unsigned Pages_ = 8,
1643  unsigned BlkSize_ = STXXL_DEFAULT_BLOCK_SIZE(Tp_),
1644  typename AllocStr_ = STXXL_DEFAULT_ALLOC_STRATEGY,
1645  pager_type Pager_ = lru
1646  >
1648 {
1649  typedef typename IF<Pager_ == lru,
1651 
1653 };
1654 
1655 
1657 
1658 __STXXL_END_NAMESPACE
1659 
1660 
1661 namespace std
1662 {
1663  template <
1664  typename Tp_,
1665  unsigned PgSz_,
1666  typename PgTp_,
1667  unsigned BlkSize_,
1668  typename AllocStr_,
1669  typename SzTp_>
1670  void swap(stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_> & a,
1671  stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_> & b)
1672  {
1673  a.swap(b);
1674  }
1675 }
1676 
1677 #endif // !STXXL_VECTOR_HEADER
1678 // vim: et:ts=4:sw=4
virtual void set_size(offset_type newsize)=0
Changes the size of the file.
Defines interface of file.
Definition: file.h:90
file * get_file() const
Get the file associated with this vector, or NULL.
Definition: vector.h:1264
Block containing elements of fixed length.
Definition: typed_block.h:223
size of block in bytes
Definition: typed_block.h:239
number of elements in block
Definition: typed_block.h:240
no meta info, bids or (non-empty) fillers included in the block, allows value_type array addressing a...
Definition: typed_block.h:241
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:1272
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:1247
void delete_blocks(const BIDIteratorClass &bidbegin, const BIDIteratorClass &bidend)
Deallocates blocks.
Definition: mng.h:218
Pager with random replacement strategy.
Definition: pager.h:38
External vector container.
Definition: vector.h:259
void new_blocks(const DiskAssignFunctor &functor, BIDIteratorClass bidbegin, BIDIteratorClass bidend, unsigned_type offset=0)
Allocates new blocks.
Definition: mng.h:90
Implemented as reference counting smart pointer.
Definition: request_ptr.h:34
void wait_all(request_iterator_ reqs_begin, request_iterator_ reqs_end)
Collection of functions to track statuses of a number of requests.
Definition: request_operations.h:36
size_type raw_capacity() const
Returns the number of bytes that the vector has allocated on disks.
Definition: vector.h:871
Pager with LRU replacement strategy.
Definition: pager.h:58
vector(file *from, size_type size=size_type(-1))
Construct vector from a file.
Definition: vector.h:1018
Const external vector iterator, model of ext_random_access_iterator concept.
Definition: vector.h:264
Block manager class.
Definition: mng.h:59
IF template metaprogramming statement.
Definition: tmeta.h:31
External vector type generator.
Definition: vector.h:1647
Access point to disks properties.
Definition: config.h:31
External vector iterator, model of ext_random_access_iterator concept.
Definition: vector.h:270