00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef STXXL_STACK_HEADER
00014 #define STXXL_STACK_HEADER
00015
00016 #include <stack>
00017 #include <vector>
00018
00019 #include <stxxl/bits/mng/mng.h>
00020 #include <stxxl/bits/mng/typed_block.h>
00021 #include <stxxl/bits/common/simple_vector.h>
00022 #include <stxxl/bits/common/tmeta.h>
00023 #include <stxxl/bits/mng/read_write_pool.h>
00024 #include <stxxl/bits/mng/write_pool.h>
00025 #include <stxxl/bits/mng/prefetch_pool.h>
00026
00027
00028 __STXXL_BEGIN_NAMESPACE
00029
00032
00033 template <class ValTp,
00034 unsigned BlocksPerPage = 4,
00035 unsigned BlkSz = STXXL_DEFAULT_BLOCK_SIZE(ValTp),
00036 class AllocStr = STXXL_DEFAULT_ALLOC_STRATEGY,
00037 class SzTp = stxxl::int64>
00038 struct stack_config_generator
00039 {
00040 typedef ValTp value_type;
00041 enum { blocks_per_page = BlocksPerPage };
00042 typedef AllocStr alloc_strategy;
00043 enum { block_size = BlkSz };
00044 typedef SzTp size_type;
00045 };
00046
00047
00049
00055 template <class Config_>
00056 class normal_stack : private noncopyable
00057 {
00058 public:
00059 typedef Config_ cfg;
00060 typedef typename cfg::value_type value_type;
00061 typedef typename cfg::alloc_strategy alloc_strategy_type;
00062 typedef typename cfg::size_type size_type;
00063 enum {
00064 blocks_per_page = cfg::blocks_per_page,
00065 block_size = cfg::block_size
00066 };
00067
00068 typedef typed_block<block_size, value_type> block_type;
00069 typedef BID<block_size> bid_type;
00070
00071 private:
00072 size_type size_;
00073 unsigned_type cache_offset;
00074 value_type * current_element;
00075 simple_vector<block_type> cache;
00076 typename simple_vector<block_type>::iterator front_page;
00077 typename simple_vector<block_type>::iterator back_page;
00078 std::vector<bid_type> bids;
00079 alloc_strategy_type alloc_strategy;
00080
00081 public:
00082 normal_stack() :
00083 size_(0),
00084 cache_offset(0),
00085 current_element(NULL),
00086 cache(blocks_per_page * 2),
00087 front_page(cache.begin() + blocks_per_page),
00088 back_page(cache.begin()),
00089 bids(0)
00090 {
00091 bids.reserve(blocks_per_page);
00092 }
00093
00094 void swap(normal_stack & obj)
00095 {
00096 std::swap(size_, obj.size_);
00097 std::swap(cache_offset, obj.cache_offset);
00098 std::swap(current_element, obj.current_element);
00099 std::swap(cache, obj.cache);
00100 std::swap(front_page, obj.front_page);
00101 std::swap(back_page, obj.back_page);
00102 std::swap(bids, obj.bids);
00103 std::swap(alloc_strategy, obj.alloc_strategy);
00104 }
00105
00109 template <class stack_type>
00110 normal_stack(const stack_type & stack_) :
00111 size_(0),
00112 cache_offset(0),
00113 current_element(NULL),
00114 cache(blocks_per_page * 2),
00115 front_page(cache.begin() + blocks_per_page),
00116 back_page(cache.begin()),
00117 bids(0)
00118 {
00119 bids.reserve(blocks_per_page);
00120
00121 stack_type stack_copy = stack_;
00122 const size_type sz = stack_copy.size();
00123 size_type i;
00124
00125 std::vector<value_type> tmp(sz);
00126
00127 for (i = 0; i < sz; ++i)
00128 {
00129 tmp[sz - i - 1] = stack_copy.top();
00130 stack_copy.pop();
00131 }
00132 for (i = 0; i < sz; ++i)
00133 this->push(tmp[i]);
00134 }
00135 virtual ~normal_stack()
00136 {
00137 STXXL_VERBOSE(STXXL_PRETTY_FUNCTION_NAME);
00138 block_manager::get_instance()->delete_blocks(bids.begin(), bids.end());
00139 }
00140 size_type size() const
00141 {
00142 return size_;
00143 }
00144 bool empty() const
00145 {
00146 return (!size_);
00147 }
00148 value_type & top()
00149 {
00150 assert(size_ > 0);
00151 return (*current_element);
00152 }
00153 const value_type & top() const
00154 {
00155 assert(size_ > 0);
00156 return (*current_element);
00157 }
00158 void push(const value_type & val)
00159 {
00160 assert(cache_offset <= 2 * blocks_per_page * block_type::size);
00161
00162
00163 if (cache_offset == 2 * blocks_per_page * block_type::size)
00164 {
00165 STXXL_VERBOSE2("growing, size: " << size_);
00166
00167 bids.resize(bids.size() + blocks_per_page);
00168 typename std::vector<bid_type>::iterator cur_bid = bids.end() - blocks_per_page;
00169 block_manager::get_instance()->new_blocks(alloc_strategy, cur_bid, bids.end(), cur_bid - bids.begin());
00170
00171 simple_vector<request_ptr> requests(blocks_per_page);
00172
00173 for (int i = 0; i < blocks_per_page; ++i, ++cur_bid)
00174 {
00175 requests[i] = (back_page + i)->write(*cur_bid);
00176 }
00177
00178
00179 std::swap(back_page, front_page);
00180
00181 bids.reserve(bids.size() + blocks_per_page);
00182
00183 cache_offset = blocks_per_page * block_type::size + 1;
00184 current_element = &((*front_page)[0]);
00185 ++size_;
00186
00187 wait_all(requests.begin(), blocks_per_page);
00188
00189 *current_element = val;
00190
00191 return;
00192 }
00193
00194 current_element = element(cache_offset);
00195 *current_element = val;
00196 ++size_;
00197 ++cache_offset;
00198 }
00199 void pop()
00200 {
00201 assert(cache_offset <= 2 * blocks_per_page * block_type::size);
00202 assert(cache_offset > 0);
00203 assert(size_ > 0);
00204
00205 if (cache_offset == 1 && bids.size() >= blocks_per_page)
00206 {
00207 STXXL_VERBOSE2("shrinking, size: " << size_);
00208
00209 simple_vector<request_ptr> requests(blocks_per_page);
00210
00211 {
00212 typename std::vector<bid_type>::const_iterator cur_bid = bids.end();
00213 for (int i = blocks_per_page - 1; i >= 0; --i)
00214 {
00215 requests[i] = (front_page + i)->read(*(--cur_bid));
00216 }
00217 }
00218
00219 std::swap(front_page, back_page);
00220
00221 cache_offset = blocks_per_page * block_type::size;
00222 --size_;
00223 current_element = &((*(back_page + (blocks_per_page - 1)))[block_type::size - 1]);
00224
00225 wait_all(requests.begin(), blocks_per_page);
00226
00227 block_manager::get_instance()->delete_blocks(bids.end() - blocks_per_page, bids.end());
00228 bids.resize(bids.size() - blocks_per_page);
00229
00230 return;
00231 }
00232
00233 --size_;
00234
00235 current_element = element((--cache_offset) - 1);
00236 }
00237
00238 private:
00239 value_type * element(unsigned_type offset)
00240 {
00241 if (offset < blocks_per_page * block_type::size)
00242 return &((*(back_page + offset / block_type::size))[offset % block_type::size]);
00243
00244
00245 unsigned_type unbiased_offset = offset - blocks_per_page * block_type::size;
00246 return &((*(front_page + unbiased_offset / block_type::size))[unbiased_offset % block_type::size]);
00247 }
00248 };
00249
00250
00252
00256 template <class Config_>
00257 class grow_shrink_stack : private noncopyable
00258 {
00259 public:
00260 typedef Config_ cfg;
00261 typedef typename cfg::value_type value_type;
00262 typedef typename cfg::alloc_strategy alloc_strategy_type;
00263 typedef typename cfg::size_type size_type;
00264 enum {
00265 blocks_per_page = cfg::blocks_per_page,
00266 block_size = cfg::block_size,
00267 };
00268
00269 typedef typed_block<block_size, value_type> block_type;
00270 typedef BID<block_size> bid_type;
00271
00272 private:
00273 size_type size_;
00274 unsigned_type cache_offset;
00275 value_type * current_element;
00276 simple_vector<block_type> cache;
00277 typename simple_vector<block_type>::iterator cache_buffers;
00278 typename simple_vector<block_type>::iterator overlap_buffers;
00279 simple_vector<request_ptr> requests;
00280 std::vector<bid_type> bids;
00281 alloc_strategy_type alloc_strategy;
00282
00283 public:
00284 grow_shrink_stack() :
00285 size_(0),
00286 cache_offset(0),
00287 current_element(NULL),
00288 cache(blocks_per_page * 2),
00289 cache_buffers(cache.begin()),
00290 overlap_buffers(cache.begin() + blocks_per_page),
00291 requests(blocks_per_page),
00292 bids(0)
00293 {
00294 bids.reserve(blocks_per_page);
00295 }
00296
00297 void swap(grow_shrink_stack & obj)
00298 {
00299 std::swap(size_, obj.size_);
00300 std::swap(cache_offset, obj.cache_offset);
00301 std::swap(current_element, obj.current_element);
00302 std::swap(cache, obj.cache);
00303 std::swap(cache_buffers, obj.cache_buffers);
00304 std::swap(overlap_buffers, obj.overlap_buffers);
00305 std::swap(requests, obj.requests);
00306 std::swap(bids, obj.bids);
00307 std::swap(alloc_strategy, obj.alloc_strategy);
00308 }
00309
00313 template <class stack_type>
00314 grow_shrink_stack(const stack_type & stack_) :
00315 size_(0),
00316 cache_offset(0),
00317 current_element(NULL),
00318 cache(blocks_per_page * 2),
00319 cache_buffers(cache.begin()),
00320 overlap_buffers(cache.begin() + blocks_per_page),
00321 requests(blocks_per_page),
00322 bids(0)
00323 {
00324 bids.reserve(blocks_per_page);
00325
00326 stack_type stack_copy = stack_;
00327 const size_type sz = stack_copy.size();
00328 size_type i;
00329
00330 std::vector<value_type> tmp(sz);
00331
00332 for (i = 0; i < sz; ++i)
00333 {
00334 tmp[sz - i - 1] = stack_copy.top();
00335 stack_copy.pop();
00336 }
00337 for (i = 0; i < sz; ++i)
00338 this->push(tmp[i]);
00339 }
00340 virtual ~grow_shrink_stack()
00341 {
00342 STXXL_VERBOSE(STXXL_PRETTY_FUNCTION_NAME);
00343 try
00344 {
00345 if (requests[0].get())
00346 wait_all(requests.begin(), blocks_per_page);
00347 }
00348 catch (const io_error & ex)
00349 { }
00350 block_manager::get_instance()->delete_blocks(bids.begin(), bids.end());
00351 }
00352 size_type size() const
00353 {
00354 return size_;
00355 }
00356 bool empty() const
00357 {
00358 return (!size_);
00359 }
00360 value_type & top()
00361 {
00362 assert(size_ > 0);
00363 return (*current_element);
00364 }
00365 const value_type & top() const
00366 {
00367 assert(size_ > 0);
00368 return (*current_element);
00369 }
00370 void push(const value_type & val)
00371 {
00372 assert(cache_offset <= blocks_per_page * block_type::size);
00373
00374
00375 if (cache_offset == blocks_per_page * block_type::size)
00376 {
00377 STXXL_VERBOSE2("growing, size: " << size_);
00378
00379 bids.resize(bids.size() + blocks_per_page);
00380 typename std::vector<bid_type>::iterator cur_bid = bids.end() - blocks_per_page;
00381 block_manager::get_instance()->new_blocks(alloc_strategy, cur_bid, bids.end(), cur_bid - bids.begin());
00382
00383 for (int i = 0; i < blocks_per_page; ++i, ++cur_bid)
00384 {
00385 if (requests[i].get())
00386 requests[i]->wait();
00387
00388 requests[i] = (cache_buffers + i)->write(*cur_bid);
00389 }
00390
00391 std::swap(cache_buffers, overlap_buffers);
00392
00393 bids.reserve(bids.size() + blocks_per_page);
00394
00395 cache_offset = 1;
00396 current_element = &((*cache_buffers)[0]);
00397 ++size_;
00398
00399 *current_element = val;
00400
00401 return;
00402 }
00403
00404 current_element = &((*(cache_buffers + cache_offset / block_type::size))[cache_offset % block_type::size]);
00405 *current_element = val;
00406 ++size_;
00407 ++cache_offset;
00408 }
00409 void pop()
00410 {
00411 assert(cache_offset <= blocks_per_page * block_type::size);
00412 assert(cache_offset > 0);
00413 assert(size_ > 0);
00414
00415 if (cache_offset == 1 && bids.size() >= blocks_per_page)
00416 {
00417 STXXL_VERBOSE2("shrinking, size: " << size_);
00418
00419 if (requests[0].get())
00420 wait_all(requests.begin(), blocks_per_page);
00421
00422
00423 std::swap(cache_buffers, overlap_buffers);
00424
00425 if (bids.size() > blocks_per_page)
00426 {
00427 STXXL_VERBOSE2("prefetching, size: " << size_);
00428 typename std::vector<bid_type>::const_iterator cur_bid = bids.end() - blocks_per_page;
00429 for (int i = blocks_per_page - 1; i >= 0; --i)
00430 requests[i] = (overlap_buffers + i)->read(*(--cur_bid));
00431 }
00432
00433 block_manager::get_instance()->delete_blocks(bids.end() - blocks_per_page, bids.end());
00434 bids.resize(bids.size() - blocks_per_page);
00435
00436 cache_offset = blocks_per_page * block_type::size;
00437 --size_;
00438 current_element = &((*(cache_buffers + (blocks_per_page - 1)))[block_type::size - 1]);
00439
00440 return;
00441 }
00442
00443 --size_;
00444 unsigned_type cur_offset = (--cache_offset) - 1;
00445 current_element = &((*(cache_buffers + cur_offset / block_type::size))[cur_offset % block_type::size]);
00446 }
00447 };
00448
00451 template <class Config_>
00452 class grow_shrink_stack2 : private noncopyable
00453 {
00454 public:
00455 typedef Config_ cfg;
00456 typedef typename cfg::value_type value_type;
00457 typedef typename cfg::alloc_strategy alloc_strategy_type;
00458 typedef typename cfg::size_type size_type;
00459 enum {
00460 blocks_per_page = cfg::blocks_per_page,
00461 block_size = cfg::block_size,
00462 };
00463
00464 typedef typed_block<block_size, value_type> block_type;
00465 typedef BID<block_size> bid_type;
00466
00467 private:
00468 typedef read_write_pool<block_type> pool_type;
00469
00470 size_type size_;
00471 unsigned_type cache_offset;
00472 block_type * cache;
00473 std::vector<bid_type> bids;
00474 alloc_strategy_type alloc_strategy;
00475 unsigned_type pref_aggr;
00476 pool_type * owned_pool;
00477 pool_type * pool;
00478
00479 public:
00483 grow_shrink_stack2(
00484 pool_type & pool_,
00485 unsigned_type prefetch_aggressiveness = 0) :
00486 size_(0),
00487 cache_offset(0),
00488 cache(new block_type),
00489 pref_aggr(prefetch_aggressiveness),
00490 owned_pool(NULL),
00491 pool(&pool_)
00492 {
00493 STXXL_VERBOSE2("grow_shrink_stack2::grow_shrink_stack2(...)");
00494 }
00495
00500 _STXXL_DEPRECATED(grow_shrink_stack2(
00501 prefetch_pool<block_type> & p_pool_,
00502 write_pool<block_type> & w_pool_,
00503 unsigned_type prefetch_aggressiveness = 0)) :
00504 size_(0),
00505 cache_offset(0),
00506 cache(new block_type),
00507 pref_aggr(prefetch_aggressiveness),
00508 owned_pool(new pool_type(p_pool_, w_pool_)),
00509 pool(owned_pool)
00510 {
00511 STXXL_VERBOSE2("grow_shrink_stack2::grow_shrink_stack2(...)");
00512 }
00513
00514 void swap(grow_shrink_stack2 & obj)
00515 {
00516 std::swap(size_, obj.size_);
00517 std::swap(cache_offset, obj.cache_offset);
00518 std::swap(cache, obj.cache);
00519 std::swap(bids, obj.bids);
00520 std::swap(alloc_strategy, obj.alloc_strategy);
00521 std::swap(pref_aggr, obj.pref_aggr);
00522 std::swap(owned_pool, obj.owned_pool);
00523 std::swap(pool, obj.pool);
00524 }
00525
00526 virtual ~grow_shrink_stack2()
00527 {
00528 try
00529 {
00530 STXXL_VERBOSE2("grow_shrink_stack2::~grow_shrink_stack2()");
00531 const int_type bids_size = bids.size();
00532 const int_type last_pref = STXXL_MAX(int_type(bids_size) - int_type(pref_aggr), (int_type)0);
00533 int_type i;
00534 for (i = bids_size - 1; i >= last_pref; --i)
00535 {
00536
00537 pool->invalidate(bids[i]);
00538 }
00539 typename std::vector<bid_type>::iterator cur = bids.begin();
00540 typename std::vector<bid_type>::const_iterator end = bids.end();
00541 for ( ; cur != end; ++cur)
00542 {
00543
00544 block_type * b = NULL;
00545 if (b)
00546 {
00547 pool->add(cache);
00548 cache = b;
00549 }
00550 }
00551 delete cache;
00552 }
00553 catch (const io_error & ex)
00554 { }
00555 block_manager::get_instance()->delete_blocks(bids.begin(), bids.end());
00556 delete owned_pool;
00557 }
00558
00559 size_type size() const
00560 {
00561 return size_;
00562 }
00563
00564 bool empty() const
00565 {
00566 return (!size_);
00567 }
00568
00569 void push(const value_type & val)
00570 {
00571 STXXL_VERBOSE3("grow_shrink_stack2::push(" << val << ")");
00572 assert(cache_offset <= block_type::size);
00573
00574 if (cache_offset == block_type::size)
00575 {
00576 STXXL_VERBOSE2("grow_shrink_stack2::push(" << val << ") growing, size: " << size_);
00577
00578 bids.resize(bids.size() + 1);
00579 typename std::vector<bid_type>::iterator cur_bid = bids.end() - 1;
00580 block_manager::get_instance()->new_blocks(alloc_strategy, cur_bid, bids.end(), cur_bid - bids.begin());
00581 pool->write(cache, bids.back());
00582 cache = pool->steal();
00583 const int_type bids_size = bids.size();
00584 const int_type last_pref = STXXL_MAX(int_type(bids_size) - int_type(pref_aggr) - 1, (int_type)0);
00585 for (int_type i = bids_size - 2; i >= last_pref; --i)
00586 {
00587
00588 pool->invalidate(bids[i]);
00589 }
00590 cache_offset = 0;
00591 }
00592 (*cache)[cache_offset] = val;
00593 ++size_;
00594 ++cache_offset;
00595
00596 assert(cache_offset > 0);
00597 assert(cache_offset <= block_type::size);
00598 }
00599
00600 value_type & top()
00601 {
00602 assert(size_ > 0);
00603 assert(cache_offset > 0);
00604 assert(cache_offset <= block_type::size);
00605 return (*cache)[cache_offset - 1];
00606 }
00607
00608 const value_type & top() const
00609 {
00610 assert(size_ > 0);
00611 assert(cache_offset > 0);
00612 assert(cache_offset <= block_type::size);
00613 return (*cache)[cache_offset - 1];
00614 }
00615
00616 void pop()
00617 {
00618 STXXL_VERBOSE3("grow_shrink_stack2::pop()");
00619 assert(size_ > 0);
00620 assert(cache_offset > 0);
00621 assert(cache_offset <= block_type::size);
00622 if (cache_offset == 1 && (!bids.empty()))
00623 {
00624 STXXL_VERBOSE2("grow_shrink_stack2::pop() shrinking, size = " << size_);
00625
00626 bid_type last_block = bids.back();
00627 bids.pop_back();
00628 pool->read(cache, last_block)->wait();
00629 block_manager::get_instance()->delete_block(last_block);
00630 rehint();
00631 cache_offset = block_type::size + 1;
00632 }
00633
00634 --cache_offset;
00635 --size_;
00636 }
00637
00641 void set_prefetch_aggr(unsigned_type new_p)
00642 {
00643 if (pref_aggr > new_p)
00644 {
00645 const int_type bids_size = bids.size();
00646 const int_type last_pref = STXXL_MAX(int_type(bids_size) - int_type(pref_aggr), (int_type)0);
00647 for (int_type i = bids_size - new_p - 1; i >= last_pref; --i)
00648 {
00649
00650 pool->invalidate(bids[i]);
00651 }
00652 }
00653 pref_aggr = new_p;
00654 rehint();
00655 }
00656
00658 unsigned_type get_prefetch_aggr() const
00659 {
00660 return pref_aggr;
00661 }
00662
00663 private:
00665 void rehint()
00666 {
00667 const int_type bids_size = bids.size();
00668 const int_type last_pref = STXXL_MAX(int_type(bids_size) - int_type(pref_aggr), (int_type)0);
00669 for (int_type i = bids_size - 1; i >= last_pref; --i)
00670 {
00671 pool->hint(bids[i]);
00672 }
00673 }
00674 };
00675
00676
00678
00680 template <unsigned_type CritSize, class ExternalStack, class InternalStack>
00681 class migrating_stack : private noncopyable
00682 {
00683 public:
00684 typedef typename ExternalStack::cfg cfg;
00685 typedef typename cfg::value_type value_type;
00686 typedef typename cfg::size_type size_type;
00687 enum {
00688 blocks_per_page = cfg::blocks_per_page,
00689 block_size = cfg::block_size
00690 };
00691
00692
00693 typedef InternalStack int_stack_type;
00694 typedef ExternalStack ext_stack_type;
00695
00696 private:
00697 enum { critical_size = CritSize };
00698
00699 int_stack_type * int_impl;
00700 ext_stack_type * ext_impl;
00701
00702
00703 template <class stack_type>
00704 migrating_stack(const stack_type & stack_);
00705
00706 public:
00707 migrating_stack() : int_impl(new int_stack_type()), ext_impl(NULL) { }
00708
00709 void swap(migrating_stack & obj)
00710 {
00711 std::swap(int_impl, obj.int_impl);
00712 std::swap(ext_impl, obj.ext_impl);
00713 }
00714
00716 bool internal() const
00717 {
00718 assert((int_impl && !ext_impl) || (!int_impl && ext_impl));
00719 return int_impl;
00720 }
00722 bool external() const
00723 {
00724 assert((int_impl && !ext_impl) || (!int_impl && ext_impl));
00725 return ext_impl;
00726 }
00727
00728 bool empty() const
00729 {
00730 assert((int_impl && !ext_impl) || (!int_impl && ext_impl));
00731 return (int_impl) ? int_impl->empty() : ext_impl->empty();
00732 }
00733 size_type size() const
00734 {
00735 assert((int_impl && !ext_impl) || (!int_impl && ext_impl));
00736 return (int_impl) ? int_impl->size() : ext_impl->size();
00737 }
00738 value_type & top()
00739 {
00740 assert((int_impl && !ext_impl) || (!int_impl && ext_impl));
00741 return (int_impl) ? int_impl->top() : ext_impl->top();
00742 }
00743 const value_type & top() const
00744 {
00745 assert((int_impl && !ext_impl) || (!int_impl && ext_impl));
00746 return (int_impl) ? int_impl->top() : ext_impl->top();
00747 }
00748 void push(const value_type & val)
00749 {
00750 assert((int_impl && !ext_impl) || (!int_impl && ext_impl));
00751
00752 if (int_impl)
00753 {
00754 int_impl->push(val);
00755 if (int_impl->size() == critical_size)
00756 {
00757
00758 ext_impl = new ext_stack_type(*int_impl);
00759 delete int_impl;
00760 int_impl = NULL;
00761 }
00762 }
00763 else
00764 ext_impl->push(val);
00765 }
00766 void pop()
00767 {
00768 assert((int_impl && !ext_impl) || (!int_impl && ext_impl));
00769
00770 if (int_impl)
00771 int_impl->pop();
00772 else
00773 ext_impl->pop();
00774 }
00775 virtual ~migrating_stack()
00776 {
00777 delete int_impl;
00778 delete ext_impl;
00779 }
00780 };
00781
00783
00784
00787
00788 enum stack_externality { external, migrating, internal };
00789 enum stack_behaviour { normal, grow_shrink, grow_shrink2 };
00790
00792
00828 template <
00829 class ValTp,
00830 stack_externality Externality = external,
00831 stack_behaviour Behaviour = normal,
00832 unsigned BlocksPerPage = 4,
00833 unsigned BlkSz = STXXL_DEFAULT_BLOCK_SIZE(ValTp),
00834
00835 class IntStackTp = std::stack<ValTp>,
00836 unsigned_type MigrCritSize = (2 * BlocksPerPage * BlkSz),
00837
00838 class AllocStr = STXXL_DEFAULT_ALLOC_STRATEGY,
00839 class SzTp = stxxl::int64
00840 >
00841 class STACK_GENERATOR
00842 {
00843 typedef stack_config_generator<ValTp, BlocksPerPage, BlkSz, AllocStr, SzTp> cfg;
00844
00845 typedef typename IF<Behaviour == grow_shrink,
00846 grow_shrink_stack<cfg>,
00847 grow_shrink_stack2<cfg> >::result GrShrTp;
00848 typedef typename IF<Behaviour == normal, normal_stack<cfg>, GrShrTp>::result ExtStackTp;
00849 typedef typename IF<Externality == migrating,
00850 migrating_stack<MigrCritSize, ExtStackTp, IntStackTp>, ExtStackTp>::result MigrOrNotStackTp;
00851
00852 public:
00853 typedef typename IF<Externality == internal, IntStackTp, MigrOrNotStackTp>::result result;
00854 };
00855
00857
00858 __STXXL_END_NAMESPACE
00859
00860
00861 namespace std
00862 {
00863 template <class Config_>
00864 void swap(stxxl::normal_stack<Config_> & a,
00865 stxxl::normal_stack<Config_> & b)
00866 {
00867 a.swap(b);
00868 }
00869
00870 template <class Config_>
00871 void swap(stxxl::grow_shrink_stack<Config_> & a,
00872 stxxl::grow_shrink_stack<Config_> & b)
00873 {
00874 a.swap(b);
00875 }
00876
00877 template <class Config_>
00878 void swap(stxxl::grow_shrink_stack2<Config_> & a,
00879 stxxl::grow_shrink_stack2<Config_> & b)
00880 {
00881 a.swap(b);
00882 }
00883
00884 template <stxxl::unsigned_type CritSize, class ExternalStack, class InternalStack>
00885 void swap(stxxl::migrating_stack<CritSize, ExternalStack, InternalStack> & a,
00886 stxxl::migrating_stack<CritSize, ExternalStack, InternalStack> & b)
00887 {
00888 a.swap(b);
00889 }
00890 }
00891
00892 #endif // !STXXL_STACK_HEADER
00893