multiway_merge.h: Reformat to 80 columns; adjust some inline specifiers; other minor...
[gcc.git] / libstdc++-v3 / include / parallel / losertree.h
1 // -*- C++ -*-
2
3 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING. If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 // MA 02111-1307, USA.
20
21 // As a special exception, you may use this file as part of a free
22 // software library without restriction. Specifically, if other files
23 // instantiate templates or use macros or inline functions from this
24 // file, or you compile this file and link it with other files to
25 // produce an executable, this file does not by itself cause the
26 // resulting executable to be covered by the GNU General Public
27 // License. This exception does not however invalidate any other
28 // reasons why the executable file might be covered by the GNU General
29 // Public License.
30
31 /** @file parallel/losertree.h
32 * @brief Many generic loser tree variants.
33 * This file is a GNU parallel extension to the Standard C++ Library.
34 */
35
36 // Written by Johannes Singler.
37
38 #ifndef _GLIBCXX_PARALLEL_LOSERTREE_H
39 #define _GLIBCXX_PARALLEL_LOSERTREE_H 1
40
41 #include <functional>
42
43 #include <bits/stl_algobase.h>
44 #include <parallel/features.h>
45 #include <parallel/base.h>
46
47 namespace __gnu_parallel
48 {
49
50 #if _GLIBCXX_LOSER_TREE_EXPLICIT
51
52 /** @brief Guarded loser tree, copying the whole element into the
53 * tree structure.
54 *
55 * Guarding is done explicitly through two flags per element, inf
56 * and sup This is a quite slow variant.
57 */
58 template<typename T, typename Comparator = std::less<T> >
59 class LoserTreeExplicit
60 {
61 private:
62 struct Loser
63 {
64 // The relevant element.
65 T key;
66
67 // Is this an infimum or supremum element?
68 bool inf, sup;
69
70 // Number of the sequence the element comes from.
71 int source;
72 };
73
74 unsigned int size, offset;
75 Loser* losers;
76 Comparator comp;
77
78 public:
79 LoserTreeExplicit(unsigned int _size, Comparator _comp = std::less<T>())
80 : comp(_comp)
81 {
82 size = _size;
83 offset = size;
84 losers = new Loser[size];
85 for (unsigned int l = 0; l < size; ++l)
86 {
87 //losers[l].key = ... stays unset
88 losers[l].inf = true;
89 losers[l].sup = false;
90 //losers[l].source = -1; //sentinel
91 }
92 }
93
94 ~LoserTreeExplicit()
95 { delete[] losers; }
96
97 int
98 get_min_source()
99 { return losers[0].source; }
100
101 void
102 insert_start(T key, int source, bool sup)
103 {
104 bool inf = false;
105 for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
106 {
107 if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
108 && comp(losers[pos].key, key)) || losers[pos].inf || sup)
109 {
110 // The other one is smaller.
111 std::swap(losers[pos].key, key);
112 std::swap(losers[pos].inf, inf);
113 std::swap(losers[pos].sup, sup);
114 std::swap(losers[pos].source, source);
115 }
116 }
117
118 losers[0].key = key;
119 losers[0].inf = inf;
120 losers[0].sup = sup;
121 losers[0].source = source;
122 }
123
124 void
125 init() { }
126
127 void
128 delete_min_insert(T key, bool sup)
129 {
130 bool inf = false;
131 int source = losers[0].source;
132 for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
133 {
134 // The smaller one gets promoted.
135 if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
136 && comp(losers[pos].key, key))
137 || losers[pos].inf || sup)
138 {
139 // The other one is smaller.
140 std::swap(losers[pos].key, key);
141 std::swap(losers[pos].inf, inf);
142 std::swap(losers[pos].sup, sup);
143 std::swap(losers[pos].source, source);
144 }
145 }
146
147 losers[0].key = key;
148 losers[0].inf = inf;
149 losers[0].sup = sup;
150 losers[0].source = source;
151 }
152
153 void
154 insert_start_stable(T key, int source, bool sup)
155 {
156 bool inf = false;
157 for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
158 {
159 if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
160 && ((comp(losers[pos].key, key))
161 || (!comp(key, losers[pos].key)
162 && losers[pos].source < source)))
163 || losers[pos].inf || sup)
164 {
165 // Take next key.
166 std::swap(losers[pos].key, key);
167 std::swap(losers[pos].inf, inf);
168 std::swap(losers[pos].sup, sup);
169 std::swap(losers[pos].source, source);
170 }
171 }
172
173 losers[0].key = key;
174 losers[0].inf = inf;
175 losers[0].sup = sup;
176 losers[0].source = source;
177 }
178
179 void
180 init_stable() { }
181
182 void
183 delete_min_insert_stable(T key, bool sup)
184 {
185 bool inf = false;
186 int source = losers[0].source;
187 for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
188 {
189 if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
190 && ((comp(losers[pos].key, key))
191 || (!comp(key, losers[pos].key)
192 && losers[pos].source < source)))
193 || losers[pos].inf || sup)
194 {
195 std::swap(losers[pos].key, key);
196 std::swap(losers[pos].inf, inf);
197 std::swap(losers[pos].sup, sup);
198 std::swap(losers[pos].source, source);
199 }
200 }
201
202 losers[0].key = key;
203 losers[0].inf = inf;
204 losers[0].sup = sup;
205 losers[0].source = source;
206 }
207 };
208
209 #endif
210
211 #if _GLIBCXX_LOSER_TREE
212
213 /** @brief Guarded loser tree, either copying the whole element into
214 * the tree structure, or looking up the element via the index.
215 *
216 * Guarding is done explicitly through one flag sup per element,
217 * inf is not needed due to a better initialization routine. This
218 * is a well-performing variant.
219 */
220 template<typename T, typename Comparator = std::less<T> >
221 class LoserTree
222 {
223 private:
224 struct Loser
225 {
226 bool sup;
227 int source;
228 T key;
229 };
230
231 unsigned int ik, k, offset;
232 Loser* losers;
233 Comparator comp;
234 bool first_insert;
235
236 public:
237 LoserTree(unsigned int _k, Comparator _comp = std::less<T>())
238 : comp(_comp)
239 {
240 ik = _k;
241
242 // Next greater power of 2.
243 k = 1 << (log2(ik - 1) + 1);
244 offset = k;
245 // Avoid default-constructing losers[].key
246 losers = static_cast<Loser*>(::operator new(2 * k * sizeof(Loser)));
247 for (unsigned int i = ik - 1; i < k; ++i)
248 losers[i + k].sup = true;
249
250 first_insert = true;
251 }
252
253 ~LoserTree()
254 { ::operator delete(losers); }
255
256 int
257 get_min_source()
258 { return losers[0].source; }
259
260 void
261 insert_start(const T& key, int source, bool sup)
262 {
263 unsigned int pos = k + source;
264
265 if(first_insert)
266 {
267 // Construct all keys, so we can easily deconstruct them.
268 for (unsigned int i = 0; i < (2 * k); ++i)
269 ::new(&(losers[i].key)) T(key);
270 first_insert = false;
271 }
272 else
273 ::new(&(losers[pos].key)) T(key);
274
275 losers[pos].sup = sup;
276 losers[pos].source = source;
277 }
278
279 unsigned int
280 init_winner (unsigned int root)
281 {
282 if (root >= k)
283 {
284 return root;
285 }
286 else
287 {
288 unsigned int left = init_winner (2 * root);
289 unsigned int right = init_winner (2 * root + 1);
290 if (losers[right].sup
291 || (!losers[left].sup
292 && !comp(losers[right].key, losers[left].key)))
293 {
294 // Left one is less or equal.
295 losers[root] = losers[right];
296 return left;
297 }
298 else
299 {
300 // Right one is less.
301 losers[root] = losers[left];
302 return right;
303 }
304 }
305 }
306
307 void
308 init()
309 { losers[0] = losers[init_winner(1)]; }
310
311 // Do not pass const reference since key will be used as local variable.
312 void
313 delete_min_insert(T key, bool sup)
314 {
315 int source = losers[0].source;
316 for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
317 {
318 // The smaller one gets promoted.
319 if (sup || (!losers[pos].sup && comp(losers[pos].key, key)))
320 {
321 // The other one is smaller.
322 std::swap(losers[pos].sup, sup);
323 std::swap(losers[pos].source, source);
324 std::swap(losers[pos].key, key);
325 }
326 }
327
328 losers[0].sup = sup;
329 losers[0].source = source;
330 losers[0].key = key;
331 }
332
333 void
334 insert_start_stable(const T& key, int source, bool sup)
335 { return insert_start(key, source, sup); }
336
337 unsigned int
338 init_winner_stable (unsigned int root)
339 {
340 if (root >= k)
341 {
342 return root;
343 }
344 else
345 {
346 unsigned int left = init_winner (2 * root);
347 unsigned int right = init_winner (2 * root + 1);
348 if (losers[right].sup
349 || (!losers[left].sup
350 && !comp(losers[right].key, losers[left].key)))
351 {
352 // Left one is less or equal.
353 losers[root] = losers[right];
354 return left;
355 }
356 else
357 {
358 // Right one is less.
359 losers[root] = losers[left];
360 return right;
361 }
362 }
363 }
364
365 void
366 init_stable()
367 { losers[0] = losers[init_winner_stable(1)]; }
368
369 // Do not pass const reference since key will be used as local variable.
370 void
371 delete_min_insert_stable(T key, bool sup)
372 {
373 int source = losers[0].source;
374 for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
375 {
376 // The smaller one gets promoted, ties are broken by source.
377 if ( (sup && (!losers[pos].sup || losers[pos].source < source))
378 || (!sup && !losers[pos].sup
379 && ((comp(losers[pos].key, key))
380 || (!comp(key, losers[pos].key)
381 && losers[pos].source < source))))
382 {
383 // The other one is smaller.
384 std::swap(losers[pos].sup, sup);
385 std::swap(losers[pos].source, source);
386 std::swap(losers[pos].key, key);
387 }
388 }
389
390 losers[0].sup = sup;
391 losers[0].source = source;
392 losers[0].key = key;
393 }
394 };
395
396 #endif
397
398 #if _GLIBCXX_LOSER_TREE_REFERENCE
399
400 /** @brief Guarded loser tree, either copying the whole element into
401 * the tree structure, or looking up the element via the index.
402 *
403 * Guarding is done explicitly through one flag sup per element,
404 * inf is not needed due to a better initialization routine. This
405 * is a well-performing variant.
406 */
407 template<typename T, typename Comparator = std::less<T> >
408 class LoserTreeReference
409 {
410 #undef COPY
411 #ifdef COPY
412 #define KEY(i) losers[i].key
413 #define KEY_SOURCE(i) key
414 #else
415 #define KEY(i) keys[losers[i].source]
416 #define KEY_SOURCE(i) keys[i]
417 #endif
418 private:
419 struct Loser
420 {
421 bool sup;
422 int source;
423 #ifdef COPY
424 T key;
425 #endif
426 };
427
428 unsigned int ik, k, offset;
429 Loser* losers;
430 #ifndef COPY
431 T* keys;
432 #endif
433 Comparator comp;
434
435 public:
436 LoserTreeReference(unsigned int _k, Comparator _comp = std::less<T>())
437 : comp(_comp)
438 {
439 ik = _k;
440
441 // Next greater power of 2.
442 k = 1 << (log2(ik - 1) + 1);
443 offset = k;
444 losers = new Loser[k * 2];
445 #ifndef COPY
446 keys = new T[ik];
447 #endif
448 for (unsigned int i = ik - 1; i < k; ++i)
449 losers[i + k].sup = true;
450 }
451
452 ~LoserTreeReference()
453 {
454 delete[] losers;
455 #ifndef COPY
456 delete[] keys;
457 #endif
458 }
459
460 int
461 get_min_source()
462 { return losers[0].source; }
463
464 void
465 insert_start(T key, int source, bool sup)
466 {
467 unsigned int pos = k + source;
468
469 losers[pos].sup = sup;
470 losers[pos].source = source;
471 KEY(pos) = key;
472 }
473
474 unsigned int
475 init_winner(unsigned int root)
476 {
477 if (root >= k)
478 {
479 return root;
480 }
481 else
482 {
483 unsigned int left = init_winner (2 * root);
484 unsigned int right = init_winner (2 * root + 1);
485 if ( losers[right].sup ||
486 (!losers[left].sup && !comp(KEY(right), KEY(left))))
487 {
488 // Left one is less or equal.
489 losers[root] = losers[right];
490 return left;
491 }
492 else
493 {
494 // Right one is less.
495 losers[root] = losers[left];
496 return right;
497 }
498 }
499 }
500
501 void
502 init()
503 {
504 losers[0] = losers[init_winner(1)];
505 }
506
507 void
508 delete_min_insert(T key, bool sup)
509 {
510 int source = losers[0].source;
511 for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
512 {
513 // The smaller one gets promoted.
514 if (sup || (!losers[pos].sup && comp(KEY(pos), KEY_SOURCE(source))))
515 {
516 // The other one is smaller.
517 std::swap(losers[pos].sup, sup);
518 std::swap(losers[pos].source, source);
519 #ifdef COPY
520 std::swap(KEY(pos), KEY_SOURCE(source));
521 #endif
522 }
523 }
524
525 losers[0].sup = sup;
526 losers[0].source = source;
527 #ifdef COPY
528 KEY(0) = KEY_SOURCE(source);
529 #endif
530 }
531
532 void
533 insert_start_stable(T key, int source, bool sup)
534 { return insert_start(key, source, sup); }
535
536 unsigned int
537 init_winner_stable(unsigned int root)
538 {
539 if (root >= k)
540 {
541 return root;
542 }
543 else
544 {
545 unsigned int left = init_winner (2 * root);
546 unsigned int right = init_winner (2 * root + 1);
547 if (losers[right].sup
548 || (!losers[left].sup && !comp(KEY(right), KEY(left))))
549 {
550 // Left one is less or equal.
551 losers[root] = losers[right];
552 return left;
553 }
554 else
555 {
556 // Right one is less.
557 losers[root] = losers[left];
558 return right;
559 }
560 }
561 }
562
563 void
564 init_stable()
565 { losers[0] = losers[init_winner_stable(1)]; }
566
567 void
568 delete_min_insert_stable(T key, bool sup)
569 {
570 int source = losers[0].source;
571 for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
572 {
573 // The smaller one gets promoted, ties are broken by source.
574 if ((sup && (!losers[pos].sup || losers[pos].source < source))
575 || (!sup && !losers[pos].sup
576 && ((comp(KEY(pos), KEY_SOURCE(source)))
577 || (!comp(KEY_SOURCE(source), KEY(pos))
578 && losers[pos].source < source))))
579 {
580 // The other one is smaller.
581 std::swap(losers[pos].sup, sup);
582 std::swap(losers[pos].source, source);
583 #ifdef COPY
584 std::swap(KEY(pos), KEY_SOURCE(source));
585 #endif
586 }
587 }
588
589 losers[0].sup = sup;
590 losers[0].source = source;
591 #ifdef COPY
592 KEY(0) = KEY_SOURCE(source);
593 #endif
594 }
595 };
596 #undef KEY
597 #undef KEY_SOURCE
598
599 #endif
600
601 #if _GLIBCXX_LOSER_TREE_POINTER
602
603 /** @brief Guarded loser tree, either copying the whole element into
604 the tree structure, or looking up the element via the index.
605 * Guarding is done explicitly through one flag sup per element,
606 * inf is not needed due to a better initialization routine.
607 * This is a well-performing variant.
608 */
609 template<typename T, typename Comparator = std::less<T> >
610 class LoserTreePointer
611 {
612 private:
613 struct Loser
614 {
615 bool sup;
616 int source;
617 const T* keyp;
618 };
619
620 unsigned int ik, k, offset;
621 Loser* losers;
622 Comparator comp;
623
624 public:
625 LoserTreePointer(unsigned int _k, Comparator _comp = std::less<T>())
626 : comp(_comp)
627 {
628 ik = _k;
629
630 // Next greater power of 2.
631 k = 1 << (log2(ik - 1) + 1);
632 offset = k;
633 losers = new Loser[k * 2];
634 for (unsigned int i = ik - 1; i < k; ++i)
635 losers[i + k].sup = true;
636 }
637
638 ~LoserTreePointer()
639 { delete[] losers; }
640
641 int
642 get_min_source()
643 { return losers[0].source; }
644
645 void
646 insert_start(const T& key, int source, bool sup)
647 {
648 unsigned int pos = k + source;
649
650 losers[pos].sup = sup;
651 losers[pos].source = source;
652 losers[pos].keyp = &key;
653 }
654
655 unsigned int
656 init_winner(unsigned int root)
657 {
658 if (root >= k)
659 return root;
660 else
661 {
662 unsigned int left = init_winner (2 * root);
663 unsigned int right = init_winner (2 * root + 1);
664 if (losers[right].sup
665 || (!losers[left].sup
666 && !comp(*losers[right].keyp, *losers[left].keyp)))
667 {
668 // Left one is less or equal.
669 losers[root] = losers[right];
670 return left;
671 }
672 else
673 {
674 // Right one is less.
675 losers[root] = losers[left];
676 return right;
677 }
678 }
679 }
680
681 void
682 init()
683 { losers[0] = losers[init_winner(1)]; }
684
685 void
686 delete_min_insert(const T& key, bool sup)
687 {
688 const T* keyp = &key;
689 int source = losers[0].source;
690 for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
691 {
692 // The smaller one gets promoted.
693 if (sup || (!losers[pos].sup && comp(*losers[pos].keyp, *keyp)))
694 {
695 // The other one is smaller.
696 std::swap(losers[pos].sup, sup);
697 std::swap(losers[pos].source, source);
698 std::swap(losers[pos].keyp, keyp);
699 }
700 }
701
702 losers[0].sup = sup;
703 losers[0].source = source;
704 losers[0].keyp = keyp;
705 }
706
707 void
708 insert_start_stable(const T& key, int source, bool sup)
709 { return insert_start(key, source, sup); }
710
711 unsigned int
712 init_winner_stable(unsigned int root)
713 {
714 if (root >= k)
715 {
716 return root;
717 }
718 else
719 {
720 unsigned int left = init_winner (2 * root);
721 unsigned int right = init_winner (2 * root + 1);
722 if (losers[right].sup
723 || (!losers[left].sup && !comp(*losers[right].keyp,
724 *losers[left].keyp)))
725 {
726 // Left one is less or equal.
727 losers[root] = losers[right];
728 return left;
729 }
730 else
731 {
732 // Right one is less.
733 losers[root] = losers[left];
734 return right;
735 }
736 }
737 }
738
739 void
740 init_stable()
741 { losers[0] = losers[init_winner_stable(1)]; }
742
743 void
744 delete_min_insert_stable(const T& key, bool sup)
745 {
746 const T* keyp = &key;
747 int source = losers[0].source;
748 for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
749 {
750 // The smaller one gets promoted, ties are broken by source.
751 if ( (sup && (!losers[pos].sup || losers[pos].source < source))
752 || (!sup && !losers[pos].sup &&
753 ((comp(*losers[pos].keyp, *keyp))
754 || (!comp(*keyp, *losers[pos].keyp)
755 && losers[pos].source < source))))
756 {
757 // The other one is smaller.
758 std::swap(losers[pos].sup, sup);
759 std::swap(losers[pos].source, source);
760 std::swap(losers[pos].keyp, keyp);
761 }
762 }
763
764 losers[0].sup = sup;
765 losers[0].source = source;
766 losers[0].keyp = keyp;
767 }
768 };
769
770 #endif
771
772 #if _GLIBCXX_LOSER_TREE_UNGUARDED
773
774 /** @brief Unguarded loser tree, copying the whole element into the
775 * tree structure.
776 *
777 * No guarding is done, therefore not a single input sequence must
778 * run empty. This is a very fast variant.
779 */
780 template<typename T, typename Comparator = std::less<T> >
781 class LoserTreeUnguarded
782 {
783 private:
784 struct Loser
785 {
786 int source;
787 T key;
788 };
789
790 unsigned int ik, k, offset;
791 unsigned int* mapping;
792 Loser* losers;
793 Comparator comp;
794
795 void
796 map(unsigned int root, unsigned int begin, unsigned int end)
797 {
798 if (begin + 1 == end)
799 mapping[begin] = root;
800 else
801 {
802 // Next greater or equal power of 2.
803 unsigned int left = 1 << (log2(end - begin - 1));
804 map(root * 2, begin, begin + left);
805 map(root * 2 + 1, begin + left, end);
806 }
807 }
808
809 public:
810 LoserTreeUnguarded(unsigned int _k, Comparator _comp = std::less<T>())
811 : comp(_comp)
812 {
813 ik = _k;
814 // Next greater or equal power of 2.
815 k = 1 << (log2(ik - 1) + 1);
816 offset = k;
817 losers = new Loser[k + ik];
818 mapping = new unsigned int[ik];
819 map(1, 0, ik);
820 }
821
822 ~LoserTreeUnguarded()
823 {
824 delete[] losers;
825 delete[] mapping;
826 }
827
828 int
829 get_min_source()
830 { return losers[0].source; }
831
832 void
833 insert_start(const T& key, int source, bool)
834 {
835 unsigned int pos = mapping[source];
836 losers[pos].source = source;
837 losers[pos].key = key;
838 }
839
840 unsigned int
841 init_winner(unsigned int root, unsigned int begin, unsigned int end)
842 {
843 if (begin + 1 == end)
844 return mapping[begin];
845 else
846 {
847 // Next greater or equal power of 2.
848 unsigned int division = 1 << (log2(end - begin - 1));
849 unsigned int left = init_winner(2 * root, begin, begin + division);
850 unsigned int right =
851 init_winner(2 * root + 1, begin + division, end);
852 if (!comp(losers[right].key, losers[left].key))
853 {
854 // Left one is less or equal.
855 losers[root] = losers[right];
856 return left;
857 }
858 else
859 {
860 // Right one is less.
861 losers[root] = losers[left];
862 return right;
863 }
864 }
865 }
866
867 void
868 init()
869 { losers[0] = losers[init_winner(1, 0, ik)]; }
870
871 // Do not pass const reference since key will be used as local variable.
872 void
873 delete_min_insert(const T& key, bool)
874 {
875 losers[0].key = key;
876 T& keyr = losers[0].key;
877 int& source = losers[0].source;
878 for (int pos = mapping[source] / 2; pos > 0; pos /= 2)
879 {
880 // The smaller one gets promoted.
881 if (comp(losers[pos].key, keyr))
882 {
883 // The other one is smaller.
884 std::swap(losers[pos].source, source);
885 std::swap(losers[pos].key, keyr);
886 }
887 }
888 }
889
890 void
891 insert_start_stable(const T& key, int source, bool)
892 { return insert_start(key, source, false); }
893
894 void
895 init_stable()
896 { init(); }
897
898 void
899 delete_min_insert_stable(const T& key, bool)
900 {
901 losers[0].key = key;
902 T& keyr = losers[0].key;
903 int& source = losers[0].source;
904 for (int pos = mapping[source] / 2; pos > 0; pos /= 2)
905 {
906 // The smaller one gets promoted, ties are broken by source.
907 if (comp(losers[pos].key, keyr)
908 || (!comp(keyr, losers[pos].key)
909 && losers[pos].source < source))
910 {
911 // The other one is smaller.
912 std::swap(losers[pos].source, source);
913 std::swap(losers[pos].key, keyr);
914 }
915 }
916 }
917 };
918
919 #endif
920
921 #if _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED
922
923 /** @brief Unguarded loser tree, keeping only pointers to the
924 * elements in the tree structure.
925 *
926 * No guarding is done, therefore not a single input sequence must
927 * run empty. This is a very fast variant.
928 */
929 template<typename T, typename Comparator = std::less<T> >
930 class LoserTreePointerUnguarded
931 {
932 private:
933 struct Loser
934 {
935 int source;
936 const T* keyp;
937 };
938
939 unsigned int ik, k, offset;
940 unsigned int* mapping;
941 Loser* losers;
942 Comparator comp;
943
944 void map(unsigned int root, unsigned int begin, unsigned int end)
945 {
946 if (begin + 1 == end)
947 mapping[begin] = root;
948 else
949 {
950 // Next greater or equal power of 2.
951 unsigned int left = 1 << (log2(end - begin - 1));
952 map(root * 2, begin, begin + left);
953 map(root * 2 + 1, begin + left, end);
954 }
955 }
956
957 public:
958 LoserTreePointerUnguarded(unsigned int _k,
959 Comparator _comp = std::less<T>())
960 : comp(_comp)
961 {
962 ik = _k;
963
964 // Next greater power of 2.
965 k = 1 << (log2(ik - 1) + 1);
966 offset = k;
967 losers = new Loser[k + ik];
968 mapping = new unsigned int[ik];
969 map(1, 0, ik);
970 }
971
972 ~LoserTreePointerUnguarded()
973 {
974 delete[] losers;
975 delete[] mapping;
976 }
977
978 int
979 get_min_source()
980 { return losers[0].source; }
981
982 void
983 insert_start(const T& key, int source, bool)
984 {
985 unsigned int pos = mapping[source];
986 losers[pos].source = source;
987 losers[pos].keyp = &key;
988 }
989
990 unsigned int
991 init_winner(unsigned int root, unsigned int begin, unsigned int end)
992 {
993 if (begin + 1 == end)
994 return mapping[begin];
995 else
996 {
997 // Next greater or equal power of 2.
998 unsigned int division = 1 << (log2(end - begin - 1));
999 unsigned int left = init_winner(2 * root, begin, begin + division);
1000 unsigned int right = init_winner(2 * root + 1,
1001 begin + division, end);
1002 if (!comp(*losers[right].keyp, *losers[left].keyp))
1003 {
1004 // Left one is less or equal.
1005 losers[root] = losers[right];
1006 return left;
1007 }
1008 else
1009 {
1010 // Right one is less.
1011 losers[root] = losers[left];
1012 return right;
1013 }
1014 }
1015 }
1016
1017 void
1018 init()
1019 { losers[0] = losers[init_winner(1, 0, ik)]; }
1020
1021 void
1022 delete_min_insert(const T& key, bool)
1023 {
1024 const T* keyp = &key;
1025 int& source = losers[0].source;
1026 for (int pos = mapping[source] / 2; pos > 0; pos /= 2)
1027 {
1028 // The smaller one gets promoted.
1029 if (comp(*losers[pos].keyp, *keyp))
1030 {
1031 // The other one is smaller.
1032 std::swap(losers[pos].source, source);
1033 std::swap(losers[pos].keyp, keyp);
1034 }
1035 }
1036
1037 losers[0].keyp = keyp;
1038 }
1039
1040 void
1041 insert_start_stable(const T& key, int source, bool)
1042 { return insert_start(key, source, false); }
1043
1044 void
1045 init_stable()
1046 { init(); }
1047
1048 void
1049 delete_min_insert_stable(const T& key, bool)
1050 {
1051 int& source = losers[0].source;
1052 const T* keyp = &key;
1053 for (int pos = mapping[source] / 2; pos > 0; pos /= 2)
1054 {
1055 // The smaller one gets promoted, ties are broken by source.
1056 if (comp(*losers[pos].keyp, *keyp)
1057 || (!comp(*keyp, *losers[pos].keyp)
1058 && losers[pos].source < source))
1059 {
1060 // The other one is smaller.
1061 std::swap(losers[pos].source, source);
1062 std::swap(losers[pos].keyp, keyp);
1063 }
1064 }
1065 losers[0].keyp = keyp;
1066 }
1067 };
1068 #endif
1069
1070 template<typename _ValueTp, class Comparator>
1071 struct loser_tree_traits
1072 {
1073 #if _GLIBCXX_LOSER_TREE
1074 typedef LoserTree<_ValueTp, Comparator> LT;
1075 #else
1076 # if _GLIBCXX_LOSER_TREE_POINTER
1077 typedef LoserTreePointer<_ValueTp, Comparator> LT;
1078 # else
1079 # error Must define some type in losertree.h.
1080 # endif
1081 #endif
1082 };
1083
1084 template<typename _ValueTp, class Comparator>
1085 struct loser_tree_unguarded_traits
1086 {
1087 #if _GLIBCXX_LOSER_TREE_UNGUARDED
1088 typedef LoserTreeUnguarded<_ValueTp, Comparator> LT;
1089 #else
1090 # if _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED
1091 typedef LoserTreePointerUnguarded<_ValueTp, Comparator> LT;
1092 # else
1093 # error Must define some unguarded type in losertree.h.
1094 # endif
1095 #endif
1096 };
1097
1098 }
1099
1100 #endif