Stxxl  1.3.2
node.h
1 /***************************************************************************
2  * include/stxxl/bits/containers/btree/node.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2006 Roman Dementiev <[email protected]>
7  *
8  * Distributed under the Boost Software License, Version 1.0.
9  * (See accompanying file LICENSE_1_0.txt or copy at
10  * http://www.boost.org/LICENSE_1_0.txt)
11  **************************************************************************/
12 
13 #ifndef STXXL_CONTAINERS_BTREE__NODE_H
14 #define STXXL_CONTAINERS_BTREE__NODE_H
15 
16 #include <stxxl/bits/containers/btree/iterator.h>
17 #include <stxxl/bits/containers/btree/node_cache.h>
18 
19 
20 __STXXL_BEGIN_NAMESPACE
21 
22 namespace btree
23 {
24  template <class NodeType, class BTreeType>
25  class node_cache;
26 
27  template <class KeyType_, class KeyCmp_, unsigned RawSize_, class BTreeType>
28  class normal_node : private noncopyable
29  {
30  public:
31  typedef normal_node<KeyType_, KeyCmp_, RawSize_, BTreeType> SelfType;
32 
33  friend class node_cache<SelfType, BTreeType>;
34 
35  typedef KeyType_ key_type;
36  typedef KeyCmp_ key_compare;
37 
38  enum {
39  raw_size = RawSize_
40  };
41  typedef BID<raw_size> bid_type;
42  typedef bid_type node_bid_type;
43  typedef SelfType node_type;
44  typedef std::pair<key_type, bid_type> value_type;
45  typedef value_type & reference;
46  typedef const value_type & const_reference;
47 
48 
49  struct InfoType
50  {
51  bid_type me;
52  unsigned cur_size;
53  };
55 
56  enum {
57  nelements = block_type::size - 1,
58  max_size = nelements,
59  min_size = nelements / 2
60  };
61  typedef typename block_type::iterator block_iterator;
62  typedef typename block_type::const_iterator block_const_iterator;
63 
64  typedef BTreeType btree_type;
65  typedef typename btree_type::size_type size_type;
66  typedef typename btree_type::iterator iterator;
67  typedef typename btree_type::const_iterator const_iterator;
68 
69  typedef typename btree_type::value_type btree_value_type;
70  typedef typename btree_type::leaf_bid_type leaf_bid_type;
71  typedef typename btree_type::leaf_type leaf_type;
72 
73  typedef node_cache<normal_node, btree_type> node_cache_type;
74 
75  private:
76  struct value_compare : public std::binary_function<value_type, value_type, bool>
77  {
78  key_compare comp;
79 
80  value_compare(key_compare c) : comp(c) { }
81 
82  bool operator () (const value_type & x, const value_type & y) const
83  {
84  return comp(x.first, y.first);
85  }
86  };
87 
88  block_type * block_;
89  btree_type * btree_;
90  key_compare cmp_;
91  value_compare vcmp_;
92 
93 
94  template <class BIDType>
95  std::pair<key_type, bid_type> insert(const std::pair<key_type, BIDType> & splitter,
96  const block_iterator & place2insert)
97  {
98  std::pair<key_type, bid_type> result(key_compare::max_value(), bid_type());
99 
100  // splitter != *place2insert
101  assert(vcmp_(*place2insert, splitter) || vcmp_(splitter, *place2insert));
102 
103  block_iterator cur = block_->begin() + size() - 1;
104  for ( ; cur >= place2insert; --cur)
105  *(cur + 1) = *cur;
106  // copy elements to make space for the new element
107 
108  *place2insert = splitter; // insert
109 
110  ++(block_->info.cur_size);
111 
112  if (size() > max_nelements()) // overflow! need to split
113  {
114  STXXL_VERBOSE1("btree::normal_node::insert overflow happened, splitting");
115 
116  bid_type NewBid;
117  btree_->node_cache_.get_new_node(NewBid); // new (left) node
118  normal_node * NewNode = btree_->node_cache_.get_node(NewBid, true);
119  assert(NewNode);
120 
121  const unsigned end_of_smaller_part = size() / 2;
122 
123  result.first = ((*block_)[end_of_smaller_part - 1]).first;
124  result.second = NewBid;
125 
126 
127  const unsigned old_size = size();
128  // copy the smaller part
129  std::copy(block_->begin(), block_->begin() + end_of_smaller_part, NewNode->block_->begin());
130  NewNode->block_->info.cur_size = end_of_smaller_part;
131  // copy the larger part
132  std::copy(block_->begin() + end_of_smaller_part,
133  block_->begin() + old_size, block_->begin());
134  block_->info.cur_size = old_size - end_of_smaller_part;
135  assert(size() + NewNode->size() == old_size);
136 
137  btree_->node_cache_.unfix_node(NewBid);
138 
139  STXXL_VERBOSE1("btree::normal_node split leaf " << this
140  << " splitter: " << result.first);
141  }
142 
143  return result;
144  }
145 
146  template <class CacheType>
147  void fuse_or_balance(block_iterator UIt, CacheType & cache_)
148  {
149  typedef typename CacheType::node_type local_node_type;
150  typedef typename local_node_type::bid_type local_bid_type;
151 
152  block_iterator leftIt, rightIt;
153  if (UIt == (block_->begin() + size() - 1)) // UIt is the last entry in the root
154  {
155  assert(UIt != block_->begin());
156  rightIt = UIt;
157  leftIt = --UIt;
158  }
159  else
160  {
161  leftIt = UIt;
162  rightIt = ++UIt;
163  assert(rightIt != (block_->begin() + size()));
164  }
165 
166  // now fuse or balance nodes pointed by leftIt and rightIt
167  local_bid_type LeftBid = (local_bid_type)leftIt->second;
168  local_bid_type RightBid = (local_bid_type)rightIt->second;
169  local_node_type * LeftNode = cache_.get_node(LeftBid, true);
170  local_node_type * RightNode = cache_.get_node(RightBid, true);
171 
172  const unsigned TotalSize = LeftNode->size() + RightNode->size();
173  if (TotalSize <= RightNode->max_nelements())
174  {
175  // fuse
176  RightNode->fuse(*LeftNode); // add the content of LeftNode to RightNode
177 
178  cache_.unfix_node(RightBid);
179  cache_.delete_node(LeftBid); // 'delete_node' unfixes LeftBid also
180 
181  std::copy(leftIt + 1, block_->begin() + size(), leftIt); // delete left BID from the root
182  --(block_->info.cur_size);
183  }
184  else
185  {
186  // balance
187 
188  key_type NewSplitter = RightNode->balance(*LeftNode);
189 
190 
191  leftIt->first = NewSplitter; // change key
192  assert(vcmp_(*leftIt, *rightIt));
193 
194  cache_.unfix_node(LeftBid);
195  cache_.unfix_node(RightBid);
196  }
197  }
198 
199  public:
200  virtual ~normal_node()
201  {
202  delete block_;
203  }
204 
205  normal_node(btree_type * btree__,
206  key_compare cmp) :
207  block_(new block_type),
208  btree_(btree__),
209  cmp_(cmp),
210  vcmp_(cmp)
211  {
212  assert(min_nelements() >= 2);
213  assert(2 * min_nelements() - 1 <= max_nelements());
214  assert(max_nelements() <= nelements);
215  assert(unsigned(block_type::size) >= nelements + 1); // extra space for an overflow
216  }
217 
218  block_type & block()
219  {
220  return *block_;
221  }
222 
223  bool overflows() const { return block_->info.cur_size > max_nelements(); }
224  bool underflows() const { return block_->info.cur_size < min_nelements(); }
225 
226  unsigned max_nelements() const { return max_size; }
227  unsigned min_nelements() const { return min_size; }
228 
229  /*
230  template <class InputIterator>
231  normal_node(InputIterator begin_, InputIterator end_,
232  btree_type * btree__,
233  key_compare cmp):
234  block_(new block_type),
235  btree_(btree__),
236  cmp_(cmp),
237  vcmp_(cmp)
238  {
239  assert(min_nelements() >=2);
240  assert(2*min_nelements() - 1 <= max_nelements());
241  assert(max_nelements() <= nelements);
242  assert(unsigned(block_type::size) >= nelements +1); // extra space for an overflow
243 
244  unsigned new_size = end_ - begin_;
245  assert(new_size <= max_nelements());
246  assert(new_size >= min_nelements());
247 
248  std::copy(begin_,end_,block_->begin());
249  assert(stxxl::is_sorted(block_->begin(),block_->begin() + new_size, vcmp_));
250  block_->info.cur_size = new_size;
251  }*/
252 
253  unsigned size() const
254  {
255  return block_->info.cur_size;
256  }
257 
258  bid_type my_bid() const
259  {
260  return block_->info.me;
261  }
262 
263  void save()
264  {
265  request_ptr req = block_->write(my_bid());
266  req->wait();
267  }
268 
269  request_ptr load(const bid_type & bid)
270  {
271  request_ptr req = block_->read(bid);
272  req->wait();
273  assert(bid == my_bid());
274  return req;
275  }
276 
277  request_ptr prefetch(const bid_type & bid)
278  {
279  return block_->read(bid);
280  }
281 
282  void init(const bid_type & my_bid_)
283  {
284  block_->info.me = my_bid_;
285  block_->info.cur_size = 0;
286  }
287 
288  reference operator [] (int i)
289  {
290  return (*block_)[i];
291  }
292 
293  const_reference operator [] (int i) const
294  {
295  return (*block_)[i];
296  }
297 
298  reference back()
299  {
300  return (*block_)[size() - 1];
301  }
302 
303  reference front()
304  {
305  return *(block_->begin());
306  }
307 
308  const_reference back() const
309  {
310  return (*block_)[size() - 1];
311  }
312 
313  const_reference front() const
314  {
315  return *(block_->begin());
316  }
317 
318 
319  std::pair<iterator, bool> insert(
320  const btree_value_type & x,
321  unsigned height,
322  std::pair<key_type, bid_type> & splitter)
323  {
324  assert(size() <= max_nelements());
325  splitter.first = key_compare::max_value();
326 
327  value_type Key2Search(x.first, bid_type());
328  block_iterator it =
329  std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
330 
331  assert(it != (block_->begin() + size()));
332 
333  bid_type found_bid = it->second;
334  STXXL_UNUSED(found_bid);
335 
336  if (height == 2) // found_bid points to a leaf
337  {
338  STXXL_VERBOSE1("btree::normal_node Inserting new value into a leaf");
339  leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)it->second, true);
340  assert(Leaf);
341  std::pair<key_type, leaf_bid_type> BotSplitter;
342  std::pair<iterator, bool> result = Leaf->insert(x, BotSplitter);
343  btree_->leaf_cache_.unfix_node((leaf_bid_type)it->second);
344  //if(key_compare::max_value() == BotSplitter.first)
345  if (!(cmp_(key_compare::max_value(), BotSplitter.first) ||
346  cmp_(BotSplitter.first, key_compare::max_value())))
347  return result;
348  // no overflow/splitting happened
349 
350  STXXL_VERBOSE1("btree::normal_node Inserting new value in *this");
351 
352  splitter = insert(BotSplitter, it);
353 
354  return result;
355  }
356  else
357  { // found_bid points to a node
358  STXXL_VERBOSE1("btree::normal_node Inserting new value into a node");
359  node_type * Node = btree_->node_cache_.get_node((node_bid_type)it->second, true);
360  assert(Node);
361  std::pair<key_type, node_bid_type> BotSplitter;
362  std::pair<iterator, bool> result = Node->insert(x, height - 1, BotSplitter);
363  btree_->node_cache_.unfix_node((node_bid_type)it->second);
364  //if(key_compare::max_value() == BotSplitter.first)
365  if (!(cmp_(key_compare::max_value(), BotSplitter.first) ||
366  cmp_(BotSplitter.first, key_compare::max_value())))
367  return result;
368  // no overflow/splitting happened
369 
370  STXXL_VERBOSE1("btree::normal_node Inserting new value in *this");
371 
372  splitter = insert(BotSplitter, it);
373 
374  return result;
375  }
376  }
377 
378  iterator begin(unsigned height)
379  {
380  bid_type FirstBid = block_->begin()->second;
381  if (height == 2) // FirstBid points to a leaf
382  {
383  assert(size() > 1);
384  STXXL_VERBOSE1("btree::node retrieveing begin() from the first leaf");
385  leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)FirstBid);
386  assert(Leaf);
387  return Leaf->begin();
388  }
389  else
390  { // FirstBid points to a node
391  STXXL_VERBOSE1("btree: retrieveing begin() from the first node");
392  node_type * Node = btree_->node_cache_.get_node((node_bid_type)FirstBid, true);
393  assert(Node);
394  iterator result = Node->begin(height - 1);
395  btree_->node_cache_.unfix_node((node_bid_type)FirstBid);
396  return result;
397  }
398  }
399 
400  const_iterator begin(unsigned height) const
401  {
402  bid_type FirstBid = block_->begin()->second;
403  if (height == 2) // FirstBid points to a leaf
404  {
405  assert(size() > 1);
406  STXXL_VERBOSE1("btree::node retrieveing begin() from the first leaf");
407  leaf_type const * Leaf = btree_->leaf_cache_.get_const_node((leaf_bid_type)FirstBid);
408  assert(Leaf);
409  return Leaf->begin();
410  }
411  else
412  { // FirstBid points to a node
413  STXXL_VERBOSE1("btree: retrieveing begin() from the first node");
414  node_type const * Node = btree_->node_cache_.get_const_node((node_bid_type)FirstBid, true);
415  assert(Node);
416  const_iterator result = Node->begin(height - 1);
417  btree_->node_cache_.unfix_node((node_bid_type)FirstBid);
418  return result;
419  }
420  }
421 
422  iterator find(const key_type & k, unsigned height)
423  {
424  value_type Key2Search(k, bid_type());
425 
426  block_iterator it =
427  std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
428 
429  assert(it != (block_->begin() + size()));
430 
431  bid_type found_bid = it->second;
432 
433  if (height == 2) // found_bid points to a leaf
434  {
435  STXXL_VERBOSE1("Searching in a leaf");
436  leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)found_bid, true);
437  assert(Leaf);
438  iterator result = Leaf->find(k);
439  btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid);
440 
441  return result;
442  }
443 
444  // found_bid points to a node
445  STXXL_VERBOSE1("Searching in a node");
446  node_type * Node = btree_->node_cache_.get_node((node_bid_type)found_bid, true);
447  assert(Node);
448  iterator result = Node->find(k, height - 1);
449  btree_->node_cache_.unfix_node((node_bid_type)found_bid);
450 
451  return result;
452  }
453 
454  const_iterator find(const key_type & k, unsigned height) const
455  {
456  value_type Key2Search(k, bid_type());
457 
458  block_iterator it =
459  std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
460 
461  assert(it != (block_->begin() + size()));
462 
463  bid_type found_bid = it->second;
464 
465  if (height == 2) // found_bid points to a leaf
466  {
467  STXXL_VERBOSE1("Searching in a leaf");
468  leaf_type const * Leaf = btree_->leaf_cache_.get_const_node((leaf_bid_type)found_bid, true);
469  assert(Leaf);
470  const_iterator result = Leaf->find(k);
471  btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid);
472 
473  return result;
474  }
475 
476  // found_bid points to a node
477  STXXL_VERBOSE1("Searching in a node");
478  node_type const * Node = btree_->node_cache_.get_const_node((node_bid_type)found_bid, true);
479  assert(Node);
480  const_iterator result = Node->find(k, height - 1);
481  btree_->node_cache_.unfix_node((node_bid_type)found_bid);
482 
483  return result;
484  }
485 
486  iterator lower_bound(const key_type & k, unsigned height)
487  {
488  value_type Key2Search(k, bid_type());
489  assert(!vcmp_(back(), Key2Search));
490  block_iterator it =
491  std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
492 
493  assert(it != (block_->begin() + size()));
494 
495  bid_type found_bid = it->second;
496 
497  if (height == 2) // found_bid points to a leaf
498  {
499  STXXL_VERBOSE1("Searching lower bound in a leaf");
500  leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)found_bid, true);
501  assert(Leaf);
502  iterator result = Leaf->lower_bound(k);
503  btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid);
504 
505  return result;
506  }
507 
508  // found_bid points to a node
509  STXXL_VERBOSE1("Searching lower bound in a node");
510  node_type * Node = btree_->node_cache_.get_node((node_bid_type)found_bid, true);
511  assert(Node);
512  iterator result = Node->lower_bound(k, height - 1);
513  btree_->node_cache_.unfix_node((node_bid_type)found_bid);
514 
515  return result;
516  }
517 
518  const_iterator lower_bound(const key_type & k, unsigned height) const
519  {
520  value_type Key2Search(k, bid_type());
521  assert(!vcmp_(back(), Key2Search));
522  block_iterator it =
523  std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
524 
525  assert(it != (block_->begin() + size()));
526 
527  bid_type found_bid = it->second;
528 
529  if (height == 2) // found_bid points to a leaf
530  {
531  STXXL_VERBOSE1("Searching lower bound in a leaf");
532  leaf_type const * Leaf = btree_->leaf_cache_.get_const_node((leaf_bid_type)found_bid, true);
533  assert(Leaf);
534  const_iterator result = Leaf->lower_bound(k);
535  btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid);
536 
537  return result;
538  }
539 
540  // found_bid points to a node
541  STXXL_VERBOSE1("Searching lower bound in a node");
542  node_type const * Node = btree_->node_cache_.get_const_node((node_bid_type)found_bid, true);
543  assert(Node);
544  const_iterator result = Node->lower_bound(k, height - 1);
545  btree_->node_cache_.unfix_node((node_bid_type)found_bid);
546 
547  return result;
548  }
549 
550  iterator upper_bound(const key_type & k, unsigned height)
551  {
552  value_type Key2Search(k, bid_type());
553  assert(vcmp_(Key2Search, back()));
554  block_iterator it =
555  std::upper_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
556 
557  assert(it != (block_->begin() + size()));
558 
559  bid_type found_bid = it->second;
560 
561  if (height == 2) // found_bid points to a leaf
562  {
563  STXXL_VERBOSE1("Searching upper bound in a leaf");
564  leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)found_bid, true);
565  assert(Leaf);
566  iterator result = Leaf->upper_bound(k);
567  btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid);
568 
569  return result;
570  }
571 
572  // found_bid points to a node
573  STXXL_VERBOSE1("Searching upper bound in a node");
574  node_type * Node = btree_->node_cache_.get_node((node_bid_type)found_bid, true);
575  assert(Node);
576  iterator result = Node->upper_bound(k, height - 1);
577  btree_->node_cache_.unfix_node((node_bid_type)found_bid);
578 
579  return result;
580  }
581 
582  const_iterator upper_bound(const key_type & k, unsigned height) const
583  {
584  value_type Key2Search(k, bid_type());
585  assert(vcmp_(Key2Search, back()));
586  block_iterator it =
587  std::upper_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
588 
589  assert(it != (block_->begin() + size()));
590 
591  bid_type found_bid = it->second;
592 
593  if (height == 2) // found_bid points to a leaf
594  {
595  STXXL_VERBOSE1("Searching upper bound in a leaf");
596  leaf_type const * Leaf = btree_->leaf_cache_.get_const_node((leaf_bid_type)found_bid, true);
597  assert(Leaf);
598  const_iterator result = Leaf->upper_bound(k);
599  btree_->leaf_cache_.unfix_node((leaf_bid_type)found_bid);
600 
601  return result;
602  }
603 
604  // found_bid points to a node
605  STXXL_VERBOSE1("Searching upper bound in a node");
606  node_type const * Node = btree_->node_cache_.get_const_node((node_bid_type)found_bid, true);
607  assert(Node);
608  const_iterator result = Node->upper_bound(k, height - 1);
609  btree_->node_cache_.unfix_node((node_bid_type)found_bid);
610 
611  return result;
612  }
613 
614  void fuse(const normal_node & Src)
615  {
616  assert(vcmp_(Src.back(), front()));
617  const unsigned SrcSize = Src.size();
618 
619  block_iterator cur = block_->begin() + size() - 1;
620  block_const_iterator begin = block_->begin();
621 
622  for ( ; cur >= begin; --cur)
623  *(cur + SrcSize) = *cur;
624  // move elements to make space for Src elements
625 
626  // copy Src to *this leaf
627  std::copy(Src.block_->begin(), Src.block_->begin() + SrcSize, block_->begin());
628 
629  block_->info.cur_size += SrcSize;
630  }
631 
632 
633  key_type balance(normal_node & Left)
634  {
635  const unsigned TotalSize = Left.size() + size();
636  unsigned newLeftSize = TotalSize / 2;
637  assert(newLeftSize <= Left.max_nelements());
638  assert(newLeftSize >= Left.min_nelements());
639  unsigned newRightSize = TotalSize - newLeftSize;
640  assert(newRightSize <= max_nelements());
641  assert(newRightSize >= min_nelements());
642 
643  assert(vcmp_(Left.back(), front()) || size() == 0);
644 
645  if (newLeftSize < Left.size())
646  {
647  const unsigned nEl2Move = Left.size() - newLeftSize; // #elements to move from Left to *this
648 
649  block_iterator cur = block_->begin() + size() - 1;
650  block_const_iterator begin = block_->begin();
651 
652  for ( ; cur >= begin; --cur)
653  *(cur + nEl2Move) = *cur;
654  // move elements to make space for Src elements
655 
656  // copy Left to *this leaf
657  std::copy(Left.block_->begin() + newLeftSize,
658  Left.block_->begin() + Left.size(), block_->begin());
659  }
660  else
661  {
662  assert(newRightSize < size());
663 
664  const unsigned nEl2Move = size() - newRightSize; // #elements to move from *this to Left
665 
666  // copy *this to Left
667  std::copy(block_->begin(),
668  block_->begin() + nEl2Move, Left.block_->begin() + Left.size());
669  // move elements in *this
670  std::copy(block_->begin() + nEl2Move,
671  block_->begin() + size(), block_->begin());
672  }
673 
674  block_->info.cur_size = newRightSize; // update size
675  Left.block_->info.cur_size = newLeftSize; // update size
676 
677  return Left.back().first;
678  }
679 
680  size_type erase(const key_type & k, unsigned height)
681  {
682  value_type Key2Search(k, bid_type());
683 
684  block_iterator it =
685  std::lower_bound(block_->begin(), block_->begin() + size(), Key2Search, vcmp_);
686 
687  assert(it != (block_->begin() + size()));
688 
689  bid_type found_bid = it->second;
690 
691  assert(size() >= 2);
692 
693  if (height == 2) // 'found_bid' points to a leaf
694  {
695  STXXL_VERBOSE1("btree::normal_node Deleting key from a leaf");
696  leaf_type * Leaf = btree_->leaf_cache_.get_node((leaf_bid_type)found_bid, true);
697  assert(Leaf);
698  size_type result = Leaf->erase(k);
699  btree_->leaf_cache_.unfix_node((leaf_bid_type)it->second);
700  if (!Leaf->underflows())
701  return result;
702  // no underflow or root has a special degree 1 (too few elements)
703 
704  STXXL_VERBOSE1("btree::normal_node Fusing or rebalancing a leaf");
705  fuse_or_balance(it, btree_->leaf_cache_);
706 
707  return result;
708  }
709 
710  // 'found_bid' points to a node
711  STXXL_VERBOSE1("btree::normal_node Deleting key from a node");
712  node_type * Node = btree_->node_cache_.get_node((node_bid_type)found_bid, true);
713  assert(Node);
714  size_type result = Node->erase(k, height - 1);
715  btree_->node_cache_.unfix_node((node_bid_type)found_bid);
716  if (!Node->underflows())
717  return result;
718  // no underflow happened
719 
720  STXXL_VERBOSE1("btree::normal_node Fusing or rebalancing a node");
721  fuse_or_balance(it, btree_->node_cache_);
722 
723  return result;
724  }
725 
726  void deallocate_children(unsigned height)
727  {
728  if (height == 2)
729  {
730  // we have children leaves here
731  block_const_iterator it = block().begin();
732  for ( ; it != block().begin() + size(); ++it)
733  {
734  // delete from leaf cache and deallocate bid
735  btree_->leaf_cache_.delete_node((leaf_bid_type)it->second);
736  }
737  }
738  else
739  {
740  block_const_iterator it = block().begin();
741  for ( ; it != block().begin() + size(); ++it)
742  {
743  node_type * Node = btree_->node_cache_.get_node((node_bid_type)it->second);
744  assert(Node);
745  Node->deallocate_children(height - 1);
746  // delete from node cache and deallocate bid
747  btree_->node_cache_.delete_node((node_bid_type)it->second);
748  }
749  }
750  }
751 
752  void push_back(const value_type & x)
753  {
754  (*this)[size()] = x;
755  ++(block_->info.cur_size);
756  }
757  };
758 }
759 
760 
761 __STXXL_END_NAMESPACE
762 
763 
764 #endif /* STXXL_CONTAINERS_BTREE__NODE_H */
Block containing elements of fixed length.
Definition: typed_block.h:223
number of elements in block
Definition: typed_block.h:240
Implemented as reference counting smart pointer.
Definition: request_ptr.h:34
_ExtIterator find(_ExtIterator _begin, _ExtIterator _end, const _EqualityComparable &_value, int_type nbuffers)
External equivalent of std::find.
Definition: scan.h:215
virtual void wait(bool measure_time=true)=0
Suspends calling thread until completion of the request.