13 #ifndef STXXL_CONTAINERS_BTREE_LEAF_HEADER
14 #define STXXL_CONTAINERS_BTREE_LEAF_HEADER
24 template <
class NodeType,
class BTreeType>
27 template <
class KeyType_,
class DataType_,
class KeyCmp_,
unsigned RawSize_,
class BTreeType>
54 nelements = block_type::size - 1,
56 min_size = nelements / 2
68 struct value_compare :
public std::binary_function<value_type, value_type, bool>
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();
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);
143 <<
" splitter: " << splitter.first);
145 #if STXXL_VERBOSE_LEVEL >= 1
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);
173 assert(min_nelements() >= 2);
174 assert(2 * min_nelements() - 1 <= max_nelements());
175 assert(max_nelements() <= nelements);
176 assert(
unsigned(block_type::size) >= nelements + 1);
179 bool overflows()
const {
return block_->info.cur_size > max_nelements(); }
180 bool underflows()
const {
return block_->info.cur_size < min_nelements(); }
188 return block_->info.succ;
192 return block_->info.pred;
197 return block_->info.succ;
201 return block_->info.pred;
230 return block_->info.cur_size;
235 return block_->info.me;
248 assert(bid == my_bid());
254 return block_->read(bid);
259 block_->info.me = my_bid_;
262 block_->info.cur_size = 0;
277 return (*block_)[size() - 1];
282 return *(block_->begin());
287 return (*block_)[size() - 1];
292 return *(block_->begin());
298 for (
unsigned i = 0; i < size(); ++i)
304 std::pair<key_type, bid_type>& splitter)
306 assert(size() <= max_nelements());
307 splitter.first = key_compare::max_value();
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(),
unsigned(it - block_->begin())),
322 for ( ; cur >= it; --cur)
328 std::vector<iterator_base*> Iterators2Fix;
329 btree_->iterator_map_.find(my_bid(),
unsigned(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(),
unsigned(it - block_->begin())),
true);
342 if (size() <= max_nelements())
358 return iterator(btree_, my_bid(), 0);
368 return iterator(btree_, my_bid(), size());
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())
385 }
else if (it.
pos == 1 && btree_->prefetching_enabled_)
389 btree_->leaf_cache_.prefetch_node(succ());
391 btree_->iterator_map_.register_iterator(it);
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);
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);
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(),
unsigned(lb - block_->begin()));
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(),
unsigned(lb - block_->begin()));
452 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
455 if (lb == block_->begin() + size() && succ().valid())
460 return iterator(btree_, my_bid(),
unsigned(lb - block_->begin()));
467 std::lower_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
470 if (lb == block_->begin() + size() && succ().valid())
475 return const_iterator(btree_, my_bid(),
unsigned(lb - block_->begin()));
482 std::upper_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
485 if (lb == block_->begin() + size() && succ().valid())
490 return iterator(btree_, my_bid(),
unsigned(lb - block_->begin()));
497 std::upper_bound(block_->begin(), block_->begin() + size(), searchVal, vcmp_);
500 if (lb == block_->begin() + size() && succ().valid())
505 return const_iterator(btree_, my_bid(),
unsigned(lb - block_->begin()));
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(),
unsigned(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);
540 assert(vcmp_(Src.
back(), front()));
541 const unsigned SrcSize = Src.
size();
546 for ( ; cur >= begin; --cur)
547 *(cur + SrcSize) = *cur;
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();
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;
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;
611 for ( ; cur >= begin; --cur)
612 *(cur + nEl2Move) = *cur;
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(),
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;
690 return Left.
back().first;
696 ++(block_->info.cur_size);
705 #endif // !STXXL_CONTAINERS_BTREE_LEAF_HEADER
normal_leaf(btree_type *btree__, key_compare cmp)
void increment_iterator(iterator_base &it) const
std::pair< iterator, bool > insert(const value_type &x, std::pair< key_type, bid_type > &splitter)
const bid_type & my_bid() const
const_iterator upper_bound(const key_type &k) const
request_ptr load(const bid_type &bid)
info_type info
Per block information element.
const value_type & const_reference
btree_const_iterator< btree_type > const_iterator
void split(std::pair< key_type, bid_type > &splitter)
const_reference back() const
#define STXXL_VERBOSE2(x)
std::pair< key_type, data_type > value_type
unsigned min_nelements() const
iterator upper_bound(const key_type &k)
size_type erase(const key_type &k)
normal_leaf< KeyType_, DataType_, KeyCmp_, RawSize_, BTreeType > SelfType
key_type balance(normal_leaf &Left)
typed_block< raw_size, value_type, 0, InfoType > block_type
Block containing elements of fixed length.
virtual void wait(bool measure_time=true)=0
Suspends calling thread until completion of the request.
btree_iterator< btree_type > iterator
request_ptr prefetch(const bid_type &bid)
const_reference front() const
static std::vector< std::string > split(const std::string &str, const std::string &sep, unsigned int min_fields=0, unsigned int limit_fields=std::numeric_limits< unsigned int >::max())
Split a string by given separator string. Returns a vector of strings with at least min_fields and at...
const_pointer const_iterator
const_iterator begin() const
#define STXXL_BEGIN_NAMESPACE
iterator lower_bound(const key_type &k)
#define STXXL_VERBOSE1(x)
iterator begin()
Returns iterator pointing to the first element.
const bid_type & pred() const
btree_type::size_type size_type
value_compare(key_compare c)
btree_iterator_base< btree_type > iterator_base
iterator find(const key_type &k)
node_cache< normal_leaf, btree_type > leaf_cache_type
void push_back(const value_type &x)
const_iterator find(const key_type &k) const
unsigned max_nelements() const
void init(const bid_type &my_bid_)
void decrement_iterator(iterator_base &it) const
const_iterator lower_bound(const key_type &k) const
void fuse(const normal_leaf &Src)
#define STXXL_END_NAMESPACE
const bid_type & succ() const