13 #ifndef STXXL_CONTAINERS_BTREE_LEAF_HEADER
14 #define STXXL_CONTAINERS_BTREE_LEAF_HEADER
23 template <
class NodeType,
class BTreeType>
26 template <
class KeyType,
class DataType,
class KeyCmp,
unsigned RawSize,
class BTreeType>
55 nelements = block_type::size - 1,
57 min_size = nelements / 2
69 struct value_compare :
public std::binary_function<value_type, value_type, bool>
77 return comp(x.first, y.first);
88 void split(std::pair<key_type, bid_type>& splitter)
91 m_btree->m_leaf_cache.get_new_node(new_bid);
92 normal_leaf* new_leaf = m_btree->m_leaf_cache.get_node(new_bid,
true);
96 new_leaf->
succ() = my_bid();
100 new_leaf->
pred() = pred();
101 pred_leaf = m_btree->m_leaf_cache.get_node(pred());
103 assert(m_vcmp(pred_leaf->
back(), front()));
104 pred_leaf->
succ() = new_bid;
108 typedef std::vector<iterator_base*> iterators2fix_type;
109 iterators2fix_type iterators2fix;
110 m_btree->m_iterator_map.find(my_bid(), 0, size(), iterators2fix);
112 const unsigned end_of_smaller_part = size() / 2;
114 splitter.first = ((*m_block)[end_of_smaller_part - 1]).first;
115 splitter.second = new_bid;
117 const unsigned old_size = size();
119 std::copy(m_block->begin(), m_block->begin() + end_of_smaller_part,
121 new_leaf->
m_block->
info.cur_size = end_of_smaller_part;
123 std::copy(m_block->begin() + end_of_smaller_part,
124 m_block->begin() + old_size, m_block->begin());
125 m_block->info.cur_size = old_size - end_of_smaller_part;
126 assert(size() + new_leaf->
size() == old_size);
129 for (
typename iterators2fix_type::iterator it2fix = iterators2fix.begin();
130 it2fix != iterators2fix.end(); ++it2fix)
132 m_btree->m_iterator_map.unregister_iterator(**it2fix);
134 if ((*it2fix)->pos < end_of_smaller_part)
135 (*it2fix)->bid = new_bid;
138 (*it2fix)->pos -= end_of_smaller_part;
140 m_btree->m_iterator_map.register_iterator(**it2fix);
144 <<
" splitter: " << splitter.first);
146 #if STXXL_VERBOSE_LEVEL >= 1
154 STXXL_VERBOSE1(
"btree::normal_leaf smaller_part.largest = " << new_leaf->
back().first);
155 STXXL_VERBOSE1(
"btree::normal_leaf larger_part.smallest = " << front().first);
156 STXXL_VERBOSE1(
"btree::normal_leaf larger_part.largest = " << back().first);
158 m_btree->m_leaf_cache.unfix_node(new_bid);
174 assert(min_nelements() >= 2);
175 assert(2 * min_nelements() - 1 <= max_nelements());
176 assert(max_nelements() <= nelements);
177 assert(
unsigned(block_type::size) >= nelements + 1);
180 bool overflows()
const {
return m_block->info.cur_size > max_nelements(); }
181 bool underflows()
const {
return m_block->info.cur_size < min_nelements(); }
188 return m_block->info.succ;
192 return m_block->info.pred;
197 return m_block->info.succ;
201 return m_block->info.pred;
230 return m_block->info.cur_size;
235 return m_block->info.me;
248 assert(bid == my_bid());
254 return m_block->read(bid);
259 m_block->info.me = my_bid_;
262 m_block->info.cur_size = 0;
267 return (*m_block)[i];
272 return (*m_block)[i];
277 return (*m_block)[size() - 1];
282 return *(m_block->begin());
287 return (*m_block)[size() - 1];
292 return *(m_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(m_block->begin(), m_block->begin() + size(), x, m_vcmp);
312 if (!(m_vcmp(*it, x) || m_vcmp(x, *it)) && it != (m_block->begin() + size()))
315 return std::pair<iterator, bool>(
316 iterator(m_btree, my_bid(),
unsigned(it - m_block->begin())),
322 for ( ; cur >= it; --cur)
328 std::vector<iterator_base*> iterators2fix;
329 m_btree->m_iterator_map.find(my_bid(),
unsigned(it - m_block->begin()), size(), iterators2fix);
330 typename std::vector<iterator_base*>::iterator it2fix = iterators2fix.begin();
331 for ( ; it2fix != iterators2fix.end(); ++it2fix)
333 m_btree->m_iterator_map.unregister_iterator(**it2fix);
335 m_btree->m_iterator_map.register_iterator(**it2fix);
338 ++(m_block->info.cur_size);
340 std::pair<iterator, bool> result(
iterator(m_btree, my_bid(),
unsigned(it - m_block->begin())),
true);
342 if (size() <= max_nelements())
358 return iterator(m_btree, my_bid(), 0);
368 return iterator(m_btree, my_bid(), size());
373 assert(it.
bid == my_bid());
374 assert(it.
pos != size());
376 m_btree->m_iterator_map.unregister_iterator(it);
379 if (it.
pos == size() && succ().valid())
387 else if (it.
pos == 1 && m_btree->m_prefetching_enabled)
391 m_btree->m_leaf_cache.prefetch_node(succ());
393 m_btree->m_iterator_map.register_iterator(it);
398 assert(it.
bid == my_bid());
400 m_btree->m_iterator_map.unregister_iterator(it);
404 assert(pred().valid());
407 normal_leaf const* pred_leaf = m_btree->m_leaf_cache.get_const_node(pred(),
true);
409 it.
pos = pred_leaf->
size() - 1;
412 if (m_btree->m_prefetching_enabled && pred_leaf->
pred().
valid())
413 m_btree->m_leaf_cache.prefetch_node(pred_leaf->
pred());
415 m_btree->m_leaf_cache.unfix_node(pred());
420 m_btree->m_iterator_map.register_iterator(it);
427 std::lower_bound(m_block->begin(), m_block->begin() + size(), search_val, m_vcmp);
428 if (lb == m_block->begin() + size() || lb->first != k)
429 return m_btree->end();
431 return iterator(m_btree, my_bid(),
unsigned(lb - m_block->begin()));
438 std::lower_bound(m_block->begin(), m_block->begin() + size(), search_val, m_vcmp);
439 if (lb == m_block->begin() + size() || lb->first != k)
440 return m_btree->end();
442 return const_iterator(m_btree, my_bid(),
unsigned(lb - m_block->begin()));
450 std::lower_bound(m_block->begin(), m_block->begin() + size(), search_val, m_vcmp);
453 if (lb == m_block->begin() + size() && succ().valid())
455 return iterator(m_btree, succ(), 0);
458 return iterator(m_btree, my_bid(),
unsigned(lb - m_block->begin()));
465 std::lower_bound(m_block->begin(), m_block->begin() + size(), search_val, m_vcmp);
468 if (lb == m_block->begin() + size() && succ().valid())
470 return iterator(m_btree, succ(), 0);
473 return const_iterator(m_btree, my_bid(),
unsigned(lb - m_block->begin()));
480 std::upper_bound(m_block->begin(), m_block->begin() + size(), search_val, m_vcmp);
483 if (lb == m_block->begin() + size() && succ().valid())
485 return iterator(m_btree, succ(), 0);
488 return iterator(m_btree, my_bid(),
unsigned(lb - m_block->begin()));
495 std::upper_bound(m_block->begin(), m_block->begin() + size(), search_val, m_vcmp);
498 if (lb == m_block->begin() + size() && succ().valid())
503 return const_iterator(m_btree, my_bid(),
unsigned(lb - m_block->begin()));
510 std::lower_bound(m_block->begin(), m_block->begin() + size(), search_val, m_vcmp);
512 if (it == m_block->begin() + size() || it->first != k)
517 std::copy(it + 1, m_block->begin() + size(), it);
519 std::vector<iterator_base*> iterators2fix;
520 m_btree->m_iterator_map.find(my_bid(),
unsigned(it + 1 - m_block->begin()), size(), iterators2fix);
521 typename std::vector<iterator_base*>::iterator it2fix = iterators2fix.begin();
522 for ( ; it2fix != iterators2fix.end(); ++it2fix)
524 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
" (pos--)");
525 m_btree->m_iterator_map.unregister_iterator(**it2fix);
527 m_btree->m_iterator_map.register_iterator(**it2fix);
530 --(m_block->info.cur_size);
538 assert(m_vcmp(src.
back(), front()));
539 const unsigned src_size = src.
size();
544 for ( ; cur >= begin; --cur)
545 *(cur + src_size) = *cur;
551 std::vector<iterator_base*> iterators2fix;
552 m_btree->m_iterator_map.find(my_bid(), 0, size(), iterators2fix);
553 typename std::vector<iterator_base*>::iterator it2fix = iterators2fix.begin();
554 for ( ; it2fix != iterators2fix.end(); ++it2fix)
556 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
557 " (pos+" << src_size <<
")");
558 m_btree->m_iterator_map.unregister_iterator(**it2fix);
559 ((*it2fix)->pos) += src_size;
560 m_btree->m_iterator_map.register_iterator(**it2fix);
563 iterators2fix.clear();
564 m_btree->m_iterator_map.find(src.
my_bid(), 0, src_size, iterators2fix);
565 for (it2fix = iterators2fix.begin(); it2fix != iterators2fix.end(); ++it2fix)
567 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
568 " (bid=" << my_bid() <<
")");
569 m_btree->m_iterator_map.unregister_iterator(**it2fix);
570 ((*it2fix)->bid) = my_bid();
571 m_btree->m_iterator_map.register_iterator(**it2fix);
574 m_block->info.cur_size += src_size;
580 normal_leaf* new_pred = m_btree->m_leaf_cache.get_node(pred());
582 new_pred->
succ() = my_bid();
588 STXXL_VERBOSE1(
"btree::normal_leaf Balancing leaves with bids " <<
589 left.
my_bid() <<
" and " << my_bid());
590 const unsigned total_size = left.
size() + size();
591 unsigned new_left_size = total_size / 2;
594 unsigned new_right_size = total_size - new_left_size;
595 assert(new_right_size <= max_nelements());
596 assert(new_right_size >= min_nelements());
598 assert(m_vcmp(left.
back(), front()) || size() == 0);
600 if (new_left_size < left.
size())
603 const unsigned nEl2Move = left.
size() - new_left_size;
608 for ( ; cur >= begin; --cur)
609 *(cur + nEl2Move) = *cur;
616 std::vector<iterator_base*> iterators2fix1;
617 std::vector<iterator_base*> iterators2fix2;
618 m_btree->m_iterator_map.find(my_bid(), 0, size(), iterators2fix1);
619 m_btree->m_iterator_map.find(left.
my_bid(), new_left_size, left.
size(), iterators2fix2);
621 typename std::vector<iterator_base*>::iterator it2fix = iterators2fix1.begin();
622 for ( ; it2fix != iterators2fix1.end(); ++it2fix)
624 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
625 " (pos+" << nEl2Move <<
")");
626 m_btree->m_iterator_map.unregister_iterator(**it2fix);
627 ((*it2fix)->pos) += nEl2Move;
628 m_btree->m_iterator_map.register_iterator(**it2fix);
631 it2fix = iterators2fix2.begin();
632 for ( ; it2fix != iterators2fix2.end(); ++it2fix)
634 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
635 " (pos-" << new_left_size <<
" bid=" << my_bid() <<
")");
636 m_btree->m_iterator_map.unregister_iterator(**it2fix);
637 ((*it2fix)->bid) = my_bid();
638 ((*it2fix)->pos) -= new_left_size;
639 m_btree->m_iterator_map.register_iterator(**it2fix);
644 assert(new_right_size < size());
646 const unsigned nEl2Move = size() - new_right_size;
649 std::copy(m_block->begin(),
652 std::copy(m_block->begin() + nEl2Move,
653 m_block->begin() + size(), m_block->begin());
655 std::vector<iterator_base*> iterators2fix1;
656 std::vector<iterator_base*> iterators2fix2;
657 m_btree->m_iterator_map.find(my_bid(), nEl2Move, size(), iterators2fix1);
658 m_btree->m_iterator_map.find(my_bid(), 0, nEl2Move - 1, iterators2fix2);
660 typename std::vector<iterator_base*>::iterator it2fix = iterators2fix1.begin();
661 for ( ; it2fix != iterators2fix1.end(); ++it2fix)
663 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
664 " (pos-" << nEl2Move <<
")");
665 m_btree->m_iterator_map.unregister_iterator(**it2fix);
666 ((*it2fix)->pos) -= nEl2Move;
667 m_btree->m_iterator_map.register_iterator(**it2fix);
670 it2fix = iterators2fix2.begin();
671 for ( ; it2fix != iterators2fix2.end(); ++it2fix)
673 STXXL_VERBOSE2(
"btree::normal_leaf updating iterator " << (*it2fix) <<
674 " (pos+" << left.
size() <<
" bid=" << left.
my_bid() <<
")");
675 m_btree->m_iterator_map.unregister_iterator(**it2fix);
676 ((*it2fix)->bid) = left.
my_bid();
677 ((*it2fix)->pos) += left.
size();
678 m_btree->m_iterator_map.register_iterator(**it2fix);
682 m_block->info.cur_size = new_right_size;
685 return left.
back().first;
691 ++(m_block->info.cur_size);
699 #endif // !STXXL_CONTAINERS_BTREE_LEAF_HEADER
std::pair< key_type, data_type > value_type
normal_leaf< KeyType, DataType, KeyCmp, RawSize, BTreeType > self_type
const_iterator lower_bound(const key_type &k) const
const_iterator upper_bound(const key_type &k) const
const bid_type & pred() const
void push_back(const value_type &x)
typed_block< raw_size, value_type, 0, metainfo_type > block_type
void fuse(const normal_leaf &src)
key_type balance(normal_leaf &left)
const_reference back() const
normal_leaf(btree_type *btree, key_compare cmp)
info_type info
Per block information element.
const_iterator begin() const
iterator find(const key_type &k)
static unsigned max_nelements()
#define STXXL_VERBOSE2(x)
const value_type & const_reference
btree_type::size_type size_type
const bid_type & succ() const
value_compare(key_compare c)
request_ptr load(const bid_type &bid)
Block containing elements of fixed length.
virtual void wait(bool measure_time=true)=0
Suspends calling thread until completion of the request.
node_cache< normal_leaf, btree_type > leaf_cache_type
void increment_iterator(iterator_base &it) const
void decrement_iterator(iterator_base &it) const
btree_iterator< btree_type > iterator
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
#define STXXL_BEGIN_NAMESPACE
const_reference front() const
#define STXXL_VERBOSE1(x)
iterator lower_bound(const key_type &k)
iterator begin()
Returns iterator pointing to the first element.
std::pair< iterator, bool > insert(const value_type &x, std::pair< key_type, bid_type > &splitter)
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
size_type erase(const key_type &k)
const bid_type & my_bid() const
void split(std::pair< key_type, bid_type > &splitter)
btree_const_iterator< btree_type > const_iterator
iterator upper_bound(const key_type &k)
static unsigned min_nelements()
btree_iterator_base< btree_type > iterator_base
void init(const bid_type &my_bid_)
request_ptr prefetch(const bid_type &bid)
const_iterator find(const key_type &k) const
#define STXXL_END_NAMESPACE