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