STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
losertree.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2007-2013 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
9 // version.
10 
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
30 // Written by Johannes Singler.
31 
32 #ifndef _GLIBCXX_PARALLEL_LOSERTREE_H
33 #define _GLIBCXX_PARALLEL_LOSERTREE_H 1
34 
35 #include <bits/stl_algobase.h>
36 #include <bits/stl_function.h>
37 #include <parallel/features.h>
38 #include <parallel/base.h>
39 
40 namespace __gnu_parallel
41 {
54  template<typename _Tp, typename _Compare>
56  {
57  protected:
59  struct _Loser
60  {
62  bool _M_sup;
64  int _M_source;
66  _Tp _M_key;
67  };
68 
69  unsigned int _M_ik, _M_k, _M_offset;
70 
72  unsigned int _M_log_k;
73 
76 
78  _Compare _M_comp;
79 
86 
87  public:
94  _LoserTreeBase(unsigned int __k, _Compare __comp)
95  : _M_comp(__comp)
96  {
97  _M_ik = __k;
98 
99  // Compute log_2{_M_k} for the _Loser Tree
100  _M_log_k = __rd_log2(_M_ik - 1) + 1;
101 
102  // Next greater power of 2.
103  _M_k = 1 << _M_log_k;
104  _M_offset = _M_k;
105 
106  // Avoid default-constructing _M_losers[]._M_key
107  _M_losers = static_cast<_Loser*>(::operator new(2 * _M_k
108  * sizeof(_Loser)));
109  for (unsigned int __i = _M_ik - 1; __i < _M_k; ++__i)
110  _M_losers[__i + _M_k]._M_sup = true;
111 
112  _M_first_insert = true;
113  }
114 
119  {
120  for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
121  _M_losers[__i].~_Loser();
122  ::operator delete(_M_losers);
123  }
124 
133  void
134  __insert_start(const _Tp& __key, int __source, bool __sup)
135  {
136  unsigned int __pos = _M_k + __source;
137 
138  if (_M_first_insert)
139  {
140  // Construct all keys, so we can easily destruct them.
141  for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
142  ::new(&(_M_losers[__i]._M_key)) _Tp(__key);
143  _M_first_insert = false;
144  }
145  else
146  _M_losers[__pos]._M_key = __key;
147 
148  _M_losers[__pos]._M_sup = __sup;
149  _M_losers[__pos]._M_source = __source;
150  }
151 
156  { return _M_losers[0]._M_source; }
157  };
158 
167  template<bool __stable/* default == true */, typename _Tp,
168  typename _Compare>
170  : public _LoserTreeBase<_Tp, _Compare>
171  {
173  using _Base::_M_k;
174  using _Base::_M_comp;
175  using _Base::_M_losers;
177 
178  public:
179  _LoserTree(unsigned int __k, _Compare __comp)
180  : _Base::_LoserTreeBase(__k, __comp)
181  { }
182 
183  unsigned int
184  __init_winner(unsigned int __root)
185  {
186  if (__root >= _M_k)
187  return __root;
188  else
189  {
190  unsigned int __left = __init_winner(2 * __root);
191  unsigned int __right = __init_winner(2 * __root + 1);
192  if (_M_losers[__right]._M_sup
193  || (!_M_losers[__left]._M_sup
194  && !_M_comp(_M_losers[__right]._M_key,
195  _M_losers[__left]._M_key)))
196  {
197  // Left one is less or equal.
198  _M_losers[__root] = _M_losers[__right];
199  return __left;
200  }
201  else
202  {
203  // Right one is less.
204  _M_losers[__root] = _M_losers[__left];
205  return __right;
206  }
207  }
208  }
209 
210  void __init()
211  { _M_losers[0] = _M_losers[__init_winner(1)]; }
212 
219  // Do not pass a const reference since __key will be used as
220  // local variable.
221  void
222  __delete_min_insert(_Tp __key, bool __sup)
223  {
224  using std::swap;
225 #if _GLIBCXX_ASSERTIONS
226  // no dummy sequence can ever be at the top!
227  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
228 #endif
229 
230  int __source = _M_losers[0]._M_source;
231  for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
232  __pos /= 2)
233  {
234  // The smaller one gets promoted, ties are broken by _M_source.
235  if ((__sup && (!_M_losers[__pos]._M_sup
236  || _M_losers[__pos]._M_source < __source))
237  || (!__sup && !_M_losers[__pos]._M_sup
238  && ((_M_comp(_M_losers[__pos]._M_key, __key))
239  || (!_M_comp(__key, _M_losers[__pos]._M_key)
240  && _M_losers[__pos]._M_source < __source))))
241  {
242  // The other one is smaller.
243  std::swap(_M_losers[__pos]._M_sup, __sup);
244  std::swap(_M_losers[__pos]._M_source, __source);
245  swap(_M_losers[__pos]._M_key, __key);
246  }
247  }
248 
249  _M_losers[0]._M_sup = __sup;
250  _M_losers[0]._M_source = __source;
251  _M_losers[0]._M_key = __key;
252  }
253  };
254 
260  template<typename _Tp, typename _Compare>
261  class _LoserTree</* __stable == */false, _Tp, _Compare>
262  : public _LoserTreeBase<_Tp, _Compare>
263  {
265  using _Base::_M_log_k;
266  using _Base::_M_k;
267  using _Base::_M_comp;
268  using _Base::_M_losers;
270 
271  public:
272  _LoserTree(unsigned int __k, _Compare __comp)
273  : _Base::_LoserTreeBase(__k, __comp)
274  { }
275 
283  unsigned int
284  __init_winner(unsigned int __root)
285  {
286  if (__root >= _M_k)
287  return __root;
288  else
289  {
290  unsigned int __left = __init_winner(2 * __root);
291  unsigned int __right = __init_winner(2 * __root + 1);
292  if (_M_losers[__right]._M_sup
293  || (!_M_losers[__left]._M_sup
294  && !_M_comp(_M_losers[__right]._M_key,
295  _M_losers[__left]._M_key)))
296  {
297  // Left one is less or equal.
298  _M_losers[__root] = _M_losers[__right];
299  return __left;
300  }
301  else
302  {
303  // Right one is less.
304  _M_losers[__root] = _M_losers[__left];
305  return __right;
306  }
307  }
308  }
309 
310  void
312  { _M_losers[0] = _M_losers[__init_winner(1)]; }
313 
321  // Do not pass a const reference since __key will be used as local
322  // variable.
323  void
324  __delete_min_insert(_Tp __key, bool __sup)
325  {
326  using std::swap;
327 #if _GLIBCXX_ASSERTIONS
328  // no dummy sequence can ever be at the top!
329  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
330 #endif
331 
332  int __source = _M_losers[0]._M_source;
333  for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
334  __pos /= 2)
335  {
336  // The smaller one gets promoted.
337  if (__sup || (!_M_losers[__pos]._M_sup
338  && _M_comp(_M_losers[__pos]._M_key, __key)))
339  {
340  // The other one is smaller.
341  std::swap(_M_losers[__pos]._M_sup, __sup);
342  std::swap(_M_losers[__pos]._M_source, __source);
343  swap(_M_losers[__pos]._M_key, __key);
344  }
345  }
346 
347  _M_losers[0]._M_sup = __sup;
348  _M_losers[0]._M_source = __source;
349  _M_losers[0]._M_key = __key;
350  }
351  };
352 
356  template<typename _Tp, typename _Compare>
358  {
359  protected:
361  struct _Loser
362  {
363  bool _M_sup;
365  const _Tp* _M_keyp;
366  };
367 
368  unsigned int _M_ik, _M_k, _M_offset;
370  _Compare _M_comp;
371 
372  public:
373  _LoserTreePointerBase(unsigned int __k,
374  _Compare __comp = std::less<_Tp>())
375  : _M_comp(__comp)
376  {
377  _M_ik = __k;
378 
379  // Next greater power of 2.
380  _M_k = 1 << (__rd_log2(_M_ik - 1) + 1);
381  _M_offset = _M_k;
382  _M_losers = new _Loser[_M_k * 2];
383  for (unsigned int __i = _M_ik - 1; __i < _M_k; __i++)
384  _M_losers[__i + _M_k]._M_sup = true;
385  }
386 
388  { delete[] _M_losers; }
389 
391  { return _M_losers[0]._M_source; }
392 
393  void __insert_start(const _Tp& __key, int __source, bool __sup)
394  {
395  unsigned int __pos = _M_k + __source;
396 
397  _M_losers[__pos]._M_sup = __sup;
398  _M_losers[__pos]._M_source = __source;
399  _M_losers[__pos]._M_keyp = &__key;
400  }
401  };
402 
408  template<bool __stable/* default == true */, typename _Tp, typename _Compare>
410  : public _LoserTreePointerBase<_Tp, _Compare>
411  {
413  using _Base::_M_k;
414  using _Base::_M_comp;
415  using _Base::_M_losers;
416 
417  public:
418  _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>())
419  : _Base::_LoserTreePointerBase(__k, __comp)
420  { }
421 
422  unsigned int
423  __init_winner(unsigned int __root)
424  {
425  if (__root >= _M_k)
426  return __root;
427  else
428  {
429  unsigned int __left = __init_winner(2 * __root);
430  unsigned int __right = __init_winner(2 * __root + 1);
431  if (_M_losers[__right]._M_sup
432  || (!_M_losers[__left]._M_sup
433  && !_M_comp(*_M_losers[__right]._M_keyp,
434  *_M_losers[__left]._M_keyp)))
435  {
436  // Left one is less or equal.
437  _M_losers[__root] = _M_losers[__right];
438  return __left;
439  }
440  else
441  {
442  // Right one is less.
443  _M_losers[__root] = _M_losers[__left];
444  return __right;
445  }
446  }
447  }
448 
449  void __init()
450  { _M_losers[0] = _M_losers[__init_winner(1)]; }
451 
452  void __delete_min_insert(const _Tp& __key, bool __sup)
453  {
454 #if _GLIBCXX_ASSERTIONS
455  // no dummy sequence can ever be at the top!
456  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
457 #endif
458 
459  const _Tp* __keyp = &__key;
460  int __source = _M_losers[0]._M_source;
461  for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
462  __pos /= 2)
463  {
464  // The smaller one gets promoted, ties are broken by __source.
465  if ((__sup && (!_M_losers[__pos]._M_sup
466  || _M_losers[__pos]._M_source < __source))
467  || (!__sup && !_M_losers[__pos]._M_sup &&
468  ((_M_comp(*_M_losers[__pos]._M_keyp, *__keyp))
469  || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp)
470  && _M_losers[__pos]._M_source < __source))))
471  {
472  // The other one is smaller.
473  std::swap(_M_losers[__pos]._M_sup, __sup);
474  std::swap(_M_losers[__pos]._M_source, __source);
475  std::swap(_M_losers[__pos]._M_keyp, __keyp);
476  }
477  }
478 
479  _M_losers[0]._M_sup = __sup;
480  _M_losers[0]._M_source = __source;
481  _M_losers[0]._M_keyp = __keyp;
482  }
483  };
484 
490  template<typename _Tp, typename _Compare>
491  class _LoserTreePointer</* __stable == */false, _Tp, _Compare>
492  : public _LoserTreePointerBase<_Tp, _Compare>
493  {
495  using _Base::_M_k;
496  using _Base::_M_comp;
497  using _Base::_M_losers;
498 
499  public:
500  _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>())
501  : _Base::_LoserTreePointerBase(__k, __comp)
502  { }
503 
504  unsigned int
505  __init_winner(unsigned int __root)
506  {
507  if (__root >= _M_k)
508  return __root;
509  else
510  {
511  unsigned int __left = __init_winner(2 * __root);
512  unsigned int __right = __init_winner(2 * __root + 1);
513  if (_M_losers[__right]._M_sup
514  || (!_M_losers[__left]._M_sup
515  && !_M_comp(*_M_losers[__right]._M_keyp,
516  *_M_losers[__left]._M_keyp)))
517  {
518  // Left one is less or equal.
519  _M_losers[__root] = _M_losers[__right];
520  return __left;
521  }
522  else
523  {
524  // Right one is less.
525  _M_losers[__root] = _M_losers[__left];
526  return __right;
527  }
528  }
529  }
530 
531  void __init()
532  { _M_losers[0] = _M_losers[__init_winner(1)]; }
533 
534  void __delete_min_insert(const _Tp& __key, bool __sup)
535  {
536 #if _GLIBCXX_ASSERTIONS
537  // no dummy sequence can ever be at the top!
538  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
539 #endif
540 
541  const _Tp* __keyp = &__key;
542  int __source = _M_losers[0]._M_source;
543  for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
544  __pos /= 2)
545  {
546  // The smaller one gets promoted.
547  if (__sup || (!_M_losers[__pos]._M_sup
548  && _M_comp(*_M_losers[__pos]._M_keyp, *__keyp)))
549  {
550  // The other one is smaller.
551  std::swap(_M_losers[__pos]._M_sup, __sup);
552  std::swap(_M_losers[__pos]._M_source, __source);
553  std::swap(_M_losers[__pos]._M_keyp, __keyp);
554  }
555  }
556 
557  _M_losers[0]._M_sup = __sup;
558  _M_losers[0]._M_source = __source;
559  _M_losers[0]._M_keyp = __keyp;
560  }
561  };
562 
573  template<typename _Tp, typename _Compare>
575  {
576  protected:
577  struct _Loser
578  {
580  _Tp _M_key;
581  };
582 
583  unsigned int _M_ik, _M_k, _M_offset;
585  _Compare _M_comp;
586 
587  public:
588  _LoserTreeUnguardedBase(unsigned int __k, const _Tp& __sentinel,
589  _Compare __comp = std::less<_Tp>())
590  : _M_comp(__comp)
591  {
592  _M_ik = __k;
593 
594  // Next greater power of 2.
595  _M_k = 1 << (__rd_log2(_M_ik - 1) + 1);
596  _M_offset = _M_k;
597  // Avoid default-constructing _M_losers[]._M_key
598  _M_losers = static_cast<_Loser*>(::operator new(2 * _M_k
599  * sizeof(_Loser)));
600 
601  for (unsigned int __i = 0; __i < _M_k; ++__i)
602  {
603  ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel);
604  _M_losers[__i]._M_source = -1;
605  }
606  for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
607  {
608  ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel);
609  _M_losers[__i]._M_source = -1;
610  }
611  }
612 
614  {
615  for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
616  _M_losers[__i].~_Loser();
617  ::operator delete(_M_losers);
618  }
619 
620  int
622  {
623 #if _GLIBCXX_ASSERTIONS
624  // no dummy sequence can ever be at the top!
625  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
626 #endif
627  return _M_losers[0]._M_source;
628  }
629 
630  void
631  __insert_start(const _Tp& __key, int __source, bool)
632  {
633  unsigned int __pos = _M_k + __source;
634 
635  ::new(&(_M_losers[__pos]._M_key)) _Tp(__key);
636  _M_losers[__pos]._M_source = __source;
637  }
638  };
639 
645  template<bool __stable/* default == true */, typename _Tp, typename _Compare>
647  : public _LoserTreeUnguardedBase<_Tp, _Compare>
648  {
650  using _Base::_M_k;
651  using _Base::_M_comp;
652  using _Base::_M_losers;
653 
654  public:
655  _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel,
656  _Compare __comp = std::less<_Tp>())
657  : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp)
658  { }
659 
660  unsigned int
661  __init_winner(unsigned int __root)
662  {
663  if (__root >= _M_k)
664  return __root;
665  else
666  {
667  unsigned int __left = __init_winner(2 * __root);
668  unsigned int __right = __init_winner(2 * __root + 1);
669  if (!_M_comp(_M_losers[__right]._M_key,
670  _M_losers[__left]._M_key))
671  {
672  // Left one is less or equal.
673  _M_losers[__root] = _M_losers[__right];
674  return __left;
675  }
676  else
677  {
678  // Right one is less.
679  _M_losers[__root] = _M_losers[__left];
680  return __right;
681  }
682  }
683  }
684 
685  void
687  {
689 
690 #if _GLIBCXX_ASSERTIONS
691  // no dummy sequence can ever be at the top at the beginning
692  // (0 sequences!)
693  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
694 #endif
695  }
696 
697  // Do not pass a const reference since __key will be used as
698  // local variable.
699  void
700  __delete_min_insert(_Tp __key, bool)
701  {
702  using std::swap;
703 #if _GLIBCXX_ASSERTIONS
704  // no dummy sequence can ever be at the top!
705  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
706 #endif
707 
708  int __source = _M_losers[0]._M_source;
709  for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
710  __pos /= 2)
711  {
712  // The smaller one gets promoted, ties are broken by _M_source.
713  if (_M_comp(_M_losers[__pos]._M_key, __key)
714  || (!_M_comp(__key, _M_losers[__pos]._M_key)
715  && _M_losers[__pos]._M_source < __source))
716  {
717  // The other one is smaller.
718  std::swap(_M_losers[__pos]._M_source, __source);
719  swap(_M_losers[__pos]._M_key, __key);
720  }
721  }
722 
723  _M_losers[0]._M_source = __source;
724  _M_losers[0]._M_key = __key;
725  }
726  };
727 
733  template<typename _Tp, typename _Compare>
734  class _LoserTreeUnguarded</* __stable == */false, _Tp, _Compare>
735  : public _LoserTreeUnguardedBase<_Tp, _Compare>
736  {
738  using _Base::_M_k;
739  using _Base::_M_comp;
740  using _Base::_M_losers;
741 
742  public:
743  _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel,
744  _Compare __comp = std::less<_Tp>())
745  : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp)
746  { }
747 
748  unsigned int
749  __init_winner(unsigned int __root)
750  {
751  if (__root >= _M_k)
752  return __root;
753  else
754  {
755  unsigned int __left = __init_winner(2 * __root);
756  unsigned int __right = __init_winner(2 * __root + 1);
757 
758 #if _GLIBCXX_ASSERTIONS
759  // If __left one is sentinel then __right one must be, too.
760  if (_M_losers[__left]._M_source == -1)
761  _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1);
762 #endif
763 
764  if (!_M_comp(_M_losers[__right]._M_key,
765  _M_losers[__left]._M_key))
766  {
767  // Left one is less or equal.
768  _M_losers[__root] = _M_losers[__right];
769  return __left;
770  }
771  else
772  {
773  // Right one is less.
774  _M_losers[__root] = _M_losers[__left];
775  return __right;
776  }
777  }
778  }
779 
780  void
782  {
784 
785 #if _GLIBCXX_ASSERTIONS
786  // no dummy sequence can ever be at the top at the beginning
787  // (0 sequences!)
788  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
789 #endif
790  }
791 
792  // Do not pass a const reference since __key will be used as
793  // local variable.
794  void
795  __delete_min_insert(_Tp __key, bool)
796  {
797  using std::swap;
798 #if _GLIBCXX_ASSERTIONS
799  // no dummy sequence can ever be at the top!
800  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
801 #endif
802 
803  int __source = _M_losers[0]._M_source;
804  for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
805  __pos /= 2)
806  {
807  // The smaller one gets promoted.
808  if (_M_comp(_M_losers[__pos]._M_key, __key))
809  {
810  // The other one is smaller.
811  std::swap(_M_losers[__pos]._M_source, __source);
812  swap(_M_losers[__pos]._M_key, __key);
813  }
814  }
815 
816  _M_losers[0]._M_source = __source;
817  _M_losers[0]._M_key = __key;
818  }
819  };
820 
827  template<typename _Tp, typename _Compare>
829  {
830  protected:
831  struct _Loser
832  {
834  const _Tp* _M_keyp;
835  };
836 
837  unsigned int _M_ik, _M_k, _M_offset;
839  _Compare _M_comp;
840 
841  public:
842 
843  _LoserTreePointerUnguardedBase(unsigned int __k, const _Tp& __sentinel,
844  _Compare __comp = std::less<_Tp>())
845  : _M_comp(__comp)
846  {
847  _M_ik = __k;
848 
849  // Next greater power of 2.
850  _M_k = 1 << (__rd_log2(_M_ik - 1) + 1);
851  _M_offset = _M_k;
852  // Avoid default-constructing _M_losers[]._M_key
853  _M_losers = new _Loser[2 * _M_k];
854 
855  for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
856  {
857  _M_losers[__i]._M_keyp = &__sentinel;
858  _M_losers[__i]._M_source = -1;
859  }
860  }
861 
863  { delete[] _M_losers; }
864 
865  int
867  {
868 #if _GLIBCXX_ASSERTIONS
869  // no dummy sequence can ever be at the top!
870  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
871 #endif
872  return _M_losers[0]._M_source;
873  }
874 
875  void
876  __insert_start(const _Tp& __key, int __source, bool)
877  {
878  unsigned int __pos = _M_k + __source;
879 
880  _M_losers[__pos]._M_keyp = &__key;
881  _M_losers[__pos]._M_source = __source;
882  }
883  };
884 
890  template<bool __stable/* default == true */, typename _Tp, typename _Compare>
892  : public _LoserTreePointerUnguardedBase<_Tp, _Compare>
893  {
895  using _Base::_M_k;
896  using _Base::_M_comp;
897  using _Base::_M_losers;
898 
899  public:
900  _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel,
901  _Compare __comp = std::less<_Tp>())
902  : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp)
903  { }
904 
905  unsigned int
906  __init_winner(unsigned int __root)
907  {
908  if (__root >= _M_k)
909  return __root;
910  else
911  {
912  unsigned int __left = __init_winner(2 * __root);
913  unsigned int __right = __init_winner(2 * __root + 1);
914  if (!_M_comp(*_M_losers[__right]._M_keyp,
915  *_M_losers[__left]._M_keyp))
916  {
917  // Left one is less or equal.
918  _M_losers[__root] = _M_losers[__right];
919  return __left;
920  }
921  else
922  {
923  // Right one is less.
924  _M_losers[__root] = _M_losers[__left];
925  return __right;
926  }
927  }
928  }
929 
930  void
932  {
934 
935 #if _GLIBCXX_ASSERTIONS
936  // no dummy sequence can ever be at the top at the beginning
937  // (0 sequences!)
938  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
939 #endif
940  }
941 
942  void
943  __delete_min_insert(const _Tp& __key, bool __sup)
944  {
945 #if _GLIBCXX_ASSERTIONS
946  // no dummy sequence can ever be at the top!
947  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
948 #endif
949 
950  const _Tp* __keyp = &__key;
951  int __source = _M_losers[0]._M_source;
952  for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
953  __pos /= 2)
954  {
955  // The smaller one gets promoted, ties are broken by _M_source.
956  if (_M_comp(*_M_losers[__pos]._M_keyp, *__keyp)
957  || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp)
958  && _M_losers[__pos]._M_source < __source))
959  {
960  // The other one is smaller.
961  std::swap(_M_losers[__pos]._M_source, __source);
962  std::swap(_M_losers[__pos]._M_keyp, __keyp);
963  }
964  }
965 
966  _M_losers[0]._M_source = __source;
967  _M_losers[0]._M_keyp = __keyp;
968  }
969  };
970 
976  template<typename _Tp, typename _Compare>
977  class _LoserTreePointerUnguarded</* __stable == */false, _Tp, _Compare>
978  : public _LoserTreePointerUnguardedBase<_Tp, _Compare>
979  {
981  using _Base::_M_k;
982  using _Base::_M_comp;
983  using _Base::_M_losers;
984 
985  public:
986  _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel,
987  _Compare __comp = std::less<_Tp>())
988  : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp)
989  { }
990 
991  unsigned int
992  __init_winner(unsigned int __root)
993  {
994  if (__root >= _M_k)
995  return __root;
996  else
997  {
998  unsigned int __left = __init_winner(2 * __root);
999  unsigned int __right = __init_winner(2 * __root + 1);
1000 
1001 #if _GLIBCXX_ASSERTIONS
1002  // If __left one is sentinel then __right one must be, too.
1003  if (_M_losers[__left]._M_source == -1)
1004  _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1);
1005 #endif
1006 
1007  if (!_M_comp(*_M_losers[__right]._M_keyp,
1008  *_M_losers[__left]._M_keyp))
1009  {
1010  // Left one is less or equal.
1011  _M_losers[__root] = _M_losers[__right];
1012  return __left;
1013  }
1014  else
1015  {
1016  // Right one is less.
1017  _M_losers[__root] = _M_losers[__left];
1018  return __right;
1019  }
1020  }
1021  }
1022 
1023  void
1025  {
1027 
1028 #if _GLIBCXX_ASSERTIONS
1029  // no dummy sequence can ever be at the top at the beginning
1030  // (0 sequences!)
1031  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
1032 #endif
1033  }
1034 
1035  void
1036  __delete_min_insert(const _Tp& __key, bool __sup)
1037  {
1038 #if _GLIBCXX_ASSERTIONS
1039  // no dummy sequence can ever be at the top!
1040  _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
1041 #endif
1042 
1043  const _Tp* __keyp = &__key;
1044  int __source = _M_losers[0]._M_source;
1045  for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
1046  __pos /= 2)
1047  {
1048  // The smaller one gets promoted.
1049  if (_M_comp(*(_M_losers[__pos]._M_keyp), *__keyp))
1050  {
1051  // The other one is smaller.
1052  std::swap(_M_losers[__pos]._M_source, __source);
1053  std::swap(_M_losers[__pos]._M_keyp, __keyp);
1054  }
1055  }
1056 
1057  _M_losers[0]._M_source = __source;
1058  _M_losers[0]._M_keyp = __keyp;
1059  }
1060  };
1061 } // namespace __gnu_parallel
1062 
1063 #endif /* _GLIBCXX_PARALLEL_LOSERTREE_H */
bool _M_sup
flag, true iff this is a "maximum" __sentinel.
Definition: losertree.h:62
_Compare _M_comp
Definition: losertree.h:370
Internal representation of a _LoserTree element.
Definition: losertree.h:59
Unguarded loser tree, keeping only pointers to the elements in the tree structure.
Definition: losertree.h:828
unsigned int __init_winner(unsigned int __root)
Definition: losertree.h:505
_Loser * _M_losers
_LoserTree __elements.
Definition: losertree.h:75
Stable _LoserTree variant.
Definition: losertree.h:169
void __init()
Definition: losertree.h:210
_LoserTreeBase(unsigned int __k, _Compare __comp)
The constructor.
Definition: losertree.h:94
_LoserTreePointerUnguardedBase< _Tp, _Compare > _Base
Definition: losertree.h:980
void __delete_min_insert(_Tp __key, bool)
Definition: losertree.h:700
void __init()
Definition: losertree.h:931
int __get_min_source()
Definition: losertree.h:621
unsigned int _M_offset
Definition: losertree.h:368
unsigned int __init_winner(unsigned int __root)
Definition: losertree.h:992
_LoserTreeUnguardedBase(unsigned int __k, const _Tp &__sentinel, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:588
Base class of _Loser Tree implementation using pointers.
Definition: losertree.h:357
Sequential helper functions. This file is a GNU parallel extension to the Standard C++ Library...
void __delete_min_insert(_Tp __key, bool)
Definition: losertree.h:795
void __delete_min_insert(const _Tp &__key, bool __sup)
Definition: losertree.h:1036
#define false
Definition: stdbool.h:35
void __insert_start(const _Tp &__key, int __source, bool __sup)
Definition: losertree.h:393
int __get_min_source()
Definition: losertree.h:390
unsigned int _M_ik
Definition: losertree.h:69
Stable unguarded _LoserTree variant storing pointers.
Definition: losertree.h:891
_Loser * _M_losers
Definition: losertree.h:838
_LoserTreePointer(unsigned int __k, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:500
const _Tp * _M_keyp
Definition: losertree.h:834
~_LoserTreePointerUnguardedBase()
Definition: losertree.h:862
void __insert_start(const _Tp &__key, int __source, bool)
Definition: losertree.h:631
void __init()
Definition: losertree.h:311
const _Tp * _M_keyp
Definition: losertree.h:365
~_LoserTreePointerBase()
Definition: losertree.h:387
unsigned int __init_winner(unsigned int __root)
Definition: losertree.h:184
unsigned int _M_k
Definition: losertree.h:583
_LoserTreeUnguardedBase< _Tp, _Compare > _Base
Definition: losertree.h:737
void __delete_min_insert(const _Tp &__key, bool __sup)
Definition: losertree.h:534
_Loser * _M_losers
Definition: losertree.h:584
_LoserTreePointerUnguarded(unsigned int __k, const _Tp &__sentinel, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:986
_LoserTreeUnguarded(unsigned int __k, const _Tp &__sentinel, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:655
unsigned int _M_offset
Definition: losertree.h:69
_LoserTreePointerBase(unsigned int __k, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:373
_LoserTree(unsigned int __k, _Compare __comp)
Definition: losertree.h:272
int __get_min_source()
Definition: losertree.h:866
~_LoserTreeUnguardedBase()
Definition: losertree.h:613
_LoserTreeUnguardedBase< _Tp, _Compare > _Base
Definition: losertree.h:649
_Compare _M_comp
Definition: losertree.h:839
void __insert_start(const _Tp &__key, int __source, bool __sup)
Initializes the sequence "_M_source" with the element "__key".
Definition: losertree.h:134
unsigned int _M_k
Definition: losertree.h:368
void __delete_min_insert(const _Tp &__key, bool __sup)
Definition: losertree.h:943
_LoserTreePointerUnguardedBase< _Tp, _Compare > _Base
Definition: losertree.h:894
int _M_source
__index of the __source __sequence.
Definition: losertree.h:64
~_LoserTreeBase()
The destructor.
Definition: losertree.h:118
unsigned int __init_winner(unsigned int __root)
Definition: losertree.h:661
unsigned int __init_winner(unsigned int __root)
Definition: losertree.h:906
int _M_source
Definition: losertree.h:364
_Size __rd_log2(_Size __n)
Calculates the rounded-down logarithm of __n for base 2.
Definition: base.h:102
_LoserTreeUnguarded(unsigned int __k, const _Tp &__sentinel, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:743
_LoserTreePointerUnguardedBase(unsigned int __k, const _Tp &__sentinel, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:843
void __insert_start(const _Tp &__key, int __source, bool)
Definition: losertree.h:876
unsigned int _M_offset
Definition: losertree.h:837
bool _M_first_insert
State flag that determines whether the _LoserTree is empty.
Definition: losertree.h:85
unsigned int _M_log_k
Definition: losertree.h:72
_LoserTreeBase< _Tp, _Compare > _Base
Definition: losertree.h:172
_Loser * _M_losers
Definition: losertree.h:369
_LoserTree(unsigned int __k, _Compare __comp)
Definition: losertree.h:179
Stable _LoserTree implementation.
Definition: losertree.h:409
unsigned int _M_ik
Definition: losertree.h:368
unsigned int __init_winner(unsigned int __root)
Definition: losertree.h:284
Stable implementation of unguarded _LoserTree.
Definition: losertree.h:646
Internal representation of _LoserTree __elements.
Definition: losertree.h:361
_LoserTreePointer(unsigned int __k, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:418
unsigned int _M_offset
Definition: losertree.h:583
_LoserTreeBase< _Tp, _Compare > _Base
Definition: losertree.h:264
unsigned int _M_ik
Definition: losertree.h:583
_LoserTreePointerBase< _Tp, _Compare > _Base
Definition: losertree.h:494
#define _GLIBCXX_PARALLEL_ASSERT(_Condition)
Definition: base.h:422
Base class for unguarded _LoserTree implementation.
Definition: losertree.h:574
void __delete_min_insert(_Tp __key, bool __sup)
Delete the smallest element and insert a new element from the previously smallest element's sequence...
Definition: losertree.h:222
void __init()
Definition: losertree.h:449
void __delete_min_insert(const _Tp &__key, bool __sup)
Definition: losertree.h:452
unsigned int _M_k
Definition: losertree.h:837
unsigned int __init_winner(unsigned int __root)
Definition: losertree.h:423
_Compare _M_comp
_Compare to use.
Definition: losertree.h:78
void __init()
Definition: losertree.h:686
bool _M_sup
Definition: losertree.h:363
unsigned int _M_k
Definition: losertree.h:69
unsigned int _M_ik
Definition: losertree.h:837
Defines on whether to include algorithm variants.
Guarded loser/tournament tree.
Definition: losertree.h:55
void __delete_min_insert(_Tp __key, bool __sup)
Definition: losertree.h:324
void swap(exception_ptr &__lhs, exception_ptr &__rhs)
Definition: exception_ptr.h:160
unsigned int __init_winner(unsigned int __root)
Definition: losertree.h:749
_Tp _M_key
_M_key of the element in the _LoserTree.
Definition: losertree.h:66
_LoserTreePointerBase< _Tp, _Compare > _Base
Definition: losertree.h:412
_Tp _M_key
Definition: losertree.h:580
int __get_min_source()
Definition: losertree.h:155
_LoserTreePointerUnguarded(unsigned int __k, const _Tp &__sentinel, _Compare __comp=std::less< _Tp >())
Definition: losertree.h:900
int _M_source
Definition: losertree.h:579
_Compare _M_comp
Definition: losertree.h:585