13 #ifndef STXXL_CONTAINERS_BTREE_BTREE_HEADER 
   14 #define STXXL_CONTAINERS_BTREE_BTREE_HEADER 
   31 template <
class KeyType,
 
   82         min_node_size = node_type::min_size,
 
   83         max_node_size = node_type::max_size,
 
   84         min_leaf_size = leaf_type::min_size,
 
   85         max_leaf_size = leaf_type::max_size
 
  111         std::pair<root_node_iterator_type, bool> result =
 
  112             root_node_.insert(splitter);
 
  114         if (root_node_.size() > max_node_size)          
 
  116             STXXL_VERBOSE1(
"btree::insert_into_root, overflow happened, splitting");
 
  119             node_type* LeftNode = node_cache_.get_new_node(LeftBid);
 
  122             node_type* RightNode = node_cache_.get_new_node(RightBid);
 
  137             LeftNode->
block().
info.cur_size = (
unsigned int)half;
 
  149             key_type RightKey = (RightNode->
block()[right_size - 1]).first;
 
  151             assert(old_size == RightNode->
size() + LeftNode->
size());
 
  161             if (node_cache_.size() < (height_ - 1))
 
  163                 STXXL_THROW2(std::runtime_error, 
"btree::bulk_construction", 
"The height of the tree (" << height_ << 
") has exceeded the required capacity (" << (node_cache_.size() + 1) << 
") of the node cache. Increase the node cache size.");
 
  168     template <
class CacheType>
 
  171         typedef typename CacheType::node_type local_node_type;
 
  172         typedef typename local_node_type::bid_type local_bid_type;
 
  175         if (UIt->first == key_compare::max_value())             
 
  177             assert(UIt != root_node_.begin());
 
  185             assert(rightIt != root_node_.end());
 
  189         local_bid_type LeftBid = (local_bid_type)leftIt->second;
 
  190         local_bid_type RightBid = (local_bid_type)rightIt->second;
 
  191         local_node_type* LeftNode = cache_.get_node(LeftBid, 
true);
 
  192         local_node_type* RightNode = cache_.get_node(RightBid, 
true);
 
  194         const unsigned_type TotalSize = LeftNode->size() + RightNode->size();
 
  195         if (TotalSize <= RightNode->max_nelements())
 
  198             RightNode->fuse(*LeftNode);                 
 
  200             cache_.unfix_node(RightBid);
 
  201             cache_.delete_node(LeftBid);                
 
  203             root_node_.erase(leftIt);                   
 
  209             key_type NewSplitter = RightNode->balance(*LeftNode);
 
  211             root_node_.erase(leftIt);                   
 
  215             cache_.unfix_node(LeftBid);
 
  216             cache_.unfix_node(RightBid);
 
  223         leaf_type* NewLeaf = leaf_cache_.get_new_node(NewBid);
 
  225         end_iterator = NewLeaf->
end();                  
 
  235             for ( ; it != root_node_.end(); ++it)
 
  244             for ( ; it != root_node_.end(); ++it)
 
  255     template <
class InputIterator>
 
  256     void bulk_construction(InputIterator b, InputIterator e, 
double node_fill_factor, 
double leaf_fill_factor)
 
  258         assert(node_fill_factor >= 0.5);
 
  259         assert(leaf_fill_factor >= 0.5);
 
  260         key_type lastKey = key_compare::max_value();
 
  262         typedef std::pair<key_type, node_bid_type> key_bid_pair;
 
  264                                                  node_block_type::raw_size>::result key_bid_vector_type;
 
  266         key_bid_vector_type Bids;
 
  269         leaf_type* Leaf = leaf_cache_.get_new_node(NewBid);
 
  277             if (key_compare_(b->first, lastKey) || key_compare_(lastKey, b->first))
 
  280                 if (Leaf->
size() == max_leaf_elements)
 
  285                     leaf_type* NewLeaf = leaf_cache_.get_new_node(NewBid);
 
  306                 Leaf->
fuse(*LeftLeaf);
 
  307                 leaf_cache_.delete_node((
leaf_bid_type)(Bids.back().second));
 
  315                 Bids.back().first = NewSplitter;
 
  322         end_iterator = Leaf->
end();                 
 
  324         Bids.push_back(key_bid_pair(key_compare::max_value(), (
node_bid_type)NewBid));
 
  328         while (Bids.size() > max_node_elements)
 
  330             key_bid_vector_type ParentBids;
 
  333             assert(nparents >= 2);
 
  334             STXXL_VERBOSE1(
"btree bulk constructBids.size() " << Bids.size() << 
" nparents: " << nparents << 
" max_ns: " 
  335                                                               << max_node_elements);
 
  337             typename key_bid_vector_type::const_iterator it = Bids.begin();
 
  342                 node_type* Node = node_cache_.get_new_node(NewBid);
 
  345                 for ( ; cnt < max_node_elements && it != Bids.end(); ++cnt, ++it)
 
  354                     assert(it == Bids.end());                           
 
  355                     assert(!ParentBids.empty());
 
  357                     node_type* LeftNode = node_cache_.get_node(ParentBids.back().second);
 
  361                         Node->
fuse(*LeftNode);
 
  362                         node_cache_.delete_node(ParentBids.back().second);
 
  363                         ParentBids.pop_back();
 
  368                         ParentBids.back().first = NewSplitter;
 
  369                         assert(!LeftNode->overflows() && !LeftNode->underflows());
 
  374                 ParentBids.push_back(key_bid_pair(Node->
back().first, NewBid));
 
  375             } 
while (it != Bids.end());
 
  377             std::swap(ParentBids, Bids);
 
  379             assert(nparents == Bids.size() || (nparents - 1) == Bids.size());
 
  383             if (node_cache_.size() < (height_ - 1))
 
  385                 STXXL_THROW2(std::runtime_error, 
"btree::bulk_construction", 
"The height of the tree (" << height_ << 
") has exceeded the required capacity (" << (node_cache_.size() + 1) << 
") of the node cache. Increase the node cache size.");
 
  389         root_node_.insert(Bids.begin(), Bids.end());
 
  396         node_cache_(node_cache_size_in_bytes, this, key_compare_),
 
  397         leaf_cache_(leaf_cache_size_in_bytes, this, key_compare_),
 
  401         prefetching_enabled_(true),
 
  421         node_cache_(node_cache_size_in_bytes, this, key_compare_),
 
  422         leaf_cache_(leaf_cache_size_in_bytes, this, key_compare_),
 
  426         prefetching_enabled_(true),
 
  440             deallocate_children();
 
  465         assert(!root_node_.empty());
 
  466         assert(it != root_node_.end());
 
  472             std::pair<key_type, leaf_bid_type> Splitter;
 
  473             std::pair<iterator, bool> result = Leaf->
insert(x, Splitter);
 
  479             if (!(key_compare_(key_compare::max_value(), Splitter.first) ||
 
  480                   key_compare_(Splitter.first, key_compare::max_value())))
 
  486             insert_into_root(std::make_pair(Splitter.first, 
node_bid_type(Splitter.second)));
 
  488             assert(leaf_cache_.nfixed() == 0);
 
  489             assert(node_cache_.nfixed() == 0);
 
  497         std::pair<key_type, node_bid_type> Splitter;
 
  498         std::pair<iterator, bool> result = Node->
insert(x, height_ - 1, Splitter);
 
  504         if (!(key_compare_(key_compare::max_value(), Splitter.first) ||
 
  505               key_compare_(Splitter.first, key_compare::max_value())))
 
  511         insert_into_root(Splitter);
 
  513         assert(leaf_cache_.nfixed() == 0);
 
  514         assert(node_cache_.nfixed() == 0);
 
  522         assert(it != root_node_.end());
 
  530             assert(leaf_cache_.nfixed() == 0);
 
  531             assert(node_cache_.nfixed() == 0);
 
  532             return Leaf->
begin();
 
  542         assert(leaf_cache_.nfixed() == 0);
 
  543         assert(node_cache_.nfixed() == 0);
 
  551         assert(it != root_node_.end());
 
  558             assert(leaf_cache_.nfixed() == 0);
 
  559             assert(node_cache_.nfixed() == 0);
 
  560             return Leaf->
begin();
 
  569         assert(leaf_cache_.nfixed() == 0);
 
  570         assert(node_cache_.nfixed() == 0);
 
  592         assert(it != root_node_.end());
 
  601             assert(result == end() || result->first == k);
 
  602             assert(leaf_cache_.nfixed() == 0);
 
  603             assert(node_cache_.nfixed() == 0);
 
  614         assert(result == end() || result->first == k);
 
  615         assert(leaf_cache_.nfixed() == 0);
 
  616         assert(node_cache_.nfixed() == 0);
 
  623         assert(it != root_node_.end());
 
  632             assert(result == end() || result->first == k);
 
  633             assert(leaf_cache_.nfixed() == 0);
 
  634             assert(node_cache_.nfixed() == 0);
 
  645         assert(result == end() || result->first == k);
 
  646         assert(leaf_cache_.nfixed() == 0);
 
  647         assert(node_cache_.nfixed() == 0);
 
  654         assert(it != root_node_.end());
 
  663             assert(leaf_cache_.nfixed() == 0);
 
  664             assert(node_cache_.nfixed() == 0);
 
  675         assert(leaf_cache_.nfixed() == 0);
 
  676         assert(node_cache_.nfixed() == 0);
 
  683         assert(it != root_node_.end());
 
  693             assert(leaf_cache_.nfixed() == 0);
 
  694             assert(node_cache_.nfixed() == 0);
 
  705         assert(leaf_cache_.nfixed() == 0);
 
  706         assert(node_cache_.nfixed() == 0);
 
  713         assert(it != root_node_.end());
 
  723             assert(leaf_cache_.nfixed() == 0);
 
  724             assert(node_cache_.nfixed() == 0);
 
  735         assert(leaf_cache_.nfixed() == 0);
 
  736         assert(node_cache_.nfixed() == 0);
 
  743         assert(it != root_node_.end());
 
  753             assert(leaf_cache_.nfixed() == 0);
 
  754             assert(node_cache_.nfixed() == 0);
 
  765         assert(leaf_cache_.nfixed() == 0);
 
  766         assert(node_cache_.nfixed() == 0);
 
  774         if (l == end() || key_compare_(k, l->first))                    
 
  775             return std::pair<iterator, iterator>(l, l);
 
  781         assert(leaf_cache_.nfixed() == 0);
 
  782         assert(node_cache_.nfixed() == 0);
 
  784         return std::pair<iterator, iterator>(l, u);                     
 
  791         if (l == end() || key_compare_(k, l->first))                    
 
  792             return std::pair<const_iterator, const_iterator>(l, l);
 
  798         assert(leaf_cache_.nfixed() == 0);
 
  799         assert(node_cache_.nfixed() == 0);
 
  800         return std::pair<const_iterator, const_iterator>(l, u);         
 
  806         assert(it != root_node_.end());
 
  815             assert(leaf_cache_.nfixed() == 0);
 
  816             assert(node_cache_.nfixed() == 0);
 
  818             if ((!Leaf->
underflows()) || root_node_.size() == 1)
 
  823             fuse_or_balance(it, leaf_cache_);
 
  825             assert(leaf_cache_.nfixed() == 0);
 
  826             assert(node_cache_.nfixed() == 0);
 
  833         assert(root_node_.size() >= 2);
 
  836         size_type result = Node->erase(k, height_ - 1);
 
  839         assert(leaf_cache_.nfixed() == 0);
 
  840         assert(node_cache_.nfixed() == 0);
 
  841         if (!Node->underflows())
 
  846         fuse_or_balance(it, node_cache_);
 
  848         if (root_node_.size() == 1)
 
  852             it = root_node_.begin();
 
  854             assert(it->first == key_compare::max_value());
 
  855             node_type* RootNode = node_cache_.get_node(RootBid);
 
  857             assert(RootNode->
back().first == key_compare::max_value());
 
  862             node_cache_.delete_node(RootBid);
 
  867         assert(leaf_cache_.nfixed() == 0);
 
  868         assert(node_cache_.nfixed() == 0);
 
  875         if (
find(k) == end())
 
  883         assert(pos != end());
 
  890         assert(size() == old_size - 1);
 
  895         return insert(x).first;                 
 
  900         deallocate_children();
 
  908         assert(leaf_cache_.nfixed() == 0);
 
  909         assert(node_cache_.nfixed() == 0);
 
  912     template <
class InputIterator>
 
  913     void insert(InputIterator b, InputIterator e)
 
  921     template <
class InputIterator>
 
  927           bool range_sorted = 
false,
 
  928           double node_fill_factor = 0.75,
 
  929           double leaf_fill_factor = 0.6
 
  932         node_cache_(node_cache_size_in_bytes, this, key_compare_),
 
  933         leaf_cache_(leaf_cache_size_in_bytes, this, key_compare_),
 
  937         prefetching_enabled_(true),
 
  944         if (range_sorted == 
false)
 
  948             assert(leaf_cache_.nfixed() == 0);
 
  949             assert(node_cache_.nfixed() == 0);
 
  953         bulk_construction(b, e, node_fill_factor, leaf_fill_factor);
 
  954         assert(leaf_cache_.nfixed() == 0);
 
  955         assert(node_cache_.nfixed() == 0);
 
  959     template <
class InputIterator>
 
  964           bool range_sorted = 
false,
 
  965           double node_fill_factor = 0.75,
 
  966           double leaf_fill_factor = 0.6
 
  968         node_cache_(node_cache_size_in_bytes, this, key_compare_),
 
  969         leaf_cache_(leaf_cache_size_in_bytes, this, key_compare_),
 
  973         prefetching_enabled_(true),
 
  980         if (range_sorted == 
false)
 
  984             assert(leaf_cache_.nfixed() == 0);
 
  985             assert(node_cache_.nfixed() == 0);
 
  989         bulk_construction(b, e, node_fill_factor, leaf_fill_factor);
 
  990         assert(leaf_cache_.nfixed() == 0);
 
  991         assert(node_cache_.nfixed() == 0);
 
  996         if (first == begin() && last == end())
 
 1000             while (first != last)
 
 1006         return key_compare_;
 
 1024         std::swap(size_, obj.
size_);
 
 1025         std::swap(height_, obj.
height_);
 
 1032         prefetching_enabled_ = 
true;
 
 1036         prefetching_enabled_ = 
false;
 
 1040         return prefetching_enabled_;
 
 1045         o << 
"Node cache statistics:" << std::endl;
 
 1046         node_cache_.print_statistics(o);
 
 1047         o << 
"Leaf cache statistics:" << std::endl;
 
 1048         leaf_cache_.print_statistics(o);
 
 1052         node_cache_.reset_statistics();
 
 1053         leaf_cache_.reset_statistics();
 
 1057 template <
class KeyType,
 
 1060           unsigned LogNodeSize,
 
 1061           unsigned LogLeafSize,
 
 1062           class PDAllocStrategy
 
 1070 template <
class KeyType,
 
 1073           unsigned LogNodeSize,
 
 1074           unsigned LogLeafSize,
 
 1075           class PDAllocStrategy
 
 1084 template <
class KeyType,
 
 1087           unsigned LogNodeSize,
 
 1088           unsigned LogLeafSize,
 
 1089           class PDAllocStrategy
 
 1091 inline bool operator < (const btree<KeyType, DataType, CompareType, LogNodeSize, LogLeafSize, PDAllocStrategy>& a,
 
 1094     return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
 
 1098 template <
class KeyType,
 
 1101           unsigned LogNodeSize,
 
 1102           unsigned LogLeafSize,
 
 1103           class PDAllocStrategy
 
 1112 template <
class KeyType,
 
 1115           unsigned LogNodeSize,
 
 1116           unsigned LogLeafSize,
 
 1117           class PDAllocStrategy
 
 1119 inline bool operator <= (const btree<KeyType, DataType, CompareType, LogNodeSize, LogLeafSize, PDAllocStrategy>& a,
 
 1125 template <
class KeyType,
 
 1128           unsigned LogNodeSize,
 
 1129           unsigned LogLeafSize,
 
 1130           class PDAllocStrategy
 
 1145 template <
class KeyType,
 
 1148           unsigned LogNodeSize,
 
 1149           unsigned LogLeafSize,
 
 1150           class PDAllocStrategy
 
 1161 #endif // !STXXL_CONTAINERS_BTREE_BTREE_HEADER 
std::pair< key_type, bid_type > insert(const std::pair< key_type, bid_type > &splitter, const block_iterator &place2insert)
#define STXXL_ASSERT(condition)
node_cache< leaf_type, SelfType > leaf_cache_type
std::pair< iterator, bool > insert(const value_type &x, std::pair< key_type, bid_type > &splitter)
const bid_type & my_bid() const 
bool prefetching_enabled_
key_type balance(normal_node &Left)
void insert(InputIterator b, InputIterator e)
std::pair< iterator, iterator > equal_range(const key_type &k)
unsigned long long int uint64
void bulk_construction(InputIterator b, InputIterator e, double node_fill_factor, double leaf_fill_factor)
std::pair< const_iterator, const_iterator > equal_range(const key_type &k) const 
std::map< key_type, node_bid_type, key_compare > root_node_type
const_iterator end() const 
info_type info
Per block information element. 
void deallocate_children()
normal_node< key_type, key_compare, RawNodeSize, SelfType > node_type
iterator_map< SelfType > iterator_map_type
unsigned min_nelements() const 
btree_const_iterator< SelfType > const_iterator
node_type::block_type node_block_type
PDAllocStrategy alloc_strategy_type
const_iterator lower_bound(const key_type &k) const 
void fuse(const normal_node &Src)
void insert_into_root(const std::pair< key_type, node_bid_type > &splitter)
void erase(iterator first, iterator last)
size_type erase(const key_type &k)
iterator upper_bound(const key_type &k)
btree(unsigned_type node_cache_size_in_bytes, unsigned_type leaf_cache_size_in_bytes)
iterator lower_bound(const key_type &k)
std::pair< iterator, bool > insert(const value_type &x)
size_type erase(const key_type &k)
alloc_strategy_type alloc_strategy_
leaf_type::block_type leaf_block_type
iterator find(const key_type &k)
iterator find(const key_type &k, unsigned height)
std::pair< const key_type, data_type > value_type
key_type balance(normal_leaf &Left)
iterator insert(iterator, const value_type &x)
root_node_type::const_iterator root_node_const_iterator_type
Block containing elements of fixed length. 
unsigned max_nelements() const 
stxxl::int64 difference_type
bool prefetching_enabled()
bool operator!=(const uint_pair &b) const 
inequality checking operator 
normal_leaf< key_type, data_type, key_compare, RawLeafSize, SelfType > leaf_type
const value_type & const_reference
bool operator>(const uint_pair &b) const 
greater comparison operator 
btree(InputIterator b, InputIterator e, unsigned_type node_cache_size_in_bytes, unsigned_type leaf_cache_size_in_bytes, bool range_sorted=false, double node_fill_factor=0.75, double leaf_fill_factor=0.6)
iterator_map_type iterator_map_
void enable_prefetching()
const_iterator upper_bound(const key_type &k) const 
bool operator>=(const uint_pair &b) const 
greater-or-equal comparison operator 
leaf_cache_type leaf_cache_
#define STXXL_BEGIN_NAMESPACE
void STXXL_UNUSED(const U &)
iterator lower_bound(const key_type &k)
size_type count(const key_type &k)
iterator begin(unsigned height)
#define STXXL_VERBOSE1(x)
btree_iterator< SelfType > iterator
value_compare value_comp() const 
btree(const key_compare &c_, unsigned_type node_cache_size_in_bytes, unsigned_type leaf_cache_size_in_bytes)
void fuse_or_balance(root_node_iterator_type UIt, CacheType &cache_)
#define STXXL_THROW2(exception_type, location, error_message)
Throws exception_type with "Error in [location] : [error_message]". 
static uint_pair max()
return an uint_pair instance containing the largest value possible 
node_cache_type node_cache_
iterator begin()
Returns iterator pointing to the first element. 
value_type const * const_pointer
void deallocate_children(unsigned height)
iterator find(const key_type &k)
iterator upper_bound(const key_type &k)
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
compat::remove_const< Integral >::type div_ceil(Integral __n, Integral2 __d)
node_cache< node_type, SelfType > node_cache_type
void push_back(const value_type &x)
unsigned max_nelements() const 
void print_statistics(std::ostream &o) const 
root_node_type root_node_
size_type max_size() const 
root_node_type::iterator root_node_iterator_type
node_type::bid_type node_bid_type
leaf_type::bid_type leaf_bid_type
btree(InputIterator b, InputIterator e, const key_compare &c_, unsigned_type node_cache_size_in_bytes, unsigned_type leaf_cache_size_in_bytes, bool range_sorted=false, double node_fill_factor=0.75, double leaf_fill_factor=0.6)
iterator lower_bound(const key_type &k, unsigned height)
const_iterator find(const key_type &k) const 
ExtIterator find(ExtIterator begin, ExtIterator end, const EqualityComparable &value, int_type nbuffers=0)
External equivalent of std::find, see stxxl::find. 
void disable_prefetching()
leaf_type::value_compare value_compare
External vector type generator. 
void push_back(const value_type &x)
const_iterator begin() const 
std::pair< key_type, node_bid_type > root_node_pair_type
void fuse(const normal_leaf &Src)
key_compare key_comp() const 
bool operator==(const uint_pair &b) const 
equality checking operator 
#define STXXL_END_NAMESPACE
btree< KeyType, DataType, CompareType, RawNodeSize, RawLeafSize, PDAllocStrategy > SelfType
iterator upper_bound(const key_type &k, unsigned height)