13 #ifndef STXXL_CONTAINERS_BTREE__LEAF_H
14 #define STXXL_CONTAINERS_BTREE__LEAF_H
16 #include <stxxl/bits/containers/btree/iterator.h>
17 #include <stxxl/bits/containers/btree/node_cache.h>
20 __STXXL_BEGIN_NAMESPACE
24 template <
class NodeType,
class BTreeType>
27 template <
class KeyType_,
class DataType_,
class KeyCmp_,
unsigned RawSize_,
class BTreeType>
28 class normal_leaf :
private noncopyable
31 typedef normal_leaf<KeyType_, DataType_, KeyCmp_, RawSize_, BTreeType> SelfType;
33 friend class node_cache<SelfType, BTreeType>;
35 typedef KeyType_ key_type;
36 typedef DataType_ data_type;
37 typedef KeyCmp_ key_compare;
38 typedef std::pair<key_type, data_type> value_type;
39 typedef value_type & reference;
40 typedef const value_type & const_reference;
48 bid_type me, pred, succ;
56 min_size = nelements / 2
59 typedef BTreeType btree_type;
60 typedef typename btree_type::size_type size_type;
61 typedef btree_iterator_base<btree_type> iterator_base;
62 typedef btree_iterator<btree_type> iterator;
63 typedef btree_const_iterator<btree_type> const_iterator;
65 typedef node_cache<normal_leaf, btree_type> leaf_cache_type;
68 struct value_compare :
public std::binary_function<value_type, value_type, bool>
72 value_compare(key_compare c) : comp(c) { }
74 bool operator () (
const value_type & x,
const value_type & y)
const
76 return comp(x.first, y.first);
87 void split(std::pair<key_type, bid_type> & splitter)
90 btree_->leaf_cache_.get_new_node(NewBid);
91 normal_leaf * NewLeaf = btree_->leaf_cache_.get_node(NewBid,
true);
95 NewLeaf->succ() = my_bid();
96 normal_leaf * PredLeaf = NULL;
99 NewLeaf->pred() = pred();
100 PredLeaf = btree_->leaf_cache_.get_node(pred());
102 assert(vcmp_(PredLeaf->back(), front()));
103 PredLeaf->succ() = NewBid;
107 std::vector<iterator_base *> Iterators2Fix;
108 btree_->iterator_map_.find(my_bid(), 0, size(), Iterators2Fix);
110 const unsigned end_of_smaller_part = size() / 2;
112 splitter.first = ((*block_)[end_of_smaller_part - 1]).first;
113 splitter.second = NewBid;
115 const unsigned old_size = size();
117 std::copy(block_->begin(), block_->begin() + end_of_smaller_part, NewLeaf->block_->begin());
118 NewLeaf->block_->info.cur_size = end_of_smaller_part;
120 std::copy(block_->begin() + end_of_smaller_part,
121 block_->begin() + old_size, block_->begin());
122 block_->info.cur_size = old_size - end_of_smaller_part;
123 assert(size() + NewLeaf->size() == old_size);
126 typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix.begin();
127 for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
129 btree_->iterator_map_.unregister_iterator(**it2fix);
131 if ((*it2fix)->pos < end_of_smaller_part)
132 (*it2fix)->bid = NewBid;
135 (*it2fix)->pos -= end_of_smaller_part;
138 btree_->iterator_map_.register_iterator(**it2fix);
142 STXXL_VERBOSE1(
"btree::normal_leaf split leaf " <<
this
143 <<
" splitter: " << splitter.first);
145 #if STXXL_VERBOSE_LEVEL >= 1
148 STXXL_VERBOSE1(
"btree::normal_leaf pred_part.smallest = " << PredLeaf->front().first);
149 STXXL_VERBOSE1(
"btree::normal_leaf pred_part.largest = " << PredLeaf->back().first);
152 STXXL_VERBOSE1(
"btree::normal_leaf smaller_part.smallest = " << NewLeaf->front().first);
153 STXXL_VERBOSE1(
"btree::normal_leaf smaller_part.largest = " << NewLeaf->back().first);
154 STXXL_VERBOSE1(
"btree::normal_leaf larger_part.smallest = " << front().first);
155 STXXL_VERBOSE1(
"btree::normal_leaf larger_part.largest = " << back().first);
157 btree_->leaf_cache_.unfix_node(NewBid);
161 virtual ~normal_leaf()
166 normal_leaf(btree_type * btree__,
168 block_(new block_type),
173 assert(min_nelements() >= 2);
174 assert(2 * min_nelements() - 1 <= max_nelements());
175 assert(max_nelements() <= nelements);
179 bool overflows()
const {
return block_->info.cur_size > max_nelements(); }
180 bool underflows()
const {
return block_->info.cur_size < min_nelements(); }
182 unsigned max_nelements()
const {
return max_size; }
183 unsigned min_nelements()
const {
return min_size; }
188 return block_->info.succ;
192 return block_->info.pred;
195 const bid_type & succ()
const
197 return block_->info.succ;
199 const bid_type & pred()
const
201 return block_->info.pred;
228 unsigned size()
const
230 return block_->info.cur_size;
233 const bid_type & my_bid()
const
235 return block_->info.me;
248 assert(bid == my_bid());
254 return block_->read(bid);
257 void init(
const bid_type & my_bid_)
259 block_->info.me = my_bid_;
260 block_->info.succ = bid_type();
261 block_->info.pred = bid_type();
262 block_->info.cur_size = 0;
265 reference operator [] (
int i)
270 const_reference operator [] (
int i)
const
277 return (*block_)[size() - 1];
282 return *(block_->begin());
285 const_reference back()
const
287 return (*block_)[size() - 1];
290 const_reference front()
const
292 return *(block_->begin());
297 STXXL_VERBOSE2(
"Dump of leaf " <<
this);
298 for (
unsigned i = 0; i < size(); ++i)
299 STXXL_VERBOSE2((*
this)[i].first <<
" " << (*this)[i].second);
302 std::pair<iterator, bool> insert(
303 const value_type & x,
304 std::pair<key_type, bid_type> & splitter)
306 assert(size() <= max_nelements());
307 splitter.first = key_compare::max_value();
309 typename block_type::iterator it =
310 std::lower_bound(block_->begin(), block_->begin() + size(), x, vcmp_);
312 if (!(vcmp_(*it, x) || vcmp_(x, *it)) && it != (block_->begin() + size()))
315 return std::pair<iterator, bool>(
316 iterator(btree_, my_bid(), it - block_->begin()),
320 typename block_type::iterator cur = block_->begin() + size() - 1;
322 for ( ; cur >= it; --cur)
328 std::vector<iterator_base *> Iterators2Fix;
329 btree_->iterator_map_.find(my_bid(), it - block_->begin(), size(), Iterators2Fix);
330 typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix.begin();
331 for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
333 btree_->iterator_map_.unregister_iterator(**it2fix);
335 btree_->iterator_map_.register_iterator(**it2fix);
338 ++(block_->info.cur_size);
340 std::pair<iterator, bool> result(iterator(btree_, my_bid(), it - block_->begin()),
true);
342 if (size() <= max_nelements())
358 return iterator(btree_, my_bid(), 0);
361 const_iterator begin()
const
363 return const_iterator(btree_, my_bid(), 0);
368 return iterator(btree_, my_bid(), size());
371 void increment_iterator(iterator_base & it)
const
373 assert(it.bid == my_bid());
374 assert(it.pos != size());
376 btree_->iterator_map_.unregister_iterator(it);
379 if (it.pos == size() && succ().valid())
382 STXXL_VERBOSE1(
"btree::normal_leaf jumping to the next block");
385 }
else if (it.pos == 1 && btree_->prefetching_enabled_)
389 btree_->leaf_cache_.prefetch_node(succ());
391 btree_->iterator_map_.register_iterator(it);
394 void decrement_iterator(iterator_base & it)
const
396 assert(it.bid == my_bid());
398 btree_->iterator_map_.unregister_iterator(it);
402 assert(pred().valid());
405 normal_leaf
const * PredLeaf = btree_->leaf_cache_.get_const_node(pred(),
true);
407 it.pos = PredLeaf->size() - 1;
410 if (btree_->prefetching_enabled_ && PredLeaf->pred().valid())
411 btree_->leaf_cache_.prefetch_node(PredLeaf->pred());
414 btree_->leaf_cache_.unfix_node(pred());
420 btree_->iterator_map_.register_iterator(it);
423 iterator
find(
const key_type & k)
425 value_type searchVal(k, data_type());
426 typename block_type::iterator lb =
427 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
428 if (lb == block_->begin() + size() || lb->first != k)
429 return btree_->end();
432 return iterator(btree_, my_bid(), lb - block_->begin());
435 const_iterator
find(
const key_type & k)
const
437 value_type searchVal(k, data_type());
438 typename block_type::iterator lb =
439 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
440 if (lb == block_->begin() + size() || lb->first != k)
441 return btree_->end();
444 return const_iterator(btree_, my_bid(), lb - block_->begin());
447 iterator lower_bound(
const key_type & k)
449 value_type searchVal(k, data_type());
451 typename block_type::iterator lb =
452 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
455 if (lb == block_->begin() + size() && succ().valid())
457 return iterator(btree_, succ(), 0);
460 return iterator(btree_, my_bid(), lb - block_->begin());
463 const_iterator lower_bound(
const key_type & k)
const
465 value_type searchVal(k, data_type());
466 typename block_type::iterator lb =
467 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
470 if (lb == block_->begin() + size() && succ().valid())
472 return iterator(btree_, succ(), 0);
475 return const_iterator(btree_, my_bid(), lb - block_->begin());
478 iterator upper_bound(
const key_type & k)
480 value_type searchVal(k, data_type());
481 typename block_type::iterator lb =
482 std::upper_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
485 if (lb == block_->begin() + size() && succ().valid())
487 return iterator(btree_, succ(), 0);
490 return iterator(btree_, my_bid(), lb - block_->begin());
493 const_iterator upper_bound(
const key_type & k)
const
495 value_type searchVal(k, data_type());
496 typename block_type::iterator lb =
497 std::upper_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
500 if (lb == block_->begin() + size() && succ().valid())
502 return const_iterator(btree_, succ(), 0);
505 return const_iterator(btree_, my_bid(), lb - block_->begin());
508 size_type erase(
const key_type & k)
510 value_type searchVal(k, data_type());
511 typename block_type::iterator it =
512 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
514 if (it == block_->begin() + size() || it->first != k)
519 std::copy(it + 1, block_->begin() + size(), it);
521 std::vector<iterator_base *> Iterators2Fix;
522 btree_->iterator_map_.find(my_bid(), it + 1 - block_->begin(), size(), Iterators2Fix);
523 typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix.begin();
524 for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
526 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
" (pos--)");
527 btree_->iterator_map_.unregister_iterator(**it2fix);
529 btree_->iterator_map_.register_iterator(**it2fix);
532 --(block_->info.cur_size);
537 void fuse(
const normal_leaf & Src)
539 STXXL_VERBOSE1(
"btree::normal_leaf Fusing");
540 assert(vcmp_(Src.back(), front()));
541 const unsigned SrcSize = Src.size();
543 typename block_type::iterator cur = block_->begin() + size() - 1;
544 typename block_type::const_iterator begin = block_->begin();
546 for ( ; cur >= begin; --cur)
547 *(cur + SrcSize) = *cur;
551 std::copy(Src.block_->begin(), Src.block_->begin() + SrcSize, block_->begin());
554 std::vector<iterator_base *> Iterators2Fix;
555 btree_->iterator_map_.find(my_bid(), 0, size(), Iterators2Fix);
556 typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix.begin();
557 for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
559 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
560 " (pos+" << SrcSize <<
")");
561 btree_->iterator_map_.unregister_iterator(**it2fix);
562 ((*it2fix)->pos) += SrcSize;
563 btree_->iterator_map_.register_iterator(**it2fix);
566 Iterators2Fix.clear();
567 btree_->iterator_map_.find(Src.my_bid(), 0, SrcSize, Iterators2Fix);
568 it2fix = Iterators2Fix.begin();
569 for ( ; it2fix != Iterators2Fix.end(); ++it2fix)
571 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
572 " (bid=" << my_bid() <<
")");
573 btree_->iterator_map_.unregister_iterator(**it2fix);
574 ((*it2fix)->bid) = my_bid();
575 btree_->iterator_map_.register_iterator(**it2fix);
578 block_->info.cur_size += SrcSize;
584 normal_leaf * NewPred = btree_->leaf_cache_.get_node(pred());
586 NewPred->succ() = my_bid();
590 key_type balance(normal_leaf & Left)
592 STXXL_VERBOSE1(
"btree::normal_leaf Balancing leaves with bids " <<
593 Left.my_bid() <<
" and " << my_bid());
594 const unsigned TotalSize = Left.size() + size();
595 unsigned newLeftSize = TotalSize / 2;
596 assert(newLeftSize <= Left.max_nelements());
597 assert(newLeftSize >= Left.min_nelements());
598 unsigned newRightSize = TotalSize - newLeftSize;
599 assert(newRightSize <= max_nelements());
600 assert(newRightSize >= min_nelements());
602 assert(vcmp_(Left.back(), front()) || size() == 0);
604 if (newLeftSize < Left.size())
606 const unsigned nEl2Move = Left.size() - newLeftSize;
608 typename block_type::iterator cur = block_->begin() + size() - 1;
609 typename block_type::const_iterator begin = block_->begin();
611 for ( ; cur >= begin; --cur)
612 *(cur + nEl2Move) = *cur;
616 std::copy(Left.block_->begin() + newLeftSize,
617 Left.block_->begin() + Left.size(), block_->begin());
619 std::vector<iterator_base *> Iterators2Fix1;
620 std::vector<iterator_base *> Iterators2Fix2;
621 btree_->iterator_map_.find(my_bid(), 0, size(), Iterators2Fix1);
622 btree_->iterator_map_.find(Left.my_bid(), newLeftSize, Left.size(), Iterators2Fix2);
624 typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix1.begin();
625 for ( ; it2fix != Iterators2Fix1.end(); ++it2fix)
627 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
628 " (pos+" << nEl2Move <<
")");
629 btree_->iterator_map_.unregister_iterator(**it2fix);
630 ((*it2fix)->pos) += nEl2Move;
631 btree_->iterator_map_.register_iterator(**it2fix);
635 it2fix = Iterators2Fix2.begin();
636 for ( ; it2fix != Iterators2Fix2.end(); ++it2fix)
638 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
639 " (pos-" << newLeftSize <<
" bid=" << my_bid() <<
")");
640 btree_->iterator_map_.unregister_iterator(**it2fix);
641 ((*it2fix)->bid) = my_bid();
642 ((*it2fix)->pos) -= newLeftSize;
643 btree_->iterator_map_.register_iterator(**it2fix);
648 assert(newRightSize < size());
650 const unsigned nEl2Move = size() - newRightSize;
653 std::copy(block_->begin(),
654 block_->begin() + nEl2Move, Left.block_->begin() + Left.size());
656 std::copy(block_->begin() + nEl2Move,
657 block_->begin() + size(), block_->begin());
659 std::vector<iterator_base *> Iterators2Fix1;
660 std::vector<iterator_base *> Iterators2Fix2;
661 btree_->iterator_map_.find(my_bid(), nEl2Move, size(), Iterators2Fix1);
662 btree_->iterator_map_.find(my_bid(), 0, nEl2Move - 1, Iterators2Fix2);
664 typename std::vector<iterator_base *>::iterator it2fix = Iterators2Fix1.begin();
665 for ( ; it2fix != Iterators2Fix1.end(); ++it2fix)
667 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
668 " (pos-" << nEl2Move <<
")");
669 btree_->iterator_map_.unregister_iterator(**it2fix);
670 ((*it2fix)->pos) -= nEl2Move;
671 btree_->iterator_map_.register_iterator(**it2fix);
675 it2fix = Iterators2Fix2.begin();
676 for ( ; it2fix != Iterators2Fix2.end(); ++it2fix)
678 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
679 " (pos+" << Left.size() <<
" bid=" << Left.my_bid() <<
")");
680 btree_->iterator_map_.unregister_iterator(**it2fix);
681 ((*it2fix)->bid) = Left.my_bid();
682 ((*it2fix)->pos) += Left.size();
683 btree_->iterator_map_.register_iterator(**it2fix);
687 block_->info.cur_size = newRightSize;
688 Left.block_->info.cur_size = newLeftSize;
690 return Left.back().first;
693 void push_back(
const value_type & x)
696 ++(block_->info.cur_size);
702 __STXXL_END_NAMESPACE
Block containing elements of fixed length.
Definition: typed_block.h:223
number of elements in block
Definition: typed_block.h:240
Implemented as reference counting smart pointer.
Definition: request_ptr.h:34
_ExtIterator find(_ExtIterator _begin, _ExtIterator _end, const _EqualityComparable &_value, int_type nbuffers)
External equivalent of std::find.
Definition: scan.h:215
virtual void wait(bool measure_time=true)=0
Suspends calling thread until completion of the request.