13 #ifndef STXXL_CONTAINERS_BTREE_NODE_HEADER
14 #define STXXL_CONTAINERS_BTREE_NODE_HEADER
24 template <
class NodeType,
class BTreeType>
27 template <
class KeyType_,
class KeyCmp_,
unsigned RawSize_,
class BTreeType>
57 nelements = block_type::size - 1,
59 min_size = nelements / 2
66 typedef typename btree_type::iterator
iterator;
76 struct value_compare :
public std::binary_function<value_type, value_type, bool>
84 return comp(x.first, y.first);
94 std::pair<key_type, bid_type>
insert(
const std::pair<key_type, bid_type>& splitter,
97 std::pair<key_type, bid_type> result(key_compare::max_value(),
bid_type());
100 assert(vcmp_(*place2insert, splitter) || vcmp_(splitter, *place2insert));
103 for ( ; cur >= place2insert; --cur)
107 *place2insert = splitter;
109 ++(block_->info.cur_size);
111 if (size() > max_nelements())
113 STXXL_VERBOSE1(
"btree::normal_node::insert overflow happened, splitting");
116 btree_->node_cache_.get_new_node(NewBid);
117 normal_node* NewNode = btree_->node_cache_.get_node(NewBid,
true);
120 const unsigned end_of_smaller_part = size() / 2;
122 result.first = ((*block_)[end_of_smaller_part - 1]).first;
123 result.second = NewBid;
126 const unsigned old_size = size();
128 std::copy(block_->begin(), block_->begin() + end_of_smaller_part, NewNode->
block_->
begin());
129 NewNode->
block_->
info.cur_size = end_of_smaller_part;
131 std::copy(block_->begin() + end_of_smaller_part,
132 block_->begin() + old_size, block_->begin());
133 block_->info.cur_size = old_size - end_of_smaller_part;
134 assert(size() + NewNode->
size() == old_size);
136 btree_->node_cache_.unfix_node(NewBid);
139 <<
" splitter: " << result.first);
145 template <
class CacheType>
148 typedef typename CacheType::node_type local_node_type;
149 typedef typename local_node_type::bid_type local_bid_type;
152 if (UIt == (block_->begin() + size() - 1))
154 assert(UIt != block_->begin());
162 assert(rightIt != (block_->begin() + size()));
166 local_bid_type LeftBid = (local_bid_type)leftIt->second;
167 local_bid_type RightBid = (local_bid_type)rightIt->second;
168 local_node_type* LeftNode = cache_.get_node(LeftBid,
true);
169 local_node_type* RightNode = cache_.get_node(RightBid,
true);
171 const unsigned TotalSize = LeftNode->size() + RightNode->size();
172 if (TotalSize <= RightNode->max_nelements())
175 RightNode->fuse(*LeftNode);
177 cache_.unfix_node(RightBid);
178 cache_.delete_node(LeftBid);
180 std::copy(leftIt + 1, block_->begin() + size(), leftIt);
181 --(block_->info.cur_size);
187 key_type NewSplitter = RightNode->balance(*LeftNode);
190 leftIt->first = NewSplitter;
191 assert(vcmp_(*leftIt, *rightIt));
193 cache_.unfix_node(LeftBid);
194 cache_.unfix_node(RightBid);
211 assert(min_nelements() >= 2);
212 assert(2 * min_nelements() - 1 <= max_nelements());
213 assert(max_nelements() <= nelements);
214 assert(
unsigned(block_type::size) >= nelements + 1);
222 bool overflows()
const {
return block_->info.cur_size > max_nelements(); }
223 bool underflows()
const {
return block_->info.cur_size < min_nelements(); }
254 return block_->info.cur_size;
259 return block_->info.me;
272 assert(bid == my_bid());
278 return block_->read(bid);
283 block_->info.me = my_bid_;
284 block_->info.cur_size = 0;
299 return (*block_)[size() - 1];
304 return *(block_->begin());
309 return (*block_)[size() - 1];
314 return *(block_->begin());
321 std::pair<key_type, bid_type>& splitter)
323 assert(size() <= max_nelements());
324 splitter.first = key_compare::max_value();
328 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
330 assert(it != (block_->begin() + size()));
337 STXXL_VERBOSE1(
"btree::normal_node Inserting new value into a leaf");
340 std::pair<key_type, leaf_bid_type> BotSplitter;
341 std::pair<iterator, bool> result = Leaf->insert(x, BotSplitter);
344 if (!(cmp_(key_compare::max_value(), BotSplitter.first) ||
345 cmp_(BotSplitter.first, key_compare::max_value())))
349 STXXL_VERBOSE1(
"btree::normal_node Inserting new value in *this");
351 splitter = insert(std::make_pair(BotSplitter.first,
bid_type(BotSplitter.second)), it);
357 STXXL_VERBOSE1(
"btree::normal_node Inserting new value into a node");
360 std::pair<key_type, node_bid_type> BotSplitter;
361 std::pair<iterator, bool> result = Node->
insert(x, height - 1, BotSplitter);
364 if (!(cmp_(key_compare::max_value(), BotSplitter.first) ||
365 cmp_(BotSplitter.first, key_compare::max_value())))
369 STXXL_VERBOSE1(
"btree::normal_node Inserting new value in *this");
371 splitter = insert(BotSplitter, it);
379 bid_type FirstBid = block_->begin()->second;
383 STXXL_VERBOSE1(
"btree::node retrieveing begin() from the first leaf");
386 return Leaf->begin();
401 bid_type FirstBid = block_->begin()->second;
405 STXXL_VERBOSE1(
"btree::node retrieveing begin() from the first leaf");
408 return Leaf->begin();
426 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
428 assert(it != (block_->begin() + size()));
458 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
460 assert(it != (block_->begin() + size()));
488 assert(!vcmp_(back(), Key2Search));
490 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
492 assert(it != (block_->begin() + size()));
501 iterator result = Leaf->lower_bound(k);
520 assert(!vcmp_(back(), Key2Search));
522 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
524 assert(it != (block_->begin() + size()));
552 assert(vcmp_(Key2Search, back()));
554 std::upper_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
556 assert(it != (block_->begin() + size()));
565 iterator result = Leaf->upper_bound(k);
584 assert(vcmp_(Key2Search, back()));
586 std::upper_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
588 assert(it != (block_->begin() + size()));
615 assert(vcmp_(Src.
back(), front()));
616 const unsigned SrcSize = Src.
size();
621 for ( ; cur >= begin; --cur)
622 *(cur + SrcSize) = *cur;
628 block_->info.cur_size += SrcSize;
634 const unsigned TotalSize = Left.
size() + size();
635 unsigned newLeftSize = TotalSize / 2;
638 unsigned newRightSize = TotalSize - newLeftSize;
639 assert(newRightSize <= max_nelements());
640 assert(newRightSize >= min_nelements());
642 assert(vcmp_(Left.
back(), front()) || size() == 0);
644 if (newLeftSize < Left.
size())
646 const unsigned nEl2Move = Left.
size() - newLeftSize;
651 for ( ; cur >= begin; --cur)
652 *(cur + nEl2Move) = *cur;
661 assert(newRightSize < size());
663 const unsigned nEl2Move = size() - newRightSize;
666 std::copy(block_->begin(),
669 std::copy(block_->begin() + nEl2Move,
670 block_->begin() + size(), block_->begin());
673 block_->info.cur_size = newRightSize;
676 return Left.
back().first;
684 std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
686 assert(it != (block_->begin() + size()));
699 if (!Leaf->underflows())
703 STXXL_VERBOSE1(
"btree::normal_node Fusing or rebalancing a leaf");
704 fuse_or_balance(it, btree_->leaf_cache_);
719 STXXL_VERBOSE1(
"btree::normal_node Fusing or rebalancing a node");
720 fuse_or_balance(it, btree_->node_cache_);
731 for ( ; it != block().begin() + size(); ++it)
740 for ( ; it != block().begin() + size(); ++it)
754 ++(block_->info.cur_size);
764 #endif // !STXXL_CONTAINERS_BTREE_NODE_HEADER
btree_type::value_type btree_value_type
std::pair< key_type, bid_type > insert(const std::pair< key_type, bid_type > &splitter, const block_iterator &place2insert)
key_type balance(normal_node &Left)
void fuse_or_balance(block_iterator UIt, CacheType &cache_)
info_type info
Per block information element.
btree_type::leaf_type leaf_type
btree_type::size_type size_type
value_compare(key_compare c)
unsigned min_nelements() const
block_type::const_iterator block_const_iterator
btree_type::iterator iterator
normal_node< KeyType_, KeyCmp_, RawSize_, BTreeType > SelfType
void fuse(const normal_node &Src)
request_ptr prefetch(const bid_type &bid)
block_type::iterator block_iterator
iterator find(const key_type &k, unsigned height)
const_iterator upper_bound(const key_type &k, unsigned height) const
btree_type::const_iterator const_iterator
Block containing elements of fixed length.
virtual void wait(bool measure_time=true)=0
Suspends calling thread until completion of the request.
unsigned max_nelements() const
std::pair< iterator, bool > insert(const btree_value_type &x, unsigned height, std::pair< key_type, bid_type > &splitter)
const_pointer const_iterator
btree_type::leaf_bid_type leaf_bid_type
#define STXXL_BEGIN_NAMESPACE
void STXXL_UNUSED(const U &)
normal_node(btree_type *btree__, key_compare cmp)
iterator begin(unsigned height)
#define STXXL_VERBOSE1(x)
node_cache< normal_node, btree_type > node_cache_type
size_type erase(const key_type &k, unsigned height)
iterator begin()
Returns iterator pointing to the first element.
const_iterator lower_bound(const key_type &k, unsigned height) const
const value_type & const_reference
const_reference back() const
void deallocate_children(unsigned height)
const_iterator begin(unsigned height) const
iterator lower_bound(const key_type &k, unsigned height)
std::pair< key_type, bid_type > value_type
typed_block< raw_size, value_type, 0, InfoType > block_type
void push_back(const value_type &x)
request_ptr load(const bid_type &bid)
const_iterator find(const key_type &k, unsigned height) const
#define STXXL_END_NAMESPACE
const_reference front() const
void init(const bid_type &my_bid_)
iterator upper_bound(const key_type &k, unsigned height)