Stxxl  1.4.0
include/stxxl/bits/containers/btree/leaf.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  include/stxxl/bits/containers/btree/leaf.h
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2006 Roman Dementiev <dementiev@ira.uka.de>
00007  *
00008  *  Distributed under the Boost Software License, Version 1.0.
00009  *  (See accompanying file LICENSE_1_0.txt or copy at
00010  *  http://www.boost.org/LICENSE_1_0.txt)
00011  **************************************************************************/
00012 
00013 #ifndef STXXL_CONTAINERS_BTREE__LEAF_H
00014 #define STXXL_CONTAINERS_BTREE__LEAF_H
00015 
00016 #include <stxxl/bits/containers/btree/iterator.h>
00017 #include <stxxl/bits/containers/btree/node_cache.h>
00018 
00019 
00020 __STXXL_BEGIN_NAMESPACE
00021 
00022 namespace btree
00023 {
00024     template <class NodeType, class BTreeType>
00025     class node_cache;
00026 
00027     template <class KeyType_, class DataType_, class KeyCmp_, unsigned RawSize_, class BTreeType>
00028     class normal_leaf : private noncopyable
00029     {
00030     public:
00031         typedef normal_leaf<KeyType_, DataType_, KeyCmp_, RawSize_, BTreeType> SelfType;
00032 
00033         friend class node_cache<SelfType, BTreeType>;
00034 
00035         typedef KeyType_ key_type;
00036         typedef DataType_ data_type;
00037         typedef KeyCmp_ key_compare;
00038         typedef std::pair<key_type, data_type> value_type;
00039         typedef value_type & reference;
00040         typedef const value_type & const_reference;
00041 
00042         enum {
00043             raw_size = RawSize_
00044         };
00045         typedef BID<raw_size> bid_type;
00046         struct InfoType
00047         {
00048             bid_type me, pred, succ;
00049             unsigned cur_size;
00050         };
00051 
00052         typedef typed_block<raw_size, value_type, 0, InfoType> block_type;
00053         enum {
00054             nelements = block_type::size - 1,
00055             max_size = nelements,
00056             min_size = nelements / 2
00057         };
00058 
00059         typedef BTreeType btree_type;
00060         typedef typename btree_type::size_type size_type;
00061         typedef btree_iterator_base<btree_type> iterator_base;
00062         typedef btree_iterator<btree_type> iterator;
00063         typedef btree_const_iterator<btree_type> const_iterator;
00064 
00065         typedef node_cache<normal_leaf, btree_type> leaf_cache_type;
00066 
00067     public:
00068         struct value_compare : public std::binary_function<value_type, value_type, bool>
00069         {
00070             key_compare comp;
00071 
00072             value_compare(key_compare c) : comp(c) { }
00073 
00074             bool operator () (const value_type & x, const value_type & y) const
00075             {
00076                 return comp(x.first, y.first);
00077             }
00078         };
00079 
00080     private:
00081         block_type * block_;
00082         btree_type * btree_;
00083 
00084         key_compare cmp_;
00085         value_compare vcmp_;
00086 
00087         void split(std::pair<key_type, bid_type> & splitter)
00088         {
00089             bid_type NewBid;
00090             btree_->leaf_cache_.get_new_node(NewBid);                     // new (left) leaf
00091             normal_leaf * NewLeaf = btree_->leaf_cache_.get_node(NewBid, true);
00092             assert(NewLeaf);
00093 
00094             // update links
00095             NewLeaf->succ() = my_bid();
00096             normal_leaf * PredLeaf = NULL;
00097             if (pred().valid())
00098             {
00099                 NewLeaf->pred() = pred();
00100                 PredLeaf = btree_->leaf_cache_.get_node(pred());
00101                 assert(PredLeaf);
00102                 assert(vcmp_(PredLeaf->back(), front()));
00103                 PredLeaf->succ() = NewBid;
00104             }
00105             pred() = NewBid;
00106 
00107             std::vector<iterator_base *> Iterators2Fix;
00108             btree_->iterator_map_.find(my_bid(), 0, size(), Iterators2Fix);
00109 
00110             const unsigned end_of_smaller_part = size() / 2;
00111 
00112             splitter.first = ((*block_)[end_of_smaller_part - 1]).first;
00113             splitter.second = NewBid;
00114 
00115             const unsigned old_size = size();
00116             // copy the smaller part
00117             std::copy(block_->begin(), block_->begin() + end_of_smaller_part, NewLeaf->block_->begin());
00118             NewLeaf->block_->info.cur_size = end_of_smaller_part;
00119             // copy the larger part
00120             std::copy(block_->begin() + end_of_smaller_part,
00121                       block_->begin() + old_size, block_->begin());
00122             block_->info.cur_size = old_size - end_of_smaller_part;
00123             assert(size() + NewLeaf->size() == old_size);
00124 
00125             // fix iterators
00126             typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix.begin();
00127             for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
00128             {
00129                 btree_->iterator_map_.unregister_iterator(**it2fix);
00130 
00131                 if ((*it2fix)->pos < end_of_smaller_part) // belongs to the smaller part
00132                     (*it2fix)->bid = NewBid;
00133 
00134                 else
00135                     (*it2fix)->pos -= end_of_smaller_part;
00136 
00137 
00138                 btree_->iterator_map_.register_iterator(**it2fix);
00139             }
00140 
00141 
00142             STXXL_VERBOSE1("btree::normal_leaf split leaf " << this
00143                                                             << " splitter: " << splitter.first);
00144 
00145 #if STXXL_VERBOSE_LEVEL >= 1
00146             if (PredLeaf)
00147             {
00148                 STXXL_VERBOSE1("btree::normal_leaf pred_part.smallest    = " << PredLeaf->front().first);
00149                 STXXL_VERBOSE1("btree::normal_leaf pred_part.largest     = " << PredLeaf->back().first);
00150             }
00151 #endif
00152             STXXL_VERBOSE1("btree::normal_leaf smaller_part.smallest = " << NewLeaf->front().first);
00153             STXXL_VERBOSE1("btree::normal_leaf smaller_part.largest  = " << NewLeaf->back().first);
00154             STXXL_VERBOSE1("btree::normal_leaf larger_part.smallest  = " << front().first);
00155             STXXL_VERBOSE1("btree::normal_leaf larger_part.largest   = " << back().first);
00156 
00157             btree_->leaf_cache_.unfix_node(NewBid);
00158         }
00159 
00160     public:
00161         virtual ~normal_leaf()
00162         {
00163             delete block_;
00164         }
00165 
00166         normal_leaf(btree_type * btree__,
00167                     key_compare cmp) :
00168             block_(new block_type),
00169             btree_(btree__),
00170             cmp_(cmp),
00171             vcmp_(cmp)
00172         {
00173             assert(min_nelements() >= 2);
00174             assert(2 * min_nelements() - 1 <= max_nelements());
00175             assert(max_nelements() <= nelements);
00176             assert(unsigned(block_type::size) >= nelements + 1);                   // extra space for an overflow
00177         }
00178 
00179         bool overflows() const { return block_->info.cur_size > max_nelements(); }
00180         bool underflows() const { return block_->info.cur_size < min_nelements(); }
00181 
00182         unsigned max_nelements() const { return max_size; }
00183         unsigned min_nelements() const { return min_size; }
00184 
00185 
00186         bid_type & succ()
00187         {
00188             return block_->info.succ;
00189         }
00190         bid_type & pred()
00191         {
00192             return block_->info.pred;
00193         }
00194 
00195         const bid_type & succ() const
00196         {
00197             return block_->info.succ;
00198         }
00199         const bid_type & pred() const
00200         {
00201             return block_->info.pred;
00202         }
00203 
00204         /*
00205            template <class InputIterator>
00206            normal_leaf(InputIterator begin_, InputIterator end_,
00207                 btree_type * btree__,
00208                 key_compare cmp):
00209                 block_(new block_type),
00210                 btree_(btree__),
00211                 cmp_(cmp),
00212                 vcmp_(cmp)
00213            {
00214                 assert(min_nelements() >=2);
00215                 assert(2*min_nelements() - 1 <= max_nelements());
00216                 assert(max_nelements() <= nelements);
00217                 assert(unsigned(block_type::size) >= nelements +1); // extra space for an overflow element
00218 
00219                 unsigned new_size = end_ - begin_;
00220                 assert(new_size <= max_nelements());
00221                 assert(new_size >= min_nelements());
00222 
00223                 std::copy(begin_,end_,block_->begin());
00224                 assert(stxxl::is_sorted(block_->begin(),block_->begin() + new_size, vcmp_));
00225                 block_->info.cur_size = new_size;
00226            }*/
00227 
00228         unsigned size() const
00229         {
00230             return block_->info.cur_size;
00231         }
00232 
00233         const bid_type & my_bid() const
00234         {
00235             return block_->info.me;
00236         }
00237 
00238         void save()
00239         {
00240             request_ptr req = block_->write(my_bid());
00241             req->wait();
00242         }
00243 
00244         request_ptr load(const bid_type & bid)
00245         {
00246             request_ptr req = block_->read(bid);
00247             req->wait();
00248             assert(bid == my_bid());
00249             return req;
00250         }
00251 
00252         request_ptr prefetch(const bid_type & bid)
00253         {
00254             return block_->read(bid);
00255         }
00256 
00257         void init(const bid_type & my_bid_)
00258         {
00259             block_->info.me = my_bid_;
00260             block_->info.succ = bid_type();
00261             block_->info.pred = bid_type();
00262             block_->info.cur_size = 0;
00263         }
00264 
00265         reference operator [] (int i)
00266         {
00267             return (*block_)[i];
00268         }
00269 
00270         const_reference operator [] (int i) const
00271         {
00272             return (*block_)[i];
00273         }
00274 
00275         reference back()
00276         {
00277             return (*block_)[size() - 1];
00278         }
00279 
00280         reference front()
00281         {
00282             return *(block_->begin());
00283         }
00284 
00285         const_reference back() const
00286         {
00287             return (*block_)[size() - 1];
00288         }
00289 
00290         const_reference front() const
00291         {
00292             return *(block_->begin());
00293         }
00294 
00295         void dump()
00296         {
00297             STXXL_VERBOSE2("Dump of leaf " << this);
00298             for (unsigned i = 0; i < size(); ++i)
00299                 STXXL_VERBOSE2((*this)[i].first << " " << (*this)[i].second);
00300         }
00301 
00302         std::pair<iterator, bool> insert(
00303             const value_type & x,
00304             std::pair<key_type, bid_type> & splitter)
00305         {
00306             assert(size() <= max_nelements());
00307             splitter.first = key_compare::max_value();
00308 
00309             typename block_type::iterator it =
00310                 std::lower_bound(block_->begin(), block_->begin() + size(), x, vcmp_);
00311 
00312             if (!(vcmp_(*it, x) || vcmp_(x, *it)) && it != (block_->begin() + size()))                // *it == x
00313             {
00314                 // already exists
00315                 return std::pair<iterator, bool>(
00316                            iterator(btree_, my_bid(), it - block_->begin()),
00317                            false);
00318             }
00319 
00320             typename block_type::iterator cur = block_->begin() + size() - 1;
00321 
00322             for ( ; cur >= it; --cur)
00323                 *(cur + 1) = *cur;
00324             // move elements to make space for the new element
00325 
00326             *it = x;
00327 
00328             std::vector<iterator_base *> Iterators2Fix;
00329             btree_->iterator_map_.find(my_bid(), it - block_->begin(), size(), Iterators2Fix);
00330             typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix.begin();
00331             for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
00332             {
00333                 btree_->iterator_map_.unregister_iterator(**it2fix);
00334                 ++((*it2fix)->pos);                        // fixing iterators
00335                 btree_->iterator_map_.register_iterator(**it2fix);
00336             }
00337 
00338             ++(block_->info.cur_size);
00339 
00340             std::pair<iterator, bool> result(iterator(btree_, my_bid(), it - block_->begin()), true);
00341 
00342             if (size() <= max_nelements())
00343             {
00344                 // no overflow
00345                 dump();
00346                 return result;
00347             }
00348 
00349             // overflow
00350 
00351             split(splitter);
00352 
00353             return result;
00354         }
00355 
00356         iterator begin()
00357         {
00358             return iterator(btree_, my_bid(), 0);
00359         }
00360 
00361         const_iterator begin() const
00362         {
00363             return const_iterator(btree_, my_bid(), 0);
00364         }
00365 
00366         iterator end()
00367         {
00368             return iterator(btree_, my_bid(), size());
00369         }
00370 
00371         void increment_iterator(iterator_base & it) const
00372         {
00373             assert(it.bid == my_bid());
00374             assert(it.pos != size());
00375 
00376             btree_->iterator_map_.unregister_iterator(it);
00377 
00378             ++(it.pos);
00379             if (it.pos == size() && succ().valid())
00380             {
00381                 // run to the end of the leaf
00382                 STXXL_VERBOSE1("btree::normal_leaf jumping to the next block");
00383                 it.pos = 0;
00384                 it.bid = succ();
00385             } else if (it.pos == 1 && btree_->prefetching_enabled_)                    // increment of pos from 0 to 1
00386             {
00387                 // prefetch the succ leaf
00388                 if (succ().valid())
00389                     btree_->leaf_cache_.prefetch_node(succ());
00390             }
00391             btree_->iterator_map_.register_iterator(it);
00392         }
00393 
00394         void decrement_iterator(iterator_base & it) const
00395         {
00396             assert(it.bid == my_bid());
00397 
00398             btree_->iterator_map_.unregister_iterator(it);
00399 
00400             if (it.pos == 0)
00401             {
00402                 assert(pred().valid());
00403 
00404                 it.bid = pred();
00405                 normal_leaf const * PredLeaf = btree_->leaf_cache_.get_const_node(pred(), true);
00406                 assert(PredLeaf);
00407                 it.pos = PredLeaf->size() - 1;
00408 
00409                 // prefetch the pred leaf of PredLeaf
00410                 if (btree_->prefetching_enabled_ && PredLeaf->pred().valid())
00411                     btree_->leaf_cache_.prefetch_node(PredLeaf->pred());
00412 
00413 
00414                 btree_->leaf_cache_.unfix_node(pred());
00415             }
00416             else
00417                 --it.pos;
00418 
00419 
00420             btree_->iterator_map_.register_iterator(it);
00421         }
00422 
00423         iterator find(const key_type & k)
00424         {
00425             value_type searchVal(k, data_type());
00426             typename block_type::iterator lb =
00427                 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
00428             if (lb == block_->begin() + size() || lb->first != k)
00429                 return btree_->end();
00430 
00431 
00432             return iterator(btree_, my_bid(), lb - block_->begin());
00433         }
00434 
00435         const_iterator find(const key_type & k) const
00436         {
00437             value_type searchVal(k, data_type());
00438             typename block_type::iterator lb =
00439                 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
00440             if (lb == block_->begin() + size() || lb->first != k)
00441                 return btree_->end();
00442 
00443 
00444             return const_iterator(btree_, my_bid(), lb - block_->begin());
00445         }
00446 
00447         iterator lower_bound(const key_type & k)
00448         {
00449             value_type searchVal(k, data_type());
00450 
00451             typename block_type::iterator lb =
00452                 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
00453 
00454             // lower_bound is in the succ block
00455             if (lb == block_->begin() + size() && succ().valid())
00456             {
00457                 return iterator(btree_, succ(), 0);
00458             }
00459 
00460             return iterator(btree_, my_bid(), lb - block_->begin());
00461         }
00462 
00463         const_iterator lower_bound(const key_type & k) const
00464         {
00465             value_type searchVal(k, data_type());
00466             typename block_type::iterator lb =
00467                 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
00468 
00469             // lower_bound is in the succ block
00470             if (lb == block_->begin() + size() && succ().valid())
00471             {
00472                 return iterator(btree_, succ(), 0);
00473             }
00474 
00475             return const_iterator(btree_, my_bid(), lb - block_->begin());
00476         }
00477 
00478         iterator upper_bound(const key_type & k)
00479         {
00480             value_type searchVal(k, data_type());
00481             typename block_type::iterator lb =
00482                 std::upper_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
00483 
00484             // upper_bound is in the succ block
00485             if (lb == block_->begin() + size() && succ().valid())
00486             {
00487                 return iterator(btree_, succ(), 0);
00488             }
00489 
00490             return iterator(btree_, my_bid(), lb - block_->begin());
00491         }
00492 
00493         const_iterator upper_bound(const key_type & k) const
00494         {
00495             value_type searchVal(k, data_type());
00496             typename block_type::iterator lb =
00497                 std::upper_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
00498 
00499             // upper_bound is in the succ block
00500             if (lb == block_->begin() + size() && succ().valid())
00501             {
00502                 return const_iterator(btree_, succ(), 0);
00503             }
00504 
00505             return const_iterator(btree_, my_bid(), lb - block_->begin());
00506         }
00507 
00508         size_type erase(const key_type & k)
00509         {
00510             value_type searchVal(k, data_type());
00511             typename block_type::iterator it =
00512                 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
00513 
00514             if (it == block_->begin() + size() || it->first != k)
00515                 return 0;
00516             // no such element
00517 
00518             // move elements one position left
00519             std::copy(it + 1, block_->begin() + size(), it);
00520 
00521             std::vector<iterator_base *> Iterators2Fix;
00522             btree_->iterator_map_.find(my_bid(), it + 1 - block_->begin(), size(), Iterators2Fix);
00523             typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix.begin();
00524             for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
00525             {
00526                 STXXL_VERBOSE2("btree::normal_leaf updating iterator " << (*it2fix) << " (pos--)");
00527                 btree_->iterator_map_.unregister_iterator(**it2fix);
00528                 --((*it2fix)->pos);                        // fixing iterators
00529                 btree_->iterator_map_.register_iterator(**it2fix);
00530             }
00531 
00532             --(block_->info.cur_size);
00533 
00534             return 1;
00535         }
00536 
00537         void fuse(const normal_leaf & Src)
00538         {
00539             STXXL_VERBOSE1("btree::normal_leaf Fusing");
00540             assert(vcmp_(Src.back(), front()));
00541             const unsigned SrcSize = Src.size();
00542 
00543             typename block_type::iterator cur = block_->begin() + size() - 1;
00544             typename block_type::const_iterator begin = block_->begin();
00545 
00546             for ( ; cur >= begin; --cur)
00547                 *(cur + SrcSize) = *cur;
00548             // move elements to make space for Src elements
00549 
00550             // copy Src to *this leaf
00551             std::copy(Src.block_->begin(), Src.block_->begin() + SrcSize, block_->begin());
00552 
00553 
00554             std::vector<iterator_base *> Iterators2Fix;
00555             btree_->iterator_map_.find(my_bid(), 0, size(), Iterators2Fix);
00556             typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix.begin();
00557             for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
00558             {
00559                 STXXL_VERBOSE2("btree::normal_leaf updating iterator " << (*it2fix) <<
00560                                " (pos+" << SrcSize << ")");
00561                 btree_->iterator_map_.unregister_iterator(**it2fix);
00562                 ((*it2fix)->pos) += SrcSize;                       // fixing iterators
00563                 btree_->iterator_map_.register_iterator(**it2fix);
00564             }
00565 
00566             Iterators2Fix.clear();
00567             btree_->iterator_map_.find(Src.my_bid(), 0, SrcSize, Iterators2Fix);
00568             it2fix = Iterators2Fix.begin();
00569             for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
00570             {
00571                 STXXL_VERBOSE2("btree::normal_leaf updating iterator " << (*it2fix) <<
00572                                " (bid=" << my_bid() << ")");
00573                 btree_->iterator_map_.unregister_iterator(**it2fix);
00574                 ((*it2fix)->bid) = my_bid();                         // fixing iterators
00575                 btree_->iterator_map_.register_iterator(**it2fix);
00576             }
00577 
00578             block_->info.cur_size += SrcSize;
00579 
00580             // update links
00581             pred() = Src.pred();
00582             if (pred().valid())
00583             {                     // update successor link
00584                 normal_leaf * NewPred = btree_->leaf_cache_.get_node(pred());
00585                 assert(NewPred);
00586                 NewPred->succ() = my_bid();
00587             }
00588         }
00589 
00590         key_type balance(normal_leaf & Left)
00591         {
00592             STXXL_VERBOSE1("btree::normal_leaf Balancing leaves with bids " <<
00593                            Left.my_bid() << " and " << my_bid());
00594             const unsigned TotalSize = Left.size() + size();
00595             unsigned newLeftSize = TotalSize / 2;
00596             assert(newLeftSize <= Left.max_nelements());
00597             assert(newLeftSize >= Left.min_nelements());
00598             unsigned newRightSize = TotalSize - newLeftSize;
00599             assert(newRightSize <= max_nelements());
00600             assert(newRightSize >= min_nelements());
00601 
00602             assert(vcmp_(Left.back(), front()) || size() == 0);
00603 
00604             if (newLeftSize < Left.size())
00605             {
00606                 const unsigned nEl2Move = Left.size() - newLeftSize;                        // #elements to move from Left to *this
00607 
00608                 typename block_type::iterator cur = block_->begin() + size() - 1;
00609                 typename block_type::const_iterator begin = block_->begin();
00610 
00611                 for ( ; cur >= begin; --cur)
00612                     *(cur + nEl2Move) = *cur;
00613                 // move elements to make space for Src elements
00614 
00615                 // copy Left to *this leaf
00616                 std::copy(Left.block_->begin() + newLeftSize,
00617                           Left.block_->begin() + Left.size(), block_->begin());
00618 
00619                 std::vector<iterator_base *> Iterators2Fix1;
00620                 std::vector<iterator_base *> Iterators2Fix2;
00621                 btree_->iterator_map_.find(my_bid(), 0, size(), Iterators2Fix1);
00622                 btree_->iterator_map_.find(Left.my_bid(), newLeftSize, Left.size(), Iterators2Fix2);
00623 
00624                 typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix1.begin();
00625                 for ( ; it2fix != Iterators2Fix1.end(); ++it2fix)
00626                 {
00627                     STXXL_VERBOSE2("btree::normal_leaf updating iterator " << (*it2fix) <<
00628                                    " (pos+" << nEl2Move << ")");
00629                     btree_->iterator_map_.unregister_iterator(**it2fix);
00630                     ((*it2fix)->pos) += nEl2Move;                           // fixing iterators
00631                     btree_->iterator_map_.register_iterator(**it2fix);
00632                 }
00633 
00634 
00635                 it2fix = Iterators2Fix2.begin();
00636                 for ( ; it2fix != Iterators2Fix2.end(); ++it2fix)
00637                 {
00638                     STXXL_VERBOSE2("btree::normal_leaf updating iterator " << (*it2fix) <<
00639                                    " (pos-" << newLeftSize << " bid=" << my_bid() << ")");
00640                     btree_->iterator_map_.unregister_iterator(**it2fix);
00641                     ((*it2fix)->bid) = my_bid();                                 // fixing iterators
00642                     ((*it2fix)->pos) -= newLeftSize;                             // fixing iterators
00643                     btree_->iterator_map_.register_iterator(**it2fix);
00644                 }
00645             }
00646             else
00647             {
00648                 assert(newRightSize < size());
00649 
00650                 const unsigned nEl2Move = size() - newRightSize;                        // #elements to move from *this to Left
00651 
00652                 // copy *this to Left
00653                 std::copy(block_->begin(),
00654                           block_->begin() + nEl2Move, Left.block_->begin() + Left.size());
00655                 // move elements in *this
00656                 std::copy(block_->begin() + nEl2Move,
00657                           block_->begin() + size(), block_->begin());
00658 
00659                 std::vector<iterator_base *> Iterators2Fix1;
00660                 std::vector<iterator_base *> Iterators2Fix2;
00661                 btree_->iterator_map_.find(my_bid(), nEl2Move, size(), Iterators2Fix1);
00662                 btree_->iterator_map_.find(my_bid(), 0, nEl2Move - 1, Iterators2Fix2);
00663 
00664                 typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix1.begin();
00665                 for ( ; it2fix != Iterators2Fix1.end(); ++it2fix)
00666                 {
00667                     STXXL_VERBOSE2("btree::normal_leaf updating iterator " << (*it2fix) <<
00668                                    " (pos-" << nEl2Move << ")");
00669                     btree_->iterator_map_.unregister_iterator(**it2fix);
00670                     ((*it2fix)->pos) -= nEl2Move;                             // fixing iterators
00671                     btree_->iterator_map_.register_iterator(**it2fix);
00672                 }
00673 
00674 
00675                 it2fix = Iterators2Fix2.begin();
00676                 for ( ; it2fix != Iterators2Fix2.end(); ++it2fix)
00677                 {
00678                     STXXL_VERBOSE2("btree::normal_leaf updating iterator " << (*it2fix) <<
00679                                    " (pos+" << Left.size() << " bid=" << Left.my_bid() << ")");
00680                     btree_->iterator_map_.unregister_iterator(**it2fix);
00681                     ((*it2fix)->bid) = Left.my_bid();                             // fixing iterators
00682                     ((*it2fix)->pos) += Left.size();                              // fixing iterators
00683                     btree_->iterator_map_.register_iterator(**it2fix);
00684                 }
00685             }
00686 
00687             block_->info.cur_size = newRightSize;                         // update size
00688             Left.block_->info.cur_size = newLeftSize;                     // update size
00689 
00690             return Left.back().first;
00691         }
00692 
00693         void push_back(const value_type & x)
00694         {
00695             (*this)[size()] = x;
00696             ++(block_->info.cur_size);
00697         }
00698     };
00699 }
00700 
00701 
00702 __STXXL_END_NAMESPACE
00703 
00704 #endif /* STXXL_CONTAINERS_BTREE__LEAF_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines