13 #ifndef STXXL_CONTAINERS_BTREE_NODE_HEADER
14 #define STXXL_CONTAINERS_BTREE_NODE_HEADER
23 template <
class NodeType,
class BTreeType>
26 template <
class KeyType,
class KeyCmp,
unsigned RawSize,
class BTreeType>
55 nelements = block_type::size - 1,
57 min_size = nelements / 2
64 typedef typename btree_type::iterator
iterator;
74 struct value_compare :
public std::binary_function<value_type, value_type, bool>
82 return comp(x.first, y.first);
91 std::pair<key_type, bid_type>
insert(
const std::pair<key_type, bid_type>& splitter,
94 std::pair<key_type, bid_type> result(key_compare::max_value(),
bid_type());
97 assert(m_vcmp(*place2insert, splitter) || m_vcmp(splitter, *place2insert));
100 for ( ; cur >= place2insert; --cur)
104 *place2insert = splitter;
106 ++(m_block->info.cur_size);
108 if (size() > max_nelements())
110 STXXL_VERBOSE1(
"btree::normal_node::insert overflow happened, splitting");
113 m_btree->m_node_cache.get_new_node(new_bid);
114 normal_node* new_node = m_btree->m_node_cache.get_node(new_bid,
true);
117 const unsigned end_of_smaller_part = size() / 2;
119 result.first = ((*m_block)[end_of_smaller_part - 1]).first;
120 result.second = new_bid;
122 const unsigned old_size = size();
124 std::copy(m_block->begin(), m_block->begin() + end_of_smaller_part, new_node->
m_block->
begin());
125 new_node->
m_block->
info.cur_size = end_of_smaller_part;
127 std::copy(m_block->begin() + end_of_smaller_part,
128 m_block->begin() + old_size, m_block->begin());
129 m_block->info.cur_size = old_size - end_of_smaller_part;
130 assert(size() + new_node->
size() == old_size);
132 m_btree->m_node_cache.unfix_node(new_bid);
135 <<
" splitter: " << result.first);
141 template <
class CacheType>
144 typedef typename CacheType::node_type local_node_type;
145 typedef typename local_node_type::bid_type local_bid_type;
148 if (UIt == (m_block->begin() + size() - 1))
150 assert(UIt != m_block->begin());
158 assert(rightIt != (m_block->begin() + size()));
162 local_bid_type left_bid = (local_bid_type)leftIt->second;
163 local_bid_type right_bid = (local_bid_type)rightIt->second;
164 local_node_type* left_node = cache.get_node(left_bid,
true);
165 local_node_type* right_node = cache.get_node(right_bid,
true);
167 const unsigned total_size = left_node->size() + right_node->size();
168 if (total_size <= right_node->max_nelements())
173 right_node->fuse(*left_node);
175 cache.unfix_node(right_bid);
177 cache.delete_node(left_bid);
180 std::copy(leftIt + 1, m_block->begin() + size(), leftIt);
181 --(m_block->info.cur_size);
187 key_type new_splitter = right_node->balance(*left_node);
190 leftIt->first = new_splitter;
191 assert(m_vcmp(*leftIt, *rightIt));
193 cache.unfix_node(left_bid);
194 cache.unfix_node(right_bid);
211 assert(min_nelements() >= 2);
212 assert(2 * min_nelements() - 1 <= max_nelements());
213 assert(max_nelements() <= nelements);
215 assert(
unsigned(block_type::size) >= nelements + 1);
223 bool overflows()
const {
return m_block->info.cur_size > max_nelements(); }
224 bool underflows()
const {
return m_block->info.cur_size < min_nelements(); }
255 return m_block->info.cur_size;
260 return m_block->info.me;
273 assert(bid == my_bid());
279 return m_block->read(bid);
284 m_block->info.me = my_bid_;
285 m_block->info.cur_size = 0;
290 return (*m_block)[i];
295 return (*m_block)[i];
300 return (*m_block)[size() - 1];
305 return *(m_block->begin());
310 return (*m_block)[size() - 1];
315 return *(m_block->begin());
318 std::pair<iterator, bool>
320 std::pair<key_type, bid_type>& splitter)
322 assert(size() <= max_nelements());
323 splitter.first = key_compare::max_value();
327 std::lower_bound(m_block->begin(), m_block->begin() + size(), key2search, m_vcmp);
329 assert(it != (m_block->begin() + size()));
335 STXXL_VERBOSE1(
"btree::normal_node Inserting new value into a leaf");
338 std::pair<key_type, leaf_bid_type> bot_splitter;
339 std::pair<iterator, bool> result = leaf->insert(x, bot_splitter);
342 if (!(m_cmp(key_compare::max_value(), bot_splitter.first) ||
343 m_cmp(bot_splitter.first, key_compare::max_value())))
347 STXXL_VERBOSE1(
"btree::normal_node Inserting new value in *this");
349 splitter = insert(std::make_pair(bot_splitter.first,
bid_type(bot_splitter.second)), it);
355 STXXL_VERBOSE1(
"btree::normal_node Inserting new value into a node");
358 std::pair<key_type, node_bid_type> bot_splitter;
359 std::pair<iterator, bool> result = node->
insert(x, height - 1, bot_splitter);
362 if (!(m_cmp(key_compare::max_value(), bot_splitter.first) ||
363 m_cmp(bot_splitter.first, key_compare::max_value())))
367 STXXL_VERBOSE1(
"btree::normal_node Inserting new value in *this");
369 splitter = insert(bot_splitter, it);
377 bid_type first_bid = m_block->begin()->second;
381 STXXL_VERBOSE1(
"btree::node retrieveing begin() from the first leaf");
384 return leaf->begin();
399 bid_type FirstBid = m_block->begin()->second;
403 STXXL_VERBOSE1(
"btree::node retrieveing begin() from the first leaf");
406 return leaf->begin();
424 std::lower_bound(m_block->begin(), m_block->begin() + size(), key2search, m_vcmp);
426 assert(it != (m_block->begin() + size()));
456 std::lower_bound(m_block->begin(), m_block->begin() + size(), key2search, m_vcmp);
458 assert(it != (m_block->begin() + size()));
486 assert(!m_vcmp(back(), key2search));
488 std::lower_bound(m_block->begin(), m_block->begin() + size(), key2search, m_vcmp);
490 assert(it != (m_block->begin() + size()));
499 iterator result = leaf->lower_bound(k);
518 assert(!m_vcmp(back(), key2search));
520 std::lower_bound(m_block->begin(), m_block->begin() + size(), key2search, m_vcmp);
522 assert(it != (m_block->begin() + size()));
550 assert(m_vcmp(key2search, back()));
552 std::upper_bound(m_block->begin(), m_block->begin() + size(), key2search, m_vcmp);
554 assert(it != (m_block->begin() + size()));
563 iterator result = leaf->upper_bound(k);
582 assert(m_vcmp(key2search, back()));
584 std::upper_bound(m_block->begin(), m_block->begin() + size(), key2search, m_vcmp);
586 assert(it != (m_block->begin() + size()));
613 assert(m_vcmp(src.
back(), front()));
614 const unsigned src_size = src.
size();
619 for ( ; cur >= begin; --cur)
620 *(cur + src_size) = *cur;
626 m_block->info.cur_size += src_size;
631 const unsigned total_size = left.
size() + size();
632 unsigned new_left_size = total_size / 2;
635 unsigned new_right_size = total_size - new_left_size;
636 STXXL_ASSERT(!check_constraints || new_right_size <= max_nelements());
637 STXXL_ASSERT(!check_constraints || new_right_size >= min_nelements());
639 assert(m_vcmp(left.
back(), front()) || size() == 0);
641 if (new_left_size < left.
size())
644 const unsigned nEl2Move = left.
size() - new_left_size;
649 for ( ; cur >= begin; --cur)
650 *(cur + nEl2Move) = *cur;
659 assert(new_right_size < size());
662 const unsigned nEl2Move = size() - new_right_size;
665 std::copy(m_block->begin(),
668 std::copy(m_block->begin() + nEl2Move,
669 m_block->begin() + size(), m_block->begin());
672 m_block->info.cur_size = new_right_size;
675 return left.
back().first;
683 std::lower_bound(m_block->begin(), m_block->begin() + size(), key2search, m_vcmp);
685 assert(it != (m_block->begin() + size()));
698 if (!leaf->underflows())
702 STXXL_VERBOSE1(
"btree::normal_node Fusing or rebalancing a leaf");
703 fuse_or_balance(it, m_btree->m_leaf_cache);
718 STXXL_VERBOSE1(
"btree::normal_node Fusing or rebalancing a node");
719 fuse_or_balance(it, m_btree->m_node_cache);
730 it != block().begin() + size(); ++it)
733 m_btree->m_leaf_cache.delete_node((
leaf_bid_type)it->second);
739 it != block().begin() + size(); ++it)
745 m_btree->m_node_cache.delete_node((
node_bid_type)it->second);
753 ++(m_block->info.cur_size);
761 #endif // !STXXL_CONTAINERS_BTREE_NODE_HEADER
block_type::iterator block_iterator
#define STXXL_ASSERT(condition)
const_iterator lower_bound(const key_type &k, unsigned height) const
std::pair< key_type, bid_type > value_type
const_iterator upper_bound(const key_type &k, unsigned height) const
btree_type::leaf_type leaf_type
normal_node(btree_type *btree, key_compare cmp)
info_type info
Per block information element.
static unsigned max_nelements()
std::pair< iterator, bool > insert(const btree_value_type &x, unsigned height, std::pair< key_type, bid_type > &splitter)
static unsigned min_nelements()
std::pair< key_type, bid_type > insert(const std::pair< key_type, bid_type > &splitter, const block_iterator &place2insert)
btree_type::value_type btree_value_type
btree_type::iterator iterator
void init(const bid_type &my_bid_)
value_compare(key_compare c)
btree_type::size_type size_type
normal_node< KeyType, KeyCmp, RawSize, BTreeType > self_type
Block containing elements of fixed length.
virtual void wait(bool measure_time=true)=0
Suspends calling thread until completion of the request.
btree_type::leaf_bid_type leaf_bid_type
const value_type & const_reference
typed_block< raw_size, value_type, 0, metainfo_type > block_type
void push_back(const value_type &x)
const_pointer const_iterator
block_type::const_iterator block_const_iterator
request_ptr load(const bid_type &bid)
#define STXXL_BEGIN_NAMESPACE
void fuse(const normal_node &src)
#define STXXL_VERBOSE1(x)
void deallocate_children(unsigned height)
iterator begin()
Returns iterator pointing to the first element.
size_type erase(const key_type &k, unsigned height)
btree_type::const_iterator const_iterator
request_ptr prefetch(const bid_type &bid)
node_cache< normal_node, btree_type > node_cache_type
key_type balance(normal_node &left, bool check_constraints=true)
const_iterator begin(unsigned height) const
const_reference front() const
iterator lower_bound(const key_type &k, unsigned height)
void fuse_or_balance(block_iterator UIt, CacheType &cache)
const_iterator find(const key_type &k, unsigned height) const
const_reference back() const
iterator find(const key_type &k, unsigned height)
iterator begin(unsigned height)
#define STXXL_END_NAMESPACE
iterator upper_bound(const key_type &k, unsigned height)