Stxxl
1.4.0
|
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 */