• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List

vector.h

00001 /***************************************************************************
00002  *  include/stxxl/bits/containers/vector.h
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2002-2007 Roman Dementiev <[email protected]>
00007  *  Copyright (C) 2007, 2008 Johannes Singler <[email protected]>
00008  *
00009  *  Distributed under the Boost Software License, Version 1.0.
00010  *  (See accompanying file LICENSE_1_0.txt or copy at
00011  *  http://www.boost.org/LICENSE_1_0.txt)
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(/* 0 <= block1 && */ block1 < modulo2);
00058         assert(/* 0 <= offset && */ 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(/* 0 <= block1 && */ block1 < modulo2);
00075         assert(/* 0 <= offset && */ 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     //pre-increment operator
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(/* 0 <= block1 && */ block1 < modulo2);
00107         assert(/* 0 <= offset && */ offset < modulo1);
00108 
00109         return *this;
00110     }
00111 
00112     //post-increment operator
00113     double_blocked_index operator ++ (int)
00114     {
00115         double_blocked_index former(*this);
00116         operator ++ ();
00117         return former;
00118     }
00119 
00120     //pre-increment operator
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(/*0 <= block1 &&*/ block1 < modulo2);
00138         assert(/*0 <= offset &&*/ offset < modulo1);
00139 
00140         return *this;
00141     }
00142 
00143     //post-increment operator
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        std::ostream & operator<< (std::ostream & o) const
00487        {
00488             o << "vectorpointer: "  << ((void*)p_vector) <<" offset: "<<offset;
00489             return o;
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;                 // or (offset + stxxl::int64(p_vector))
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; // or (offset + stxxl::int64(p_vector))
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       // will be deprecated soon
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     // allows to free the cache, but you may not access any element until call allocate_pacge_cache() again
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             // mark excess pages as uninitialized and evict them from cache
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             // clear dirty flag, so these pages will be never written
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         // initialize from file
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         //allocate blocks equidistantly and in-order
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        // file must be truncated
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()));   // fails if offset is too large, out of bound access
01341         int_type cache_slot = _page_to_slot[page_no];
01342         if (cache_slot < 0)                                 // == on_disk
01343         {
01344             if (_free_slots.empty())                        // has to kick
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     // don't forget to first flush() the vector's cache before updating pages externally
01384     void page_externally_updated(unsigned_type page_no) const
01385     {
01386         // fails if offset is too large, out of bound access
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             // remove page from cache
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()));   // fails if offset is too large, out of bound access
01427         int_type cache_slot = _page_to_slot[page_no];
01428         if (cache_slot < 0)                                 // == on_disk
01429         {
01430             if (_free_slots.empty())                        // has to kick
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 // specialization for stxxl::vector, to use only const_iterators
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 // vim: et:ts=4:sw=4

Generated by  doxygen 1.7.1