00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef STXXL_VECTOR_HEADER
00015 #define STXXL_VECTOR_HEADER
00016
00017 #include <vector>
00018 #include <queue>
00019 #include <algorithm>
00020
00021 #include <stxxl/bits/mng/mng.h>
00022 #include <stxxl/bits/mng/typed_block.h>
00023 #include <stxxl/bits/common/tmeta.h>
00024 #include <stxxl/bits/containers/pager.h>
00025 #include <stxxl/bits/common/is_sorted.h>
00026
00027
00028 __STXXL_BEGIN_NAMESPACE
00029
00033
00034
00038
00039 template <typename size_type, size_type modulo2, size_type modulo1>
00040 class double_blocked_index
00041 {
00042 static const size_type modulo12 = modulo1 * modulo2;
00043
00044 size_type pos, block1, block2, offset;
00045
00047
00048 void set(size_type pos)
00049 {
00050 this->pos = pos;
00051 block2 = pos / modulo12;
00052 pos -= block2 * modulo12;
00053 block1 = pos / modulo1;
00054 offset = (pos - block1 * modulo1);
00055
00056 assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
00057 assert( block1 < modulo2);
00058 assert( offset < modulo1);
00059 }
00060
00061 public:
00062 double_blocked_index()
00063 {
00064 set(0);
00065 }
00066
00067 double_blocked_index(size_type pos)
00068 {
00069 set(pos);
00070 }
00071
00072 double_blocked_index(size_type block2, size_type block1, size_type offset)
00073 {
00074 assert( block1 < modulo2);
00075 assert( offset < modulo1);
00076
00077 this->block2 = block2;
00078 this->block1 = block1;
00079 this->offset = offset;
00080 pos = block2 * modulo12 + block1 * modulo1 + offset;
00081 }
00082
00083 double_blocked_index & operator = (size_type pos)
00084 {
00085 set(pos);
00086 return *this;
00087 }
00088
00089
00090 double_blocked_index & operator ++ ()
00091 {
00092 ++pos;
00093 ++offset;
00094 if (offset == modulo1)
00095 {
00096 offset = 0;
00097 ++block1;
00098 if (block1 == modulo2)
00099 {
00100 block1 = 0;
00101 ++block2;
00102 }
00103 }
00104
00105 assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
00106 assert( block1 < modulo2);
00107 assert( offset < modulo1);
00108
00109 return *this;
00110 }
00111
00112
00113 double_blocked_index operator ++ (int)
00114 {
00115 double_blocked_index former(*this);
00116 operator ++ ();
00117 return former;
00118 }
00119
00120
00121 double_blocked_index & operator -- ()
00122 {
00123 --pos;
00124 if (offset == 0)
00125 {
00126 offset = modulo1;
00127 if (block1 == 0)
00128 {
00129 block1 = modulo2;
00130 --block2;
00131 }
00132 --block1;
00133 }
00134 --offset;
00135
00136 assert(block2 * modulo12 + block1 * modulo1 + offset == this->pos);
00137 assert( block1 < modulo2);
00138 assert( offset < modulo1);
00139
00140 return *this;
00141 }
00142
00143
00144 double_blocked_index operator -- (int)
00145 {
00146 double_blocked_index former(*this);
00147 operator -- ();
00148 return former;
00149 }
00150
00151 double_blocked_index operator + (size_type addend) const
00152 {
00153 return double_blocked_index(pos + addend);
00154 }
00155
00156 double_blocked_index & operator += (size_type addend)
00157 {
00158 set(pos + addend);
00159 return *this;
00160 }
00161
00162 double_blocked_index operator - (size_type addend) const
00163 {
00164 return double_blocked_index(pos - addend);
00165 }
00166
00167 size_type operator - (const double_blocked_index & dbi2) const
00168 {
00169 return pos - dbi2.pos;
00170 }
00171
00172 double_blocked_index & operator -= (size_type subtrahend)
00173 {
00174 set(pos - subtrahend);
00175 return *this;
00176 }
00177
00178 bool operator == (const double_blocked_index & dbi2) const
00179 {
00180 return pos == dbi2.pos;
00181 }
00182
00183 bool operator != (const double_blocked_index & dbi2) const
00184 {
00185 return pos != dbi2.pos;
00186 }
00187
00188 bool operator < (const double_blocked_index & dbi2) const
00189 {
00190 return pos < dbi2.pos;
00191 }
00192
00193 bool operator <= (const double_blocked_index & dbi2) const
00194 {
00195 return pos <= dbi2.pos;
00196 }
00197
00198 bool operator > (const double_blocked_index & dbi2) const
00199 {
00200 return pos > dbi2.pos;
00201 }
00202
00203 bool operator >= (const double_blocked_index & dbi2) const
00204 {
00205 return pos >= dbi2.pos;
00206 }
00207
00208 double_blocked_index & operator >>= (size_type shift)
00209 {
00210 set(pos >> shift);
00211 return *this;
00212 }
00213
00214 size_type get_pos() const
00215 {
00216 return pos;
00217 }
00218
00219 const size_type & get_block2() const
00220 {
00221 return block2;
00222 }
00223
00224 const size_type & get_block1() const
00225 {
00226 return block1;
00227 }
00228
00229 const size_type & get_offset() const
00230 {
00231 return offset;
00232 }
00233 };
00234
00235
00236 template <unsigned BlkSize_>
00237 class bid_vector : public std::vector<BID<BlkSize_> >
00238 {
00239 public:
00240 enum
00241 { block_size = BlkSize_ };
00242 typedef bid_vector<block_size> _Self;
00243 typedef std::vector<BID<BlkSize_> > _Derived;
00244 typedef unsigned size_type;
00245
00246 bid_vector(size_type _sz) : _Derived(_sz)
00247 { }
00248 };
00249
00250
00251 template <
00252 typename Tp_,
00253 unsigned PgSz_,
00254 typename PgTp_,
00255 unsigned BlkSize_,
00256 typename AllocStr_,
00257 typename SzTp_>
00258 class vector;
00259
00260
00261 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00262 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00263 class const_vector_iterator;
00264
00265
00267 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00268 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00269 class vector_iterator
00270 {
00271 typedef vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_,
00272 BlkSize_, PgTp_, PgSz_> _Self;
00273 typedef const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_,
00274 BlkSize_, PgTp_, PgSz_> _CIterator;
00275
00276 friend class const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>;
00277
00278 public:
00279 typedef _CIterator const_iterator;
00280 typedef _Self iterator;
00281
00282 typedef SzTp_ size_type;
00283 typedef DiffTp_ difference_type;
00284 typedef unsigned block_offset_type;
00285 typedef vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_> vector_type;
00286 friend class vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_>;
00287 typedef bid_vector<BlkSize_> bids_container_type;
00288 typedef typename bids_container_type::iterator bids_container_iterator;
00289 typedef typed_block<BlkSize_, Tp_> block_type;
00290 typedef BID<BlkSize_> bid_type;
00291
00292 typedef std::random_access_iterator_tag iterator_category;
00293 typedef typename vector_type::value_type value_type;
00294 typedef typename vector_type::reference reference;
00295 typedef typename vector_type::const_reference const_reference;
00296 typedef typename vector_type::pointer pointer;
00297 typedef typename vector_type::const_pointer const_pointer;
00298
00299 enum { block_size = BlkSize_ };
00300
00301 protected:
00302 double_blocked_index<SzTp_, PgSz_, block_type::size> offset;
00303 vector_type * p_vector;
00304
00305 private:
00306 vector_iterator(vector_type * v, size_type o) : offset(o),
00307 p_vector(v)
00308 { }
00309
00310 public:
00311 vector_iterator() : offset(0), p_vector(NULL) { }
00312 vector_iterator(const _Self & a) :
00313 offset(a.offset),
00314 p_vector(a.p_vector) { }
00315
00316 block_offset_type block_offset() const
00317 {
00318 return static_cast<block_offset_type>(offset.get_offset());
00319 }
00320 bids_container_iterator bid() const
00321 {
00322 return p_vector->bid(offset);
00323 }
00324
00325 difference_type operator - (const _Self & a) const
00326 {
00327 return offset - a.offset;
00328 }
00329
00330 difference_type operator - (const const_iterator & a) const
00331 {
00332 return offset - a.offset;
00333 }
00334
00335 _Self operator - (size_type op) const
00336 {
00337 return _Self(p_vector, offset.get_pos() - op);
00338 }
00339
00340 _Self operator + (size_type op) const
00341 {
00342 return _Self(p_vector, offset.get_pos() + op);
00343 }
00344
00345 _Self & operator -= (size_type op)
00346 {
00347 offset -= op;
00348 return *this;
00349 }
00350
00351 _Self & operator += (size_type op)
00352 {
00353 offset += op;
00354 return *this;
00355 }
00356
00357 reference operator * ()
00358 {
00359 return p_vector->element(offset);
00360 }
00361
00362 pointer operator -> ()
00363 {
00364 return &(p_vector->element(offset));
00365 }
00366
00367 const_reference operator * () const
00368 {
00369 return p_vector->const_element(offset);
00370 }
00371
00372 const_pointer operator -> () const
00373 {
00374 return &(p_vector->const_element(offset));
00375 }
00376
00377 reference operator [] (size_type op)
00378 {
00379 return p_vector->element(offset.get_pos() + op);
00380 }
00381
00382 const_reference operator [] (size_type op) const
00383 {
00384 return p_vector->const_element(offset.get_pos() + op);
00385 }
00386
00387 void block_externally_updated()
00388 {
00389 p_vector->block_externally_updated(offset);
00390 }
00391
00392 _STXXL_DEPRECATED(void touch())
00393 {
00394 block_externally_updated();
00395 }
00396
00397 _Self & operator ++ ()
00398 {
00399 offset++;
00400 return *this;
00401 }
00402 _Self operator ++ (int)
00403 {
00404 _Self __tmp = *this;
00405 offset++;
00406 return __tmp;
00407 }
00408 _Self & operator -- ()
00409 {
00410 offset--;
00411 return *this;
00412 }
00413 _Self operator -- (int)
00414 {
00415 _Self __tmp = *this;
00416 offset--;
00417 return __tmp;
00418 }
00419 bool operator == (const _Self & a) const
00420 {
00421 assert(p_vector == a.p_vector);
00422 return offset == a.offset;
00423 }
00424 bool operator != (const _Self & a) const
00425 {
00426 assert(p_vector == a.p_vector);
00427 return offset != a.offset;
00428 }
00429 bool operator < (const _Self & a) const
00430 {
00431 assert(p_vector == a.p_vector);
00432 return offset < a.offset;
00433 }
00434 bool operator <= (const _Self & a) const
00435 {
00436 assert(p_vector == a.p_vector);
00437 return offset <= a.offset;
00438 }
00439 bool operator > (const _Self & a) const
00440 {
00441 assert(p_vector == a.p_vector);
00442 return offset > a.offset;
00443 }
00444 bool operator >= (const _Self & a) const
00445 {
00446 assert(p_vector == a.p_vector);
00447 return offset >= a.offset;
00448 }
00449
00450 bool operator == (const const_iterator & a) const
00451 {
00452 assert(p_vector == a.p_vector);
00453 return offset == a.offset;
00454 }
00455 bool operator != (const const_iterator & a) const
00456 {
00457 assert(p_vector == a.p_vector);
00458 return offset != a.offset;
00459 }
00460 bool operator < (const const_iterator & a) const
00461 {
00462 assert(p_vector == a.p_vector);
00463 return offset < a.offset;
00464 }
00465 bool operator <= (const const_iterator & a) const
00466 {
00467 assert(p_vector == a.p_vector);
00468 return offset <= a.offset;
00469 }
00470 bool operator > (const const_iterator & a) const
00471 {
00472 assert(p_vector == a.p_vector);
00473 return offset > a.offset;
00474 }
00475 bool operator >= (const const_iterator & a) const
00476 {
00477 assert(p_vector == a.p_vector);
00478 return offset >= a.offset;
00479 }
00480
00481 void flush()
00482 {
00483 p_vector->flush();
00484 }
00485
00486
00487
00488
00489
00490
00491 };
00492
00494 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
00495 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
00496 class const_vector_iterator
00497 {
00498 typedef const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_,
00499 BlkSize_, PgTp_, PgSz_> _Self;
00500 typedef vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_,
00501 BlkSize_, PgTp_, PgSz_> _NonConstIterator;
00502
00503 friend class vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>;
00504
00505 public:
00506 typedef _Self const_iterator;
00507 typedef _NonConstIterator iterator;
00508
00509 typedef SzTp_ size_type;
00510 typedef DiffTp_ difference_type;
00511 typedef unsigned block_offset_type;
00512 typedef vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_> vector_type;
00513 friend class vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_>;
00514 typedef bid_vector<BlkSize_> bids_container_type;
00515 typedef typename bids_container_type::iterator bids_container_iterator;
00516 typedef typed_block<BlkSize_, Tp_> block_type;
00517 typedef BID<BlkSize_> bid_type;
00518
00519 typedef std::random_access_iterator_tag iterator_category;
00520 typedef typename vector_type::value_type value_type;
00521 typedef typename vector_type::const_reference reference;
00522 typedef typename vector_type::const_reference const_reference;
00523 typedef typename vector_type::const_pointer pointer;
00524 typedef typename vector_type::const_pointer const_pointer;
00525
00526 enum { block_size = BlkSize_ };
00527
00528 protected:
00529 double_blocked_index<SzTp_, PgSz_, block_type::size> offset;
00530 const vector_type * p_vector;
00531
00532 private:
00533 const_vector_iterator(const vector_type * v, size_type o) : offset(o),
00534 p_vector(v)
00535 { }
00536
00537 public:
00538 const_vector_iterator() : offset(0), p_vector(NULL)
00539 { }
00540 const_vector_iterator(const _Self & a) :
00541 offset(a.offset),
00542 p_vector(a.p_vector)
00543 { }
00544
00545 const_vector_iterator(const iterator & a) :
00546 offset(a.offset),
00547 p_vector(a.p_vector)
00548 { }
00549
00550 block_offset_type block_offset() const
00551 {
00552 return static_cast<block_offset_type>(offset.get_offset());
00553 }
00554 bids_container_iterator bid() const
00555 {
00556 return ((vector_type *)p_vector)->bid(offset);
00557 }
00558
00559 difference_type operator - (const _Self & a) const
00560 {
00561 return offset - a.offset;
00562 }
00563
00564 difference_type operator - (const iterator & a) const
00565 {
00566 return offset - a.offset;
00567 }
00568
00569 _Self operator - (size_type op) const
00570 {
00571 return _Self(p_vector, offset.get_pos() - op);
00572 }
00573
00574 _Self operator + (size_type op) const
00575 {
00576 return _Self(p_vector, offset.get_pos() + op);
00577 }
00578
00579 _Self & operator -= (size_type op)
00580 {
00581 offset -= op;
00582 return *this;
00583 }
00584
00585 _Self & operator += (size_type op)
00586 {
00587 offset += op;
00588 return *this;
00589 }
00590
00591 const_reference operator * () const
00592 {
00593 return p_vector->const_element(offset);
00594 }
00595
00596 const_pointer operator -> () const
00597 {
00598 return &(p_vector->const_element(offset));
00599 }
00600
00601 const_reference operator [] (size_type op) const
00602 {
00603 return p_vector->const_element(offset.get_pos() + op);
00604 }
00605
00606 void block_externally_updated()
00607 {
00608 p_vector->block_externally_updated(offset);
00609 }
00610
00611 _STXXL_DEPRECATED(void touch())
00612 {
00613 block_externally_updated();
00614 }
00615
00616 _Self & operator ++ ()
00617 {
00618 offset++;
00619 return *this;
00620 }
00621 _Self operator ++ (int)
00622 {
00623 _Self tmp_ = *this;
00624 offset++;
00625 return tmp_;
00626 }
00627 _Self & operator -- ()
00628 {
00629 offset--;
00630 return *this;
00631 }
00632 _Self operator -- (int)
00633 {
00634 _Self __tmp = *this;
00635 offset--;
00636 return __tmp;
00637 }
00638 bool operator == (const _Self & a) const
00639 {
00640 assert(p_vector == a.p_vector);
00641 return offset == a.offset;
00642 }
00643 bool operator != (const _Self & a) const
00644 {
00645 assert(p_vector == a.p_vector);
00646 return offset != a.offset;
00647 }
00648 bool operator < (const _Self & a) const
00649 {
00650 assert(p_vector == a.p_vector);
00651 return offset < a.offset;
00652 }
00653 bool operator <= (const _Self & a) const
00654 {
00655 assert(p_vector == a.p_vector);
00656 return offset <= a.offset;
00657 }
00658 bool operator > (const _Self & a) const
00659 {
00660 assert(p_vector == a.p_vector);
00661 return offset > a.offset;
00662 }
00663 bool operator >= (const _Self & a) const
00664 {
00665 assert(p_vector == a.p_vector);
00666 return offset >= a.offset;
00667 }
00668
00669 bool operator == (const iterator & a) const
00670 {
00671 assert(p_vector == a.p_vector);
00672 return offset == a.offset;
00673 }
00674 bool operator != (const iterator & a) const
00675 {
00676 assert(p_vector == a.p_vector);
00677 return offset != a.offset;
00678 }
00679 bool operator < (const iterator & a) const
00680 {
00681 assert(p_vector == a.p_vector);
00682 return offset < a.offset;
00683 }
00684 bool operator <= (const iterator & a) const
00685 {
00686 assert(p_vector == a.p_vector);
00687 return offset <= a.offset;
00688 }
00689 bool operator > (const iterator & a) const
00690 {
00691 assert(p_vector == a.p_vector);
00692 return offset > a.offset;
00693 }
00694 bool operator >= (const iterator & a) const
00695 {
00696 assert(p_vector == a.p_vector);
00697 return offset >= a.offset;
00698 }
00699
00700 void flush()
00701 {
00702 p_vector->flush();
00703 }
00704
00705 std::ostream & operator << (std::ostream & o) const
00706 {
00707 o << "vector pointer: " << ((void *)p_vector) << " offset: " << offset;
00708 return o;
00709 }
00710 };
00711
00712
00714
00727 template <
00728 typename Tp_,
00729 unsigned PgSz_ = 4,
00730 typename PgTp_ = lru_pager<8>,
00731 unsigned BlkSize_ = STXXL_DEFAULT_BLOCK_SIZE(Tp_),
00732 typename AllocStr_ = STXXL_DEFAULT_ALLOC_STRATEGY,
00733 typename SzTp_ = stxxl::uint64
00734 >
00735 class vector
00736 {
00737 public:
00738 typedef Tp_ value_type;
00739 typedef value_type & reference;
00740 typedef const value_type & const_reference;
00741 typedef value_type * pointer;
00742 typedef SzTp_ size_type;
00743 typedef stxxl::int64 difference_type;
00744 typedef const value_type * const_pointer;
00745
00746 typedef PgTp_ pager_type;
00747 typedef AllocStr_ alloc_strategy_type;
00748
00749 enum constants {
00750 block_size = BlkSize_,
00751 page_size = PgSz_,
00752 n_pages = pager_type::n_pages,
00753 on_disk = -1
00754 };
00755
00756 typedef vector_iterator<value_type, alloc_strategy_type, size_type,
00757 difference_type, block_size, pager_type, page_size> iterator;
00758 friend class vector_iterator<value_type, alloc_strategy_type, size_type, difference_type, block_size, pager_type, page_size>;
00759 typedef const_vector_iterator<value_type, alloc_strategy_type,
00760 size_type, difference_type, block_size, pager_type, page_size> const_iterator;
00761 friend class const_vector_iterator<value_type, alloc_strategy_type, size_type, difference_type, block_size, pager_type, page_size>;
00762 typedef std::reverse_iterator<iterator> reverse_iterator;
00763 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00764
00765 typedef bid_vector<block_size> bids_container_type;
00766 typedef typename bids_container_type::
00767 iterator bids_container_iterator;
00768 typedef typename bids_container_type::
00769 const_iterator const_bids_container_iterator;
00770
00771 typedef typed_block<BlkSize_, Tp_> block_type;
00772
00773 private:
00774 alloc_strategy_type alloc_strategy;
00775 size_type _size;
00776 bids_container_type _bids;
00777 mutable pager_type pager;
00778
00779 enum { valid_on_disk = 0, uninitialized = 1, dirty = 2 };
00780 mutable std::vector<unsigned char> _page_status;
00781 mutable std::vector<int_type> _page_to_slot;
00782 mutable simple_vector<int_type> _slot_to_page;
00783 mutable std::queue<int_type> _free_slots;
00784 mutable simple_vector<block_type> * _cache;
00785 file * _from;
00786 block_manager * bm;
00787 config * cfg;
00788 bool exported;
00789
00790 size_type size_from_file_length(stxxl::uint64 file_length)
00791 {
00792 stxxl::uint64 blocks_fit = file_length / stxxl::uint64(block_type::raw_size);
00793 size_type cur_size = blocks_fit * stxxl::uint64(block_type::size);
00794 stxxl::uint64 rest = file_length - blocks_fit * stxxl::uint64(block_type::raw_size);
00795 return (cur_size + rest / stxxl::uint64(sizeof(value_type)));
00796 }
00797
00798 stxxl::uint64 file_length()
00799 {
00800 typedef stxxl::uint64 file_size_type;
00801 size_type cur_size = size();
00802 size_type num_full_blocks = cur_size / block_type::size;
00803 if (cur_size % block_type::size != 0)
00804 {
00805 size_type rest = cur_size - num_full_blocks * block_type::size;
00806 return file_size_type(num_full_blocks) * block_type::raw_size + rest * sizeof(value_type);
00807 }
00808 return file_size_type(num_full_blocks) * block_type::raw_size;
00809 }
00810
00811 public:
00812 vector(size_type n = 0) :
00813 _size(n),
00814 _bids(div_ceil(n, block_type::size)),
00815 _page_status(div_ceil(_bids.size(), page_size)),
00816 _page_to_slot(div_ceil(_bids.size(), page_size)),
00817 _slot_to_page(n_pages),
00818 _cache(NULL),
00819 _from(NULL),
00820 exported(false)
00821 {
00822 bm = block_manager::get_instance();
00823 cfg = config::get_instance();
00824
00825 allocate_page_cache();
00826 int_type all_pages = div_ceil(_bids.size(), page_size);
00827 int_type i = 0;
00828 for ( ; i < all_pages; ++i)
00829 {
00830 _page_status[i] = uninitialized;
00831 _page_to_slot[i] = on_disk;
00832 }
00833
00834 for (i = 0; i < n_pages; ++i)
00835 _free_slots.push(i);
00836
00837 bm->new_blocks(alloc_strategy, _bids.begin(), _bids.end(), 0);
00838 }
00839
00840 void swap(vector & obj)
00841 {
00842 std::swap(alloc_strategy, obj.alloc_strategy);
00843 std::swap(_size, obj._size);
00844 std::swap(_bids, obj._bids);
00845 std::swap(pager, obj.pager);
00846 std::swap(_page_status, obj._page_status);
00847 std::swap(_page_to_slot, obj._page_to_slot);
00848 std::swap(_slot_to_page, obj._slot_to_page);
00849 std::swap(_free_slots, obj._free_slots);
00850 std::swap(_cache, obj._cache);
00851 std::swap(_from, obj._from);
00852 std::swap(exported, obj.exported);
00853 }
00854
00855 void allocate_page_cache() const
00856 {
00857 if (!_cache)
00858 _cache = new simple_vector<block_type>(n_pages * page_size);
00859 }
00860
00861
00862 void deallocate_page_cache() const
00863 {
00864 flush();
00865 delete _cache;
00866 _cache = NULL;
00867 }
00868
00869 size_type capacity() const
00870 {
00871 return size_type(_bids.size()) * block_type::size;
00872 }
00874 size_type raw_capacity() const
00875 {
00876 return size_type(_bids.size()) * block_type::raw_size;
00877 }
00878 void reserve(size_type n)
00879 {
00880 if (n <= capacity())
00881 return;
00882
00883
00884 unsigned_type old_bids_size = _bids.size();
00885 unsigned_type new_bids_size = div_ceil(n, block_type::size);
00886 unsigned_type new_pages = div_ceil(new_bids_size, page_size);
00887 _page_status.resize(new_pages, uninitialized);
00888 _page_to_slot.resize(new_pages, on_disk);
00889
00890 _bids.resize(new_bids_size);
00891 if (_from == NULL)
00892 {
00893 bm->new_blocks(alloc_strategy, _bids.begin() + old_bids_size, _bids.end(), old_bids_size);
00894 }
00895 else
00896 {
00897 size_type offset = size_type(old_bids_size) * size_type(block_type::raw_size);
00898 bids_container_iterator it = _bids.begin() + old_bids_size;
00899 for ( ; it != _bids.end(); ++it, offset += size_type(block_type::raw_size))
00900 {
00901 (*it).storage = _from;
00902 (*it).offset = offset;
00903 }
00904 STXXL_VERBOSE1("vector::reserve(): Changing size of file " << ((void *)_from) << " to "
00905 << offset);
00906 _from->set_size(offset);
00907 }
00908 }
00909
00910 void resize(size_type n)
00911 {
00912 _resize(n);
00913 }
00914
00915 void resize(size_type n, bool shrink_capacity)
00916 {
00917 if (shrink_capacity)
00918 _resize_shrink_capacity(n);
00919 else
00920 _resize(n);
00921 }
00922
00923 private:
00924 void _resize(size_type n)
00925 {
00926 reserve(n);
00927 if (n < _size) {
00928
00929 unsigned_type first_page_to_evict = div_ceil(n, block_type::size * page_size);
00930 for (unsigned_type i = first_page_to_evict; i < _page_status.size(); ++i) {
00931 if (_page_to_slot[i] != on_disk) {
00932 _free_slots.push(_page_to_slot[i]);
00933 _page_to_slot[i] = on_disk;
00934 }
00935 _page_status[i] = uninitialized;
00936 }
00937 }
00938 _size = n;
00939 }
00940
00941 void _resize_shrink_capacity(size_type n)
00942 {
00943 unsigned_type old_bids_size = _bids.size();
00944 unsigned_type new_bids_size = div_ceil(n, block_type::size);
00945
00946 if (new_bids_size > old_bids_size)
00947 {
00948 reserve(n);
00949 }
00950 else if (new_bids_size < old_bids_size)
00951 {
00952 if (_from != NULL)
00953 _from->set_size(new_bids_size * block_type::raw_size);
00954 else
00955 bm->delete_blocks(_bids.begin() + old_bids_size, _bids.end());
00956
00957 _bids.resize(new_bids_size);
00958 unsigned_type new_pages = div_ceil(new_bids_size, page_size);
00959 _page_status.resize(new_pages);
00960
00961 unsigned_type first_page_to_evict = div_ceil(new_bids_size, page_size);
00962
00963 std::fill(_page_status.begin() + first_page_to_evict,
00964 _page_status.end(), (unsigned char)valid_on_disk);
00965 }
00966
00967 _size = n;
00968 }
00969
00970 public:
00971 void clear()
00972 {
00973 _size = 0;
00974 if (_from == NULL)
00975 bm->delete_blocks(_bids.begin(), _bids.end());
00976
00977 _bids.clear();
00978 _page_status.clear();
00979 _page_to_slot.clear();
00980 while (!_free_slots.empty())
00981 _free_slots.pop();
00982
00983
00984 for (int_type i = 0; i < n_pages; ++i)
00985 _free_slots.push(i);
00986 }
00987 void push_back(const_reference obj)
00988 {
00989 size_type old_size = _size;
00990 resize(old_size + 1);
00991 element(old_size) = obj;
00992 }
00993 void pop_back()
00994 {
00995 resize(_size - 1);
00996 }
00997 reference back()
00998 {
00999 return element(_size - 1);
01000 }
01001 reference front()
01002 {
01003 return element(0);
01004 }
01005 const_reference back() const
01006 {
01007 return const_element(_size - 1);
01008 }
01009 const_reference front() const
01010 {
01011 return const_element(0);
01012 }
01018 vector(file * from, size_type size = size_type(-1)) :
01019 _size((size == size_type(-1)) ? size_from_file_length(from->size()) : size),
01020 _bids(div_ceil(_size, size_type(block_type::size))),
01021 _page_status(div_ceil(_bids.size(), page_size)),
01022 _page_to_slot(div_ceil(_bids.size(), page_size)),
01023 _slot_to_page(n_pages),
01024 _cache(NULL),
01025 _from(from),
01026 exported(false)
01027 {
01028
01029 if (!block_type::has_only_data)
01030 {
01031 std::ostringstream str_;
01032 str_ << "The block size for a vector that is mapped to a file must me a multiple of the element size (" <<
01033 sizeof(value_type) << ") and the page size (4096).";
01034 throw std::runtime_error(str_.str());
01035 }
01036
01037 bm = block_manager::get_instance();
01038 cfg = config::get_instance();
01039
01040 allocate_page_cache();
01041 int_type all_pages = div_ceil(_bids.size(), page_size);
01042 int_type i = 0;
01043 for ( ; i < all_pages; ++i)
01044 {
01045 _page_status[i] = valid_on_disk;
01046 _page_to_slot[i] = on_disk;
01047 }
01048
01049 for (i = 0; i < n_pages; ++i)
01050 _free_slots.push(i);
01051
01052
01053
01054 size_type offset = 0;
01055 bids_container_iterator it = _bids.begin();
01056 for ( ; it != _bids.end(); ++it, offset += size_type(block_type::raw_size))
01057 {
01058 (*it).storage = from;
01059 (*it).offset = offset;
01060 }
01061 from->set_size(offset);
01062 }
01063
01064 vector(const vector & obj) :
01065 _size(obj.size()),
01066 _bids(div_ceil(obj.size(), block_type::size)),
01067 _page_status(div_ceil(_bids.size(), page_size)),
01068 _page_to_slot(div_ceil(_bids.size(), page_size)),
01069 _slot_to_page(n_pages),
01070 _cache(NULL),
01071 _from(NULL),
01072 exported(false)
01073 {
01074 assert(!obj.exported);
01075 bm = block_manager::get_instance();
01076 cfg = config::get_instance();
01077
01078 allocate_page_cache();
01079 int_type all_pages = div_ceil(_bids.size(), page_size);
01080 int_type i = 0;
01081 for ( ; i < all_pages; ++i)
01082 {
01083 _page_status[i] = uninitialized;
01084 _page_to_slot[i] = on_disk;
01085 }
01086
01087 for (i = 0; i < n_pages; ++i)
01088 _free_slots.push(i);
01089
01090 bm->new_blocks(alloc_strategy, _bids.begin(), _bids.end(), 0);
01091
01092 const_iterator inbegin = obj.begin();
01093 const_iterator inend = obj.end();
01094 std::copy(inbegin, inend, begin());
01095 }
01096
01097 vector & operator = (const vector & obj)
01098 {
01099 if (&obj != this)
01100 {
01101 vector tmp(obj);
01102 this->swap(tmp);
01103 }
01104 return *this;
01105 }
01106
01107 size_type size() const
01108 {
01109 return _size;
01110 }
01111 bool empty() const
01112 {
01113 return (!_size);
01114 }
01115 iterator begin()
01116 {
01117 return iterator(this, 0);
01118 }
01119 const_iterator begin() const
01120 {
01121 return const_iterator(this, 0);
01122 }
01123 const_iterator cbegin() const
01124 {
01125 return begin();
01126 }
01127 iterator end()
01128 {
01129 return iterator(this, _size);
01130 }
01131 const_iterator end() const
01132 {
01133 return const_iterator(this, _size);
01134 }
01135 const_iterator cend() const
01136 {
01137 return end();
01138 }
01139
01140 reverse_iterator rbegin()
01141 {
01142 return reverse_iterator(end());
01143 }
01144 const_reverse_iterator rbegin() const
01145 {
01146 return const_reverse_iterator(end());
01147 }
01148 const_reverse_iterator crbegin() const
01149 {
01150 return const_reverse_iterator(end());
01151 }
01152 reverse_iterator rend()
01153 {
01154 return reverse_iterator(begin());
01155 }
01156 const_reverse_iterator rend() const
01157 {
01158 return const_reverse_iterator(begin());
01159 }
01160 const_reverse_iterator crend() const
01161 {
01162 return const_reverse_iterator(begin());
01163 }
01164
01165 reference operator [] (size_type offset)
01166 {
01167 return element(offset);
01168 }
01169 const_reference operator [] (size_type offset) const
01170 {
01171 return const_element(offset);
01172 }
01173
01174 void flush() const
01175 {
01176 simple_vector<bool> non_free_slots(n_pages);
01177 int_type i = 0;
01178 for ( ; i < n_pages; i++)
01179 non_free_slots[i] = true;
01180
01181
01182 while (!_free_slots.empty())
01183 {
01184 non_free_slots[_free_slots.front()] = false;
01185 _free_slots.pop();
01186 }
01187
01188 for (i = 0; i < n_pages; i++)
01189 {
01190 _free_slots.push(i);
01191 int_type page_no = _slot_to_page[i];
01192 if (non_free_slots[i])
01193 {
01194 STXXL_VERBOSE1("vector: flushing page " << i << " at address "
01195 << (int64(page_no) * int64(block_type::size) * int64(page_size)));
01196 write_page(page_no, i);
01197
01198 _page_to_slot[page_no] = on_disk;
01199 }
01200 }
01201 }
01202 ~vector()
01203 {
01204 try
01205 {
01206 flush();
01207 }
01208 catch (...)
01209 {
01210 STXXL_VERBOSE("Exception thrown in ~vector()");
01211 }
01212
01213 if (!exported)
01214 {
01215 if (_from == NULL)
01216 bm->delete_blocks(_bids.begin(), _bids.end());
01217 else
01218 {
01219 STXXL_VERBOSE1("~vector(): Changing size of file " << ((void *)_from) << " to "
01220 << file_length());
01221 STXXL_VERBOSE1("~vector(): size of the vector is " << size());
01222 _from->set_size(file_length());
01223 }
01224 }
01225 delete _cache;
01226 }
01227
01230 void export_files(std::string filename_prefix)
01231 {
01232 int64 no = 0;
01233 for (bids_container_iterator i = _bids.begin(); i != _bids.end(); ++i) {
01234 std::ostringstream number;
01235 number << std::setw(9) << std::setfill('0') << no;
01236 size_type current_block_size =
01237 ((i + 1) == _bids.end() && _size % block_type::size > 0) ?
01238 (_size % block_type::size) * sizeof(value_type) :
01239 block_type::size * sizeof(value_type);
01240 (*i).storage->export_files((*i).offset, current_block_size, filename_prefix + number.str());
01241 ++no;
01242 }
01243 exported = true;
01244 }
01245
01247 file * get_file()
01248 {
01249 return _from;
01250 }
01251
01254 template <typename ForwardIterator>
01255 void set_content(const ForwardIterator & bid_begin, const ForwardIterator & bid_end, size_type n)
01256 {
01257 unsigned_type new_bids_size = div_ceil(n, block_type::size);
01258 _bids.resize(new_bids_size);
01259 std::copy(bid_begin, bid_end, _bids.begin());
01260 unsigned_type new_pages = div_ceil(new_bids_size, page_size);
01261 _page_status.resize(new_pages, valid_on_disk);
01262 _page_to_slot.resize(new_pages, on_disk);
01263 _size = n;
01264 }
01265
01266 private:
01267 bids_container_iterator bid(const size_type & offset)
01268 {
01269 return (_bids.begin() +
01270 static_cast<typename bids_container_type::size_type>
01271 (offset / block_type::size));
01272 }
01273 bids_container_iterator bid(const double_blocked_index<SzTp_, PgSz_, block_type::size> & offset)
01274 {
01275 return (_bids.begin() +
01276 static_cast<typename bids_container_type::size_type>
01277 (offset.get_block2() * PgSz_ + offset.get_block1()));
01278 }
01279 const_bids_container_iterator bid(const size_type & offset) const
01280 {
01281 return (_bids.begin() +
01282 static_cast<typename bids_container_type::size_type>
01283 (offset / block_type::size));
01284 }
01285 const_bids_container_iterator bid(const double_blocked_index<SzTp_, PgSz_, block_type::size> & offset) const
01286 {
01287 return (_bids.begin() +
01288 static_cast<typename bids_container_type::size_type>
01289 (offset.get_block2() * PgSz_ + offset.get_block1()));
01290 }
01291 void read_page(int_type page_no, int_type cache_slot) const
01292 {
01293 if (_page_status[page_no] == uninitialized)
01294 return;
01295 STXXL_VERBOSE1("vector " << this << ": reading page_no=" << page_no << " cache_slot=" << cache_slot);
01296 request_ptr * reqs = new request_ptr[page_size];
01297 int_type block_no = page_no * page_size;
01298 int_type last_block = STXXL_MIN(block_no + page_size, int_type(_bids.size()));
01299 int_type i = cache_slot * page_size, j = 0;
01300 for ( ; block_no < last_block; ++block_no, ++i, ++j)
01301 {
01302 reqs[j] = (*_cache)[i].read(_bids[block_no]);
01303 }
01304 assert(last_block - page_no * page_size > 0);
01305 wait_all(reqs, last_block - page_no * page_size);
01306 delete[] reqs;
01307 }
01308 void write_page(int_type page_no, int_type cache_slot) const
01309 {
01310 if (!(_page_status[page_no] & dirty))
01311 return;
01312 STXXL_VERBOSE1("vector " << this << ": writing page_no=" << page_no << " cache_slot=" << cache_slot);
01313 request_ptr * reqs = new request_ptr[page_size];
01314 int_type block_no = page_no * page_size;
01315 int_type last_block = STXXL_MIN(block_no + page_size, int_type(_bids.size()));
01316 int_type i = cache_slot * page_size, j = 0;
01317 for ( ; block_no < last_block; ++block_no, ++i, ++j)
01318 {
01319 reqs[j] = (*_cache)[i].write(_bids[block_no]);
01320 }
01321 _page_status[page_no] = valid_on_disk;
01322 assert(last_block - page_no * page_size > 0);
01323 wait_all(reqs, last_block - page_no * page_size);
01324 delete[] reqs;
01325 }
01326 reference element(size_type offset)
01327 {
01328 #ifdef STXXL_RANGE_CHECK
01329 assert(offset < size());
01330 #endif
01331 return element(double_blocked_index<SzTp_, PgSz_, block_type::size>(offset));
01332 }
01333
01334 reference element(const double_blocked_index<SzTp_, PgSz_, block_type::size> & offset)
01335 {
01336 #ifdef STXXL_RANGE_CHECK
01337 assert(offset.get_pos() < size());
01338 #endif
01339 int_type page_no = offset.get_block2();
01340 assert(page_no < int_type(_page_to_slot.size()));
01341 int_type cache_slot = _page_to_slot[page_no];
01342 if (cache_slot < 0)
01343 {
01344 if (_free_slots.empty())
01345 {
01346 int_type kicked_slot = pager.kick();
01347 pager.hit(kicked_slot);
01348 int_type old_page_no = _slot_to_page[kicked_slot];
01349 _page_to_slot[page_no] = kicked_slot;
01350 _page_to_slot[old_page_no] = on_disk;
01351 _slot_to_page[kicked_slot] = page_no;
01352
01353 write_page(old_page_no, kicked_slot);
01354 read_page(page_no, kicked_slot);
01355
01356 _page_status[page_no] = dirty;
01357
01358 return (*_cache)[kicked_slot * page_size + offset.get_block1()][offset.get_offset()];
01359 }
01360 else
01361 {
01362 int_type free_slot = _free_slots.front();
01363 _free_slots.pop();
01364 pager.hit(free_slot);
01365 _page_to_slot[page_no] = free_slot;
01366 _slot_to_page[free_slot] = page_no;
01367
01368 read_page(page_no, free_slot);
01369
01370 _page_status[page_no] = dirty;
01371
01372 return (*_cache)[free_slot * page_size + offset.get_block1()][offset.get_offset()];
01373 }
01374 }
01375 else
01376 {
01377 _page_status[page_no] = dirty;
01378 pager.hit(cache_slot);
01379 return (*_cache)[cache_slot * page_size + offset.get_block1()][offset.get_offset()];
01380 }
01381 }
01382
01383
01384 void page_externally_updated(unsigned_type page_no) const
01385 {
01386
01387 assert(page_no < _page_status.size());
01388 assert(!(_page_status[page_no] & dirty) &&
01389 "A dirty page has been marked as newly initialized. The page content will be lost.");
01390 if (_page_to_slot[page_no] != on_disk) {
01391
01392 _free_slots.push(_page_to_slot[page_no]);
01393 _page_to_slot[page_no] = on_disk;
01394 }
01395 _page_status[page_no] = valid_on_disk;
01396 }
01397
01398 void block_externally_updated(size_type offset) const
01399 {
01400 page_externally_updated(offset / (block_type::size * page_size));
01401 }
01402
01403 void block_externally_updated(const double_blocked_index<SzTp_, PgSz_, block_type::size> & offset) const
01404 {
01405 page_externally_updated(offset.get_block2());
01406 }
01407
01408 _STXXL_DEPRECATED(void touch(size_type offset) const)
01409 {
01410 page_externally_updated(offset / (block_type::size * page_size));
01411 }
01412
01413 _STXXL_DEPRECATED(void touch(const double_blocked_index<SzTp_, PgSz_, block_type::size> & offset) const)
01414 {
01415 page_externally_updated(offset.get_block2());
01416 }
01417
01418 const_reference const_element(size_type offset) const
01419 {
01420 return const_element(double_blocked_index<SzTp_, PgSz_, block_type::size>(offset));
01421 }
01422
01423 const_reference const_element(const double_blocked_index<SzTp_, PgSz_, block_type::size> & offset) const
01424 {
01425 int_type page_no = offset.get_block2();
01426 assert(page_no < int_type(_page_to_slot.size()));
01427 int_type cache_slot = _page_to_slot[page_no];
01428 if (cache_slot < 0)
01429 {
01430 if (_free_slots.empty())
01431 {
01432 int_type kicked_slot = pager.kick();
01433 pager.hit(kicked_slot);
01434 int_type old_page_no = _slot_to_page[kicked_slot];
01435 _page_to_slot[page_no] = kicked_slot;
01436 _page_to_slot[old_page_no] = on_disk;
01437 _slot_to_page[kicked_slot] = page_no;
01438
01439 write_page(old_page_no, kicked_slot);
01440 read_page(page_no, kicked_slot);
01441
01442 return (*_cache)[kicked_slot * page_size + offset.get_block1()][offset.get_offset()];
01443 }
01444 else
01445 {
01446 int_type free_slot = _free_slots.front();
01447 _free_slots.pop();
01448 pager.hit(free_slot);
01449 _page_to_slot[page_no] = free_slot;
01450 _slot_to_page[free_slot] = page_no;
01451
01452 read_page(page_no, free_slot);
01453
01454 return (*_cache)[free_slot * page_size + offset.get_block1()][offset.get_offset()];
01455 }
01456 }
01457 else
01458 {
01459 pager.hit(cache_slot);
01460 return (*_cache)[cache_slot * page_size + offset.get_block1()][offset.get_offset()];
01461 }
01462 }
01463 };
01464
01465 template <
01466 typename Tp_,
01467 unsigned PgSz_,
01468 typename PgTp_,
01469 unsigned BlkSize_,
01470 typename AllocStr_,
01471 typename SzTp_>
01472 inline bool operator == (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01473 AllocStr_, SzTp_> & a,
01474 stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01475 AllocStr_, SzTp_> & b)
01476 {
01477 return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
01478 }
01479
01480 template <
01481 typename Tp_,
01482 unsigned PgSz_,
01483 typename PgTp_,
01484 unsigned BlkSize_,
01485 typename AllocStr_,
01486 typename SzTp_>
01487 inline bool operator != (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01488 AllocStr_, SzTp_> & a,
01489 stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01490 AllocStr_, SzTp_> & b)
01491 {
01492 return !(a == b);
01493 }
01494
01495 template <
01496 typename Tp_,
01497 unsigned PgSz_,
01498 typename PgTp_,
01499 unsigned BlkSize_,
01500 typename AllocStr_,
01501 typename SzTp_>
01502 inline bool operator < (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01503 AllocStr_, SzTp_> & a,
01504 stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01505 AllocStr_, SzTp_> & b)
01506 {
01507 return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
01508 }
01509
01510 template <
01511 typename Tp_,
01512 unsigned PgSz_,
01513 typename PgTp_,
01514 unsigned BlkSize_,
01515 typename AllocStr_,
01516 typename SzTp_>
01517 inline bool operator > (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01518 AllocStr_, SzTp_> & a,
01519 stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01520 AllocStr_, SzTp_> & b)
01521 {
01522 return b < a;
01523 }
01524
01525 template <
01526 typename Tp_,
01527 unsigned PgSz_,
01528 typename PgTp_,
01529 unsigned BlkSize_,
01530 typename AllocStr_,
01531 typename SzTp_>
01532 inline bool operator <= (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01533 AllocStr_, SzTp_> & a,
01534 stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01535 AllocStr_, SzTp_> & b)
01536 {
01537 return !(b < a);
01538 }
01539
01540 template <
01541 typename Tp_,
01542 unsigned PgSz_,
01543 typename PgTp_,
01544 unsigned BlkSize_,
01545 typename AllocStr_,
01546 typename SzTp_>
01547 inline bool operator >= (stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01548 AllocStr_, SzTp_> & a,
01549 stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_,
01550 AllocStr_, SzTp_> & b)
01551 {
01552 return !(a < b);
01553 }
01554
01556
01558
01559
01560 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
01561 unsigned BlkSize_, typename PgTp_, unsigned PgSz_>
01562 bool is_sorted(
01563 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> __first,
01564 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> __last)
01565 {
01566 return is_sorted_helper(
01567 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>(__first),
01568 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>(__last));
01569 }
01570
01571 template <typename Tp_, typename AllocStr_, typename SzTp_, typename DiffTp_,
01572 unsigned BlkSize_, typename PgTp_, unsigned PgSz_, typename _StrictWeakOrdering>
01573 bool is_sorted(
01574 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> __first,
01575 stxxl::vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_> __last,
01576 _StrictWeakOrdering __comp)
01577 {
01578 return is_sorted_helper(
01579 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>(__first),
01580 stxxl::const_vector_iterator<Tp_, AllocStr_, SzTp_, DiffTp_, BlkSize_, PgTp_, PgSz_>(__last),
01581 __comp);
01582 }
01583
01585
01588
01590
01613 template <
01614 typename Tp_,
01615 unsigned PgSz_ = 4,
01616 unsigned Pages_ = 8,
01617 unsigned BlkSize_ = STXXL_DEFAULT_BLOCK_SIZE(Tp_),
01618 typename AllocStr_ = STXXL_DEFAULT_ALLOC_STRATEGY,
01619 pager_type Pager_ = lru
01620 >
01621 struct VECTOR_GENERATOR
01622 {
01623 typedef typename IF<Pager_ == lru,
01624 lru_pager<Pages_>, random_pager<Pages_> >::result PagerType;
01625
01626 typedef vector<Tp_, PgSz_, PagerType, BlkSize_, AllocStr_> result;
01627 };
01628
01629
01631
01632 __STXXL_END_NAMESPACE
01633
01634
01635 namespace std
01636 {
01637 template <
01638 typename Tp_,
01639 unsigned PgSz_,
01640 typename PgTp_,
01641 unsigned BlkSize_,
01642 typename AllocStr_,
01643 typename SzTp_>
01644 void swap(stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_> & a,
01645 stxxl::vector<Tp_, PgSz_, PgTp_, BlkSize_, AllocStr_, SzTp_> & b)
01646 {
01647 a.swap(b);
01648 }
01649 }
01650
01651 #endif // !STXXL_VECTOR_HEADER
01652