Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/containers/btree/node.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__NODE_H 00014 #define STXXL_CONTAINERS_BTREE__NODE_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 KeyCmp_, unsigned RawSize_, class BTreeType> 00028 class normal_node : private noncopyable 00029 { 00030 public: 00031 typedef normal_node<KeyType_, KeyCmp_, RawSize_, BTreeType> SelfType; 00032 00033 friend class node_cache<SelfType, BTreeType>; 00034 00035 typedef KeyType_ key_type; 00036 typedef KeyCmp_ key_compare; 00037 00038 enum { 00039 raw_size = RawSize_ 00040 }; 00041 typedef BID<raw_size> bid_type; 00042 typedef bid_type node_bid_type; 00043 typedef SelfType node_type; 00044 typedef std::pair<key_type, bid_type> value_type; 00045 typedef value_type & reference; 00046 typedef const value_type & const_reference; 00047 00048 00049 struct InfoType 00050 { 00051 bid_type me; 00052 unsigned cur_size; 00053 }; 00054 typedef typed_block<raw_size, value_type, 0, InfoType> block_type; 00055 00056 enum { 00057 nelements = block_type::size - 1, 00058 max_size = nelements, 00059 min_size = nelements / 2 00060 }; 00061 typedef typename block_type::iterator block_iterator; 00062 typedef typename block_type::const_iterator block_const_iterator; 00063 00064 typedef BTreeType btree_type; 00065 typedef typename btree_type::size_type size_type; 00066 typedef typename btree_type::iterator iterator; 00067 typedef typename btree_type::const_iterator const_iterator; 00068 00069 typedef typename btree_type::value_type btree_value_type; 00070 typedef typename btree_type::leaf_bid_type leaf_bid_type; 00071 typedef typename btree_type::leaf_type leaf_type; 00072 00073 typedef node_cache<normal_node, btree_type> node_cache_type; 00074 00075 private: 00076 struct value_compare : public std::binary_function<value_type, value_type, bool> 00077 { 00078 key_compare comp; 00079 00080 value_compare(key_compare c) : comp(c) { } 00081 00082 bool operator () (const value_type & x, const value_type & y) const 00083 { 00084 return comp(x.first, y.first); 00085 } 00086 }; 00087 00088 block_type * block_; 00089 btree_type * btree_; 00090 key_compare cmp_; 00091 value_compare vcmp_; 00092 00093 00094 std::pair<key_type, bid_type> insert(const std::pair<key_type, bid_type> & splitter, 00095 const block_iterator & place2insert) 00096 { 00097 std::pair<key_type, bid_type> result(key_compare::max_value(), bid_type()); 00098 00099 // splitter != *place2insert 00100 assert(vcmp_(*place2insert, splitter) || vcmp_(splitter, *place2insert)); 00101 00102 block_iterator cur = block_->begin() + size() - 1; 00103 for ( ; cur >= place2insert; --cur) 00104 *(cur + 1) = *cur; 00105 // copy elements to make space for the new element 00106 00107 *place2insert = splitter; // insert 00108 00109 ++(block_->info.cur_size); 00110 00111 if (size() > max_nelements()) // overflow! need to split 00112 { 00113 STXXL_VERBOSE1("btree::normal_node::insert overflow happened, splitting"); 00114 00115 bid_type NewBid; 00116 btree_->node_cache_.get_new_node(NewBid); // new (left) node 00117 normal_node * NewNode = btree_->node_cache_.get_node(NewBid, true); 00118 assert(NewNode); 00119 00120 const unsigned end_of_smaller_part = size() / 2; 00121 00122 result.first = ((*block_)[end_of_smaller_part - 1]).first; 00123 result.second = NewBid; 00124 00125 00126 const unsigned old_size = size(); 00127 // copy the smaller part 00128 std::copy(block_->begin(), block_->begin() + end_of_smaller_part, NewNode->block_->begin()); 00129 NewNode->block_->info.cur_size = end_of_smaller_part; 00130 // copy the larger part 00131 std::copy(block_->begin() + end_of_smaller_part, 00132 block_->begin() + old_size, block_->begin()); 00133 block_->info.cur_size = old_size - end_of_smaller_part; 00134 assert(size() + NewNode->size() == old_size); 00135 00136 btree_->node_cache_.unfix_node(NewBid); 00137 00138 STXXL_VERBOSE1("btree::normal_node split leaf " << this 00139 << " splitter: " << result.first); 00140 } 00141 00142 return result; 00143 } 00144 00145 template <class CacheType> 00146 void fuse_or_balance(block_iterator UIt, CacheType & cache_) 00147 { 00148 typedef typename CacheType::node_type local_node_type; 00149 typedef typename local_node_type::bid_type local_bid_type; 00150 00151 block_iterator leftIt, rightIt; 00152 if (UIt == (block_->begin() + size() - 1)) // UIt is the last entry in the root 00153 { 00154 assert(UIt != block_->begin()); 00155 rightIt = UIt; 00156 leftIt = --UIt; 00157 } 00158 else 00159 { 00160 leftIt = UIt; 00161 rightIt = ++UIt; 00162 assert(rightIt != (block_->begin() + size())); 00163 } 00164 00165 // now fuse or balance nodes pointed by leftIt and rightIt 00166 local_bid_type LeftBid = (local_bid_type)leftIt->second; 00167 local_bid_type RightBid = (local_bid_type)rightIt->second; 00168 local_node_type * LeftNode = cache_.get_node(LeftBid, true); 00169 local_node_type * RightNode = cache_.get_node(RightBid, true); 00170 00171 const unsigned TotalSize = LeftNode->size() + RightNode->size(); 00172 if (TotalSize <= RightNode->max_nelements()) 00173 { 00174 // fuse 00175 RightNode->fuse(*LeftNode); // add the content of LeftNode to RightNode 00176 00177 cache_.unfix_node(RightBid); 00178 cache_.delete_node(LeftBid); // 'delete_node' unfixes LeftBid also 00179 00180 std::copy(leftIt + 1, block_->begin() + size(), leftIt); // delete left BID from the root 00181 --(block_->info.cur_size); 00182 } 00183 else 00184 { 00185 // balance 00186 00187 key_type NewSplitter = RightNode->balance(*LeftNode); 00188 00189 00190 leftIt->first = NewSplitter; // change key 00191 assert(vcmp_(*leftIt, *rightIt)); 00192 00193 cache_.unfix_node(LeftBid); 00194 cache_.unfix_node(RightBid); 00195 } 00196 } 00197 00198 public: 00199 virtual ~normal_node() 00200 { 00201 delete block_; 00202 } 00203 00204 normal_node(btree_type * btree__, 00205 key_compare cmp) : 00206 block_(new block_type), 00207 btree_(btree__), 00208 cmp_(cmp), 00209 vcmp_(cmp) 00210 { 00211 assert(min_nelements() >= 2); 00212 assert(2 * min_nelements() - 1 <= max_nelements()); 00213 assert(max_nelements() <= nelements); 00214 assert(unsigned(block_type::size) >= nelements + 1); // extra space for an overflow 00215 } 00216 00217 block_type & block() 00218 { 00219 return *block_; 00220 } 00221 00222 bool overflows() const { return block_->info.cur_size > max_nelements(); } 00223 bool underflows() const { return block_->info.cur_size < min_nelements(); } 00224 00225 unsigned max_nelements() const { return max_size; } 00226 unsigned min_nelements() const { return min_size; } 00227 00228 /* 00229 template <class InputIterator> 00230 normal_node(InputIterator begin_, InputIterator end_, 00231 btree_type * btree__, 00232 key_compare cmp): 00233 block_(new block_type), 00234 btree_(btree__), 00235 cmp_(cmp), 00236 vcmp_(cmp) 00237 { 00238 assert(min_nelements() >=2); 00239 assert(2*min_nelements() - 1 <= max_nelements()); 00240 assert(max_nelements() <= nelements); 00241 assert(unsigned(block_type::size) >= nelements +1); // extra space for an overflow 00242 00243 unsigned new_size = end_ - begin_; 00244 assert(new_size <= max_nelements()); 00245 assert(new_size >= min_nelements()); 00246 00247 std::copy(begin_,end_,block_->begin()); 00248 assert(stxxl::is_sorted(block_->begin(),block_->begin() + new_size, vcmp_)); 00249 block_->info.cur_size = new_size; 00250 }*/ 00251 00252 unsigned size() const 00253 { 00254 return block_->info.cur_size; 00255 } 00256 00257 bid_type my_bid() const 00258 { 00259 return block_->info.me; 00260 } 00261 00262 void save() 00263 { 00264 request_ptr req = block_->write(my_bid()); 00265 req->wait(); 00266 } 00267 00268 request_ptr load(const bid_type & bid) 00269 { 00270 request_ptr req = block_->read(bid); 00271 req->wait(); 00272 assert(bid == my_bid()); 00273 return req; 00274 } 00275 00276 request_ptr prefetch(const bid_type & bid) 00277 { 00278 return block_->read(bid); 00279 } 00280 00281 void init(const bid_type & my_bid_) 00282 { 00283 block_->info.me = my_bid_; 00284 block_->info.cur_size = 0; 00285 } 00286 00287 reference operator [] (int i) 00288 { 00289 return (*block_)[i]; 00290 } 00291 00292 const_reference operator [] (int i) const 00293 { 00294 return (*block_)[i]; 00295 } 00296 00297 reference back() 00298 { 00299 return (*block_)[size() - 1]; 00300 } 00301 00302 reference front() 00303 { 00304 return *(block_->begin()); 00305 } 00306 00307 const_reference back() const 00308 { 00309 return (*block_)[size() - 1]; 00310 } 00311 00312 const_reference front() const 00313 { 00314 return *(block_->begin()); 00315 } 00316 00317 00318 std::pair<iterator, bool> insert( 00319 const btree_value_type & x, 00320 unsigned height, 00321 std::pair<key_type, bid_type> & splitter) 00322 { 00323 assert(size() <= max_nelements()); 00324 splitter.first = key_compare::max_value(); 00325 00326 value_type Key2Search(x.first, bid_type()); 00327 block_iterator it = 00328 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_); 00329 00330 assert(it != (block_->begin() + size())); 00331 00332 bid_type found_bid = it->second; 00333 STXXL_UNUSED(found_bid); 00334 00335 if (height == 2) // found_bid points to a leaf 00336 { 00337 STXXL_VERBOSE1("btree::normal_node Inserting new value into a leaf"); 00338 leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)it->second, true); 00339 assert(Leaf); 00340 std::pair<key_type, leaf_bid_type> BotSplitter; 00341 std::pair<iterator, bool> result = Leaf->insert(x, BotSplitter); 00342 btree_->leaf_cache_.unfix_node((leaf_bid_type)it->second); 00343 //if(key_compare::max_value() == BotSplitter.first) 00344 if (!(cmp_(key_compare::max_value(), BotSplitter.first) || 00345 cmp_(BotSplitter.first, key_compare::max_value()))) 00346 return result; 00347 // no overflow/splitting happened 00348 00349 STXXL_VERBOSE1("btree::normal_node Inserting new value in *this"); 00350 00351 splitter = insert(std::make_pair(BotSplitter.first, bid_type(BotSplitter.second)), it); 00352 00353 return result; 00354 } 00355 else 00356 { // found_bid points to a node 00357 STXXL_VERBOSE1("btree::normal_node Inserting new value into a node"); 00358 node_type * Node = btree_->node_cache_.get_node((node_bid_type)it->second, true); 00359 assert(Node); 00360 std::pair<key_type, node_bid_type> BotSplitter; 00361 std::pair<iterator, bool> result = Node->insert(x, height - 1, BotSplitter); 00362 btree_->node_cache_.unfix_node((node_bid_type)it->second); 00363 //if(key_compare::max_value() == BotSplitter.first) 00364 if (!(cmp_(key_compare::max_value(), BotSplitter.first) || 00365 cmp_(BotSplitter.first, key_compare::max_value()))) 00366 return result; 00367 // no overflow/splitting happened 00368 00369 STXXL_VERBOSE1("btree::normal_node Inserting new value in *this"); 00370 00371 splitter = insert(BotSplitter, it); 00372 00373 return result; 00374 } 00375 } 00376 00377 iterator begin(unsigned height) 00378 { 00379 bid_type FirstBid = block_->begin()->second; 00380 if (height == 2) // FirstBid points to a leaf 00381 { 00382 assert(size() > 1); 00383 STXXL_VERBOSE1("btree::node retrieveing begin() from the first leaf"); 00384 leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)FirstBid); 00385 assert(Leaf); 00386 return Leaf->begin(); 00387 } 00388 else 00389 { // FirstBid points to a node 00390 STXXL_VERBOSE1("btree: retrieveing begin() from the first node"); 00391 node_type * Node = btree_->node_cache_.get_node((node_bid_type)FirstBid, true); 00392 assert(Node); 00393 iterator result = Node->begin(height - 1); 00394 btree_->node_cache_.unfix_node((node_bid_type)FirstBid); 00395 return result; 00396 } 00397 } 00398 00399 const_iterator begin(unsigned height) const 00400 { 00401 bid_type FirstBid = block_->begin()->second; 00402 if (height == 2) // FirstBid points to a leaf 00403 { 00404 assert(size() > 1); 00405 STXXL_VERBOSE1("btree::node retrieveing begin() from the first leaf"); 00406 leaf_type const * Leaf = btree_->leaf_cache_.get_const_node((leaf_bid_type)FirstBid); 00407 assert(Leaf); 00408 return Leaf->begin(); 00409 } 00410 else 00411 { // FirstBid points to a node 00412 STXXL_VERBOSE1("btree: retrieveing begin() from the first node"); 00413 node_type const * Node = btree_->node_cache_.get_const_node((node_bid_type)FirstBid, true); 00414 assert(Node); 00415 const_iterator result = Node->begin(height - 1); 00416 btree_->node_cache_.unfix_node((node_bid_type)FirstBid); 00417 return result; 00418 } 00419 } 00420 00421 iterator find(const key_type & k, unsigned height) 00422 { 00423 value_type Key2Search(k, bid_type()); 00424 00425 block_iterator it = 00426 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_); 00427 00428 assert(it != (block_->begin() + size())); 00429 00430 bid_type found_bid = it->second; 00431 00432 if (height == 2) // found_bid points to a leaf 00433 { 00434 STXXL_VERBOSE1("Searching in a leaf"); 00435 leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)found_bid, true); 00436 assert(Leaf); 00437 iterator result = Leaf->find(k); 00438 btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid); 00439 00440 return result; 00441 } 00442 00443 // found_bid points to a node 00444 STXXL_VERBOSE1("Searching in a node"); 00445 node_type * Node = btree_->node_cache_.get_node((node_bid_type)found_bid, true); 00446 assert(Node); 00447 iterator result = Node->find(k, height - 1); 00448 btree_->node_cache_.unfix_node((node_bid_type)found_bid); 00449 00450 return result; 00451 } 00452 00453 const_iterator find(const key_type & k, unsigned height) const 00454 { 00455 value_type Key2Search(k, bid_type()); 00456 00457 block_iterator it = 00458 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_); 00459 00460 assert(it != (block_->begin() + size())); 00461 00462 bid_type found_bid = it->second; 00463 00464 if (height == 2) // found_bid points to a leaf 00465 { 00466 STXXL_VERBOSE1("Searching in a leaf"); 00467 leaf_type const * Leaf = btree_->leaf_cache_.get_const_node((leaf_bid_type)found_bid, true); 00468 assert(Leaf); 00469 const_iterator result = Leaf->find(k); 00470 btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid); 00471 00472 return result; 00473 } 00474 00475 // found_bid points to a node 00476 STXXL_VERBOSE1("Searching in a node"); 00477 node_type const * Node = btree_->node_cache_.get_const_node((node_bid_type)found_bid, true); 00478 assert(Node); 00479 const_iterator result = Node->find(k, height - 1); 00480 btree_->node_cache_.unfix_node((node_bid_type)found_bid); 00481 00482 return result; 00483 } 00484 00485 iterator lower_bound(const key_type & k, unsigned height) 00486 { 00487 value_type Key2Search(k, bid_type()); 00488 assert(!vcmp_(back(), Key2Search)); 00489 block_iterator it = 00490 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_); 00491 00492 assert(it != (block_->begin() + size())); 00493 00494 bid_type found_bid = it->second; 00495 00496 if (height == 2) // found_bid points to a leaf 00497 { 00498 STXXL_VERBOSE1("Searching lower bound in a leaf"); 00499 leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)found_bid, true); 00500 assert(Leaf); 00501 iterator result = Leaf->lower_bound(k); 00502 btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid); 00503 00504 return result; 00505 } 00506 00507 // found_bid points to a node 00508 STXXL_VERBOSE1("Searching lower bound in a node"); 00509 node_type * Node = btree_->node_cache_.get_node((node_bid_type)found_bid, true); 00510 assert(Node); 00511 iterator result = Node->lower_bound(k, height - 1); 00512 btree_->node_cache_.unfix_node((node_bid_type)found_bid); 00513 00514 return result; 00515 } 00516 00517 const_iterator lower_bound(const key_type & k, unsigned height) const 00518 { 00519 value_type Key2Search(k, bid_type()); 00520 assert(!vcmp_(back(), Key2Search)); 00521 block_iterator it = 00522 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_); 00523 00524 assert(it != (block_->begin() + size())); 00525 00526 bid_type found_bid = it->second; 00527 00528 if (height == 2) // found_bid points to a leaf 00529 { 00530 STXXL_VERBOSE1("Searching lower bound in a leaf"); 00531 leaf_type const * Leaf = btree_->leaf_cache_.get_const_node((leaf_bid_type)found_bid, true); 00532 assert(Leaf); 00533 const_iterator result = Leaf->lower_bound(k); 00534 btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid); 00535 00536 return result; 00537 } 00538 00539 // found_bid points to a node 00540 STXXL_VERBOSE1("Searching lower bound in a node"); 00541 node_type const * Node = btree_->node_cache_.get_const_node((node_bid_type)found_bid, true); 00542 assert(Node); 00543 const_iterator result = Node->lower_bound(k, height - 1); 00544 btree_->node_cache_.unfix_node((node_bid_type)found_bid); 00545 00546 return result; 00547 } 00548 00549 iterator upper_bound(const key_type & k, unsigned height) 00550 { 00551 value_type Key2Search(k, bid_type()); 00552 assert(vcmp_(Key2Search, back())); 00553 block_iterator it = 00554 std::upper_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_); 00555 00556 assert(it != (block_->begin() + size())); 00557 00558 bid_type found_bid = it->second; 00559 00560 if (height == 2) // found_bid points to a leaf 00561 { 00562 STXXL_VERBOSE1("Searching upper bound in a leaf"); 00563 leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)found_bid, true); 00564 assert(Leaf); 00565 iterator result = Leaf->upper_bound(k); 00566 btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid); 00567 00568 return result; 00569 } 00570 00571 // found_bid points to a node 00572 STXXL_VERBOSE1("Searching upper bound in a node"); 00573 node_type * Node = btree_->node_cache_.get_node((node_bid_type)found_bid, true); 00574 assert(Node); 00575 iterator result = Node->upper_bound(k, height - 1); 00576 btree_->node_cache_.unfix_node((node_bid_type)found_bid); 00577 00578 return result; 00579 } 00580 00581 const_iterator upper_bound(const key_type & k, unsigned height) const 00582 { 00583 value_type Key2Search(k, bid_type()); 00584 assert(vcmp_(Key2Search, back())); 00585 block_iterator it = 00586 std::upper_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_); 00587 00588 assert(it != (block_->begin() + size())); 00589 00590 bid_type found_bid = it->second; 00591 00592 if (height == 2) // found_bid points to a leaf 00593 { 00594 STXXL_VERBOSE1("Searching upper bound in a leaf"); 00595 leaf_type const * Leaf = btree_->leaf_cache_.get_const_node((leaf_bid_type)found_bid, true); 00596 assert(Leaf); 00597 const_iterator result = Leaf->upper_bound(k); 00598 btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid); 00599 00600 return result; 00601 } 00602 00603 // found_bid points to a node 00604 STXXL_VERBOSE1("Searching upper bound in a node"); 00605 node_type const * Node = btree_->node_cache_.get_const_node((node_bid_type)found_bid, true); 00606 assert(Node); 00607 const_iterator result = Node->upper_bound(k, height - 1); 00608 btree_->node_cache_.unfix_node((node_bid_type)found_bid); 00609 00610 return result; 00611 } 00612 00613 void fuse(const normal_node & Src) 00614 { 00615 assert(vcmp_(Src.back(), front())); 00616 const unsigned SrcSize = Src.size(); 00617 00618 block_iterator cur = block_->begin() + size() - 1; 00619 block_const_iterator begin = block_->begin(); 00620 00621 for ( ; cur >= begin; --cur) 00622 *(cur + SrcSize) = *cur; 00623 // move elements to make space for Src elements 00624 00625 // copy Src to *this leaf 00626 std::copy(Src.block_->begin(), Src.block_->begin() + SrcSize, block_->begin()); 00627 00628 block_->info.cur_size += SrcSize; 00629 } 00630 00631 00632 key_type balance(normal_node & Left) 00633 { 00634 const unsigned TotalSize = Left.size() + size(); 00635 unsigned newLeftSize = TotalSize / 2; 00636 assert(newLeftSize <= Left.max_nelements()); 00637 assert(newLeftSize >= Left.min_nelements()); 00638 unsigned newRightSize = TotalSize - newLeftSize; 00639 assert(newRightSize <= max_nelements()); 00640 assert(newRightSize >= min_nelements()); 00641 00642 assert(vcmp_(Left.back(), front()) || size() == 0); 00643 00644 if (newLeftSize < Left.size()) 00645 { 00646 const unsigned nEl2Move = Left.size() - newLeftSize; // #elements to move from Left to *this 00647 00648 block_iterator cur = block_->begin() + size() - 1; 00649 block_const_iterator begin = block_->begin(); 00650 00651 for ( ; cur >= begin; --cur) 00652 *(cur + nEl2Move) = *cur; 00653 // move elements to make space for Src elements 00654 00655 // copy Left to *this leaf 00656 std::copy(Left.block_->begin() + newLeftSize, 00657 Left.block_->begin() + Left.size(), block_->begin()); 00658 } 00659 else 00660 { 00661 assert(newRightSize < size()); 00662 00663 const unsigned nEl2Move = size() - newRightSize; // #elements to move from *this to Left 00664 00665 // copy *this to Left 00666 std::copy(block_->begin(), 00667 block_->begin() + nEl2Move, Left.block_->begin() + Left.size()); 00668 // move elements in *this 00669 std::copy(block_->begin() + nEl2Move, 00670 block_->begin() + size(), block_->begin()); 00671 } 00672 00673 block_->info.cur_size = newRightSize; // update size 00674 Left.block_->info.cur_size = newLeftSize; // update size 00675 00676 return Left.back().first; 00677 } 00678 00679 size_type erase(const key_type & k, unsigned height) 00680 { 00681 value_type Key2Search(k, bid_type()); 00682 00683 block_iterator it = 00684 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_); 00685 00686 assert(it != (block_->begin() + size())); 00687 00688 bid_type found_bid = it->second; 00689 00690 assert(size() >= 2); 00691 00692 if (height == 2) // 'found_bid' points to a leaf 00693 { 00694 STXXL_VERBOSE1("btree::normal_node Deleting key from a leaf"); 00695 leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)found_bid, true); 00696 assert(Leaf); 00697 size_type result = Leaf->erase(k); 00698 btree_->leaf_cache_.unfix_node((leaf_bid_type)it->second); 00699 if (!Leaf->underflows()) 00700 return result; 00701 // no underflow or root has a special degree 1 (too few elements) 00702 00703 STXXL_VERBOSE1("btree::normal_node Fusing or rebalancing a leaf"); 00704 fuse_or_balance(it, btree_->leaf_cache_); 00705 00706 return result; 00707 } 00708 00709 // 'found_bid' points to a node 00710 STXXL_VERBOSE1("btree::normal_node Deleting key from a node"); 00711 node_type * Node = btree_->node_cache_.get_node((node_bid_type)found_bid, true); 00712 assert(Node); 00713 size_type result = Node->erase(k, height - 1); 00714 btree_->node_cache_.unfix_node((node_bid_type)found_bid); 00715 if (!Node->underflows()) 00716 return result; 00717 // no underflow happened 00718 00719 STXXL_VERBOSE1("btree::normal_node Fusing or rebalancing a node"); 00720 fuse_or_balance(it, btree_->node_cache_); 00721 00722 return result; 00723 } 00724 00725 void deallocate_children(unsigned height) 00726 { 00727 if (height == 2) 00728 { 00729 // we have children leaves here 00730 block_const_iterator it = block().begin(); 00731 for ( ; it != block().begin() + size(); ++it) 00732 { 00733 // delete from leaf cache and deallocate bid 00734 btree_->leaf_cache_.delete_node((leaf_bid_type)it->second); 00735 } 00736 } 00737 else 00738 { 00739 block_const_iterator it = block().begin(); 00740 for ( ; it != block().begin() + size(); ++it) 00741 { 00742 node_type * Node = btree_->node_cache_.get_node((node_bid_type)it->second); 00743 assert(Node); 00744 Node->deallocate_children(height - 1); 00745 // delete from node cache and deallocate bid 00746 btree_->node_cache_.delete_node((node_bid_type)it->second); 00747 } 00748 } 00749 } 00750 00751 void push_back(const value_type & x) 00752 { 00753 (*this)[size()] = x; 00754 ++(block_->info.cur_size); 00755 } 00756 }; 00757 } 00758 00759 00760 __STXXL_END_NAMESPACE 00761 00762 00763 #endif /* STXXL_CONTAINERS_BTREE__NODE_H */