39 #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
40 #define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
49 #if _GLIBCXX_ASSERTIONS
54 #define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first)
58 template<
typename _RAIter1,
typename _RAIter2,
typename _OutputIterator,
59 typename _DifferenceTp,
typename _Compare>
62 _OutputIterator, _DifferenceTp, _Compare);
72 template<
typename _RAIter,
typename _Compare>
92 : _M_current(__begin), _M_end(__end), __comp(__comp)
106 typename std::iterator_traits<_RAIter>::value_type&
108 {
return *_M_current; }
113 {
return _M_current; }
120 operator<(_GuardedIterator<_RAIter, _Compare>& __bi1,
123 if (__bi1._M_current == __bi1._M_end)
124 return __bi2._M_current == __bi2._M_end;
125 if (__bi2._M_current == __bi2._M_end)
127 return (__bi1.__comp)(*__bi1, *__bi2);
135 operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
138 if (__bi2._M_current == __bi2._M_end)
139 return __bi1._M_current != __bi1._M_end;
140 if (__bi1._M_current == __bi1._M_end)
142 return !(__bi1.__comp)(*__bi2, *__bi1);
146 template<
typename _RAIter,
typename _Compare>
147 class _UnguardedIterator
160 _UnguardedIterator(_RAIter __begin,
161 _RAIter , _Compare& __comp)
162 : _M_current(__begin), __comp(__comp)
167 _UnguardedIterator<_RAIter, _Compare>&
176 typename std::iterator_traits<_RAIter>::value_type&
178 {
return *_M_current; }
183 {
return _M_current; }
190 operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1,
191 _UnguardedIterator<_RAIter, _Compare>& __bi2)
194 return (__bi1.__comp)(*__bi1, *__bi2);
202 operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1,
203 _UnguardedIterator<_RAIter, _Compare>& __bi2)
206 return !(__bi1.__comp)(*__bi2, *__bi1);
235 template<
template<
typename RAI,
typename C>
class iterator,
236 typename _RAIterIterator,
238 typename _DifferenceTp,
242 _RAIterIterator __seqs_end,
244 _DifferenceTp __length, _Compare __comp)
248 typedef _DifferenceTp _DifferenceType;
250 typedef typename std::iterator_traits<_RAIterIterator>
251 ::value_type::first_type
253 typedef typename std::iterator_traits<_RAIter1>::value_type
259 #if _GLIBCXX_ASSERTIONS
260 _DifferenceTp __orig_length = __length;
263 iterator<_RAIter1, _Compare>
264 __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
265 __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
266 __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp);
268 if (__seq0 <= __seq1)
270 if (__seq1 <= __seq2)
280 if (__seq1 <= __seq2)
282 if (__seq0 <= __seq2)
290 #define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \
291 __s ## __a ## __b ## __c : \
292 *__target = *__seq ## __a; \
296 if (__length == 0) goto __finish; \
297 if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \
298 if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \
299 goto __s ## __b ## __c ## __a;
301 _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=);
302 _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < );
303 _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < );
304 _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=);
305 _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=);
306 _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < );
308 #undef _GLIBCXX_PARALLEL_MERGE_3_CASE
313 #if _GLIBCXX_ASSERTIONS
314 _GLIBCXX_PARALLEL_ASSERT(
315 ((_RAIter1)__seq0 - __seqs_begin[0].first) +
316 ((_RAIter1)__seq1 - __seqs_begin[1].first) +
317 ((_RAIter1)__seq2 - __seqs_begin[2].first)
321 __seqs_begin[0].first = __seq0;
322 __seqs_begin[1].first = __seq1;
323 __seqs_begin[2].first = __seq2;
354 template<
template<
typename RAI,
typename C>
class iterator,
355 typename _RAIterIterator,
357 typename _DifferenceTp,
361 _RAIterIterator __seqs_end,
363 _DifferenceTp __length, _Compare __comp)
366 typedef _DifferenceTp _DifferenceType;
368 typedef typename std::iterator_traits<_RAIterIterator>
369 ::value_type::first_type
371 typedef typename std::iterator_traits<_RAIter1>::value_type
374 iterator<_RAIter1, _Compare>
375 __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
376 __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
377 __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp),
378 __seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp);
380 #define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) { \
381 if (__seq ## __d < __seq ## __a) \
382 goto __s ## __d ## __a ## __b ## __c; \
383 if (__seq ## __d < __seq ## __b) \
384 goto __s ## __a ## __d ## __b ## __c; \
385 if (__seq ## __d < __seq ## __c) \
386 goto __s ## __a ## __b ## __d ## __c; \
387 goto __s ## __a ## __b ## __c ## __d; }
389 if (__seq0 <= __seq1)
391 if (__seq1 <= __seq2)
392 _GLIBCXX_PARALLEL_DECISION(0,1,2,3)
395 _GLIBCXX_PARALLEL_DECISION(2,0,1,3)
397 _GLIBCXX_PARALLEL_DECISION(0,2,1,3)
401 if (__seq1 <= __seq2)
403 if (__seq0 <= __seq2)
404 _GLIBCXX_PARALLEL_DECISION(1,0,2,3)
406 _GLIBCXX_PARALLEL_DECISION(1,2,0,3)
409 _GLIBCXX_PARALLEL_DECISION(2,1,0,3)
412 #define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d, \
414 __s ## __a ## __b ## __c ## __d: \
415 if (__length == 0) goto __finish; \
416 *__target = *__seq ## __a; \
420 if (__seq ## __a __c0 __seq ## __b) \
421 goto __s ## __a ## __b ## __c ## __d; \
422 if (__seq ## __a __c1 __seq ## __c) \
423 goto __s ## __b ## __a ## __c ## __d; \
424 if (__seq ## __a __c2 __seq ## __d) \
425 goto __s ## __b ## __c ## __a ## __d; \
426 goto __s ## __b ## __c ## __d ## __a;
428 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=);
429 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=);
430 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=);
431 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=);
432 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=);
433 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=);
434 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=);
435 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=);
436 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=);
437 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < );
438 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=);
439 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < );
440 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=);
441 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < );
442 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=);
443 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < );
444 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < );
445 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < );
446 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < );
447 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < );
448 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < );
449 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < );
450 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < );
451 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < );
453 #undef _GLIBCXX_PARALLEL_MERGE_4_CASE
454 #undef _GLIBCXX_PARALLEL_DECISION
459 __seqs_begin[0].first = __seq0;
460 __seqs_begin[1].first = __seq1;
461 __seqs_begin[2].first = __seq2;
462 __seqs_begin[3].first = __seq3;
485 template<
typename _LT,
486 typename _RAIterIterator,
488 typename _DifferenceTp,
492 _RAIterIterator __seqs_end,
494 _DifferenceTp __length, _Compare __comp)
498 typedef _DifferenceTp _DifferenceType;
499 typedef typename std::iterator_traits<_RAIterIterator>
500 ::difference_type _SeqNumber;
501 typedef typename std::iterator_traits<_RAIterIterator>
502 ::value_type::first_type
504 typedef typename std::iterator_traits<_RAIter1>::value_type
507 _SeqNumber __k =
static_cast<_SeqNumber
>(__seqs_end - __seqs_begin);
509 _LT __lt(__k, __comp);
512 _ValueType* __arbitrary_element = 0;
514 for (_SeqNumber __t = 0; __t < __k; ++__t)
516 if(!__arbitrary_element
518 __arbitrary_element = &(*__seqs_begin[__t].first);
521 for (_SeqNumber __t = 0; __t < __k; ++__t)
523 if (__seqs_begin[__t].first == __seqs_begin[__t].second)
524 __lt.__insert_start(*__arbitrary_element, __t,
true);
526 __lt.__insert_start(*__seqs_begin[__t].first, __t,
false);
533 for (_DifferenceType __i = 0; __i < __length; ++__i)
536 __source = __lt.__get_min_source();
538 *(__target++) = *(__seqs_begin[__source].first++);
541 if (__seqs_begin[__source].first == __seqs_begin[__source].second)
542 __lt.__delete_min_insert(*__arbitrary_element,
true);
545 __lt.__delete_min_insert(*__seqs_begin[__source].first,
false);
569 template<
typename _LT,
570 typename _RAIterIterator,
572 typename _DifferenceTp,
typename _Compare>
575 _RAIterIterator __seqs_end,
577 const typename std::iterator_traits<
typename std::iterator_traits<
578 _RAIterIterator>::value_type::first_type>::value_type&
580 _DifferenceTp __length,
584 typedef _DifferenceTp _DifferenceType;
586 typedef typename std::iterator_traits<_RAIterIterator>
587 ::difference_type _SeqNumber;
588 typedef typename std::iterator_traits<_RAIterIterator>
589 ::value_type::first_type
591 typedef typename std::iterator_traits<_RAIter1>::value_type
594 _SeqNumber __k = __seqs_end - __seqs_begin;
596 _LT __lt(__k, __sentinel, __comp);
598 for (_SeqNumber __t = 0; __t < __k; ++__t)
600 #if _GLIBCXX_ASSERTIONS
601 _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
602 != __seqs_begin[__t].second);
604 __lt.__insert_start(*__seqs_begin[__t].first, __t,
false);
611 #if _GLIBCXX_ASSERTIONS
612 _DifferenceType __i = 0;
615 _RAIter3 __target_end = __target + __length;
616 while (__target < __target_end)
619 __source = __lt.__get_min_source();
621 #if _GLIBCXX_ASSERTIONS
622 _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k);
623 _GLIBCXX_PARALLEL_ASSERT(__i == 0
624 || !__comp(*(__seqs_begin[__source].first), *(__target - 1)));
628 *(__target++) = *(__seqs_begin[__source].first++);
630 #if _GLIBCXX_ASSERTIONS
634 __lt.__delete_min_insert(*__seqs_begin[__source].first,
false);
656 template<
typename UnguardedLoserTree,
657 typename _RAIterIterator,
659 typename _DifferenceTp,
663 _RAIterIterator __seqs_end,
665 const typename std::iterator_traits<
typename std::iterator_traits<
666 _RAIterIterator>::value_type::first_type>::value_type&
668 _DifferenceTp __length,
673 typedef _DifferenceTp _DifferenceType;
674 typedef std::iterator_traits<_RAIterIterator> _TraitsType;
675 typedef typename std::iterator_traits<_RAIterIterator>
676 ::value_type::first_type
678 typedef typename std::iterator_traits<_RAIter1>::value_type
681 _RAIter3 __target_end;
683 for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
690 __target_end = multiway_merge_loser_tree_unguarded<UnguardedLoserTree>
691 (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
693 #if _GLIBCXX_ASSERTIONS
694 _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length);
695 _GLIBCXX_PARALLEL_ASSERT(
__is_sorted(__target, __target_end, __comp));
700 for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
730 template <
typename _Tp>
747 template<
bool __sentinels ,
748 typename _RAIterIterator,
750 typename _DifferenceTp,
755 operator()(_RAIterIterator __seqs_begin,
756 _RAIterIterator __seqs_end,
758 _DifferenceTp __length, _Compare __comp)
759 {
return multiway_merge_3_variant<_GuardedIterator>
760 (__seqs_begin, __seqs_end, __target, __length, __comp); }
768 template<
typename _RAIterIterator,
770 typename _DifferenceTp,
773 _RAIter3, _DifferenceTp,
777 operator()(_RAIterIterator __seqs_begin,
778 _RAIterIterator __seqs_end,
780 _DifferenceTp __length, _Compare __comp)
781 {
return multiway_merge_3_variant<_UnguardedIterator>
782 (__seqs_begin, __seqs_end, __target, __length, __comp); }
790 template<
bool __sentinels ,
791 typename _RAIterIterator,
793 typename _DifferenceTp,
798 operator()(_RAIterIterator __seqs_begin,
799 _RAIterIterator __seqs_end,
801 _DifferenceTp __length, _Compare __comp)
802 {
return multiway_merge_4_variant<_GuardedIterator>
803 (__seqs_begin, __seqs_end, __target, __length, __comp); }
811 template<
typename _RAIterIterator,
813 typename _DifferenceTp,
816 _RAIter3, _DifferenceTp,
820 operator()(_RAIterIterator __seqs_begin,
821 _RAIterIterator __seqs_end,
823 _DifferenceTp __length, _Compare __comp)
824 {
return multiway_merge_4_variant<_UnguardedIterator>
825 (__seqs_begin, __seqs_end, __target, __length, __comp); }
831 template<
bool __sentinels,
833 typename _RAIterIterator,
835 typename _DifferenceTp,
840 operator()(_RAIterIterator __seqs_begin,
841 _RAIterIterator __seqs_end,
843 const typename std::iterator_traits<
typename std::iterator_traits<
844 _RAIterIterator>::value_type::first_type>::value_type&
846 _DifferenceTp __length, _Compare __comp)
848 typedef typename std::iterator_traits<_RAIterIterator>
849 ::value_type::first_type
851 typedef typename std::iterator_traits<_RAIter1>::value_type
855 typename __gnu_cxx::__conditional_type<
860 (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
867 template<
bool __stable,
868 typename _RAIterIterator,
870 typename _DifferenceTp,
874 _RAIter3, _DifferenceTp,
878 operator()(_RAIterIterator __seqs_begin,
879 _RAIterIterator __seqs_end,
881 const typename std::iterator_traits<
typename std::iterator_traits<
882 _RAIterIterator>::value_type::first_type>::value_type&
884 _DifferenceTp __length, _Compare __comp)
886 typedef typename std::iterator_traits<_RAIterIterator>
887 ::value_type::first_type
889 typedef typename std::iterator_traits<_RAIter1>::value_type
893 typename __gnu_cxx::__conditional_type<
897 >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp);
913 template<
bool __stable,
915 typename _RAIterIterator,
917 typename _DifferenceTp,
921 _RAIterIterator __seqs_end,
923 const typename std::iterator_traits<
typename std::iterator_traits<
924 _RAIterIterator>::value_type::first_type>::value_type&
926 _DifferenceTp __length, _Compare __comp)
930 typedef _DifferenceTp _DifferenceType;
931 typedef typename std::iterator_traits<_RAIterIterator>
932 ::difference_type _SeqNumber;
933 typedef typename std::iterator_traits<_RAIterIterator>
934 ::value_type::first_type
936 typedef typename std::iterator_traits<_RAIter1>::value_type
939 #if _GLIBCXX_ASSERTIONS
940 for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
943 (*__s).second, __comp));
947 _DifferenceTp __total_length = 0;
948 for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
951 __length = std::min<_DifferenceTp>(__length, __total_length);
956 _RAIter3 __return_target = __target;
957 _SeqNumber __k =
static_cast<_SeqNumber
>(__seqs_end - __seqs_begin);
964 __return_target = std::copy(__seqs_begin[0].first,
965 __seqs_begin[0].first + __length,
967 __seqs_begin[0].first += __length;
971 __seqs_begin[0].second,
972 __seqs_begin[1].first,
973 __seqs_begin[1].second,
974 __target, __length, __comp);
978 <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
979 (__seqs_begin, __seqs_end, __target, __length, __comp);
983 <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
984 (__seqs_begin, __seqs_end, __target, __length, __comp);
988 <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp,
990 (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
993 #if _GLIBCXX_ASSERTIONS
994 _GLIBCXX_PARALLEL_ASSERT(
995 __is_sorted(__target, __target + __length, __comp));
998 return __return_target;
1006 template<
bool __stable,
class _RAIter,
class _StrictWeakOrdering>
1010 operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
1011 { __gnu_sequential::stable_sort(__first, __last, __comp); }
1019 template<
class _RAIter,
class _StrictWeakOrdering>
1023 operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
1024 { __gnu_sequential::sort(__first, __last, __comp); }
1030 template<
bool __stable,
1031 typename _RAIterIterator,
1033 typename _DifferenceType>
1036 _RAIterIterator __seqs_end,
1037 _DifferenceType __length,
1038 _DifferenceType __total_length,
1042 typedef typename std::iterator_traits<_RAIterIterator>
1043 ::difference_type _SeqNumber;
1044 typedef typename std::iterator_traits<_RAIterIterator>
1045 ::value_type::first_type
1047 typedef typename std::iterator_traits<_RAIter1>::value_type
1051 const _SeqNumber __k
1052 =
static_cast<_SeqNumber
>(__seqs_end - __seqs_begin);
1054 const _ThreadIndex __num_threads = omp_get_num_threads();
1056 const _DifferenceType __num_samples =
1059 _ValueType* __samples =
static_cast<_ValueType*
>
1060 (::operator
new(
sizeof(_ValueType) * __k * __num_samples));
1062 for (_SeqNumber __s = 0; __s < __k; ++__s)
1063 for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
1065 _DifferenceType sample_index =
static_cast<_DifferenceType
>
1067 * (double(__i + 1) / (__num_samples + 1))
1068 * (double(__length) / __total_length));
1069 new(&(__samples[__s * __num_samples + __i]))
1070 _ValueType(__seqs_begin[__s].first[sample_index]);
1076 (__samples, __samples + (__num_samples * __k), __comp);
1078 for (
_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
1080 for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
1084 __pieces[__slab][__seq].first = std::upper_bound
1085 (__seqs_begin[__seq].first, __seqs_begin[__seq].second,
1086 __samples[__num_samples * __k * __slab / __num_threads],
1088 - __seqs_begin[__seq].first;
1091 __pieces[__slab][__seq].first = 0;
1092 if ((__slab + 1) < __num_threads)
1093 __pieces[__slab][__seq].second = std::upper_bound
1094 (__seqs_begin[__seq].first, __seqs_begin[__seq].second,
1095 __samples[__num_samples * __k * (__slab + 1) / __num_threads],
1097 - __seqs_begin[__seq].first;
1100 __pieces[__slab][__seq].second =
1104 for (_SeqNumber __s = 0; __s < __k; ++__s)
1105 for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
1106 __samples[__s * __num_samples + __i].~_ValueType();
1107 ::operator
delete(__samples);
1115 template<
bool __stable,
1116 typename _RAIterIterator,
1118 typename _DifferenceType>
1121 _RAIterIterator __seqs_end,
1122 _DifferenceType __length,
1123 _DifferenceType __total_length,
1127 typedef typename std::iterator_traits<_RAIterIterator>
1128 ::difference_type _SeqNumber;
1129 typedef typename std::iterator_traits<_RAIterIterator>
1130 ::value_type::first_type
1133 const bool __tight = (__total_length == __length);
1136 const _SeqNumber __k = __seqs_end - __seqs_begin;
1138 const _ThreadIndex __num_threads = omp_get_num_threads();
1146 copy(__seqs_begin, __seqs_end, __se.
begin());
1148 _DifferenceType* __borders =
1149 new _DifferenceType[__num_threads + 1];
1152 for (
_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s)
1154 __offsets[__s].
resize(__k);
1156 __offsets[__s].
begin(), __comp);
1161 __offsets[__num_threads - 1].
resize(__k);
1163 _DifferenceType(__length),
1164 __offsets[__num_threads - 1].
begin(),
1170 for (
_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
1173 for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
1179 __pieces[__slab][__seq].first = 0;
1182 __pieces[__slab][__seq].first =
1183 __pieces[__slab - 1][__seq].second;
1184 if (!__tight || __slab < (__num_threads - 1))
1185 __pieces[__slab][__seq].second =
1186 __offsets[__slab][__seq] - __seqs_begin[__seq].first;
1190 __pieces[__slab][__seq].second =
1217 template<
bool __stable,
1219 typename _RAIterIterator,
1221 typename _DifferenceTp,
1226 _RAIterIterator __seqs_end,
1228 _Splitter __splitter,
1229 _DifferenceTp __length,
1233 #if _GLIBCXX_ASSERTIONS
1234 _GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1);
1239 typedef _DifferenceTp _DifferenceType;
1240 typedef typename std::iterator_traits<_RAIterIterator>
1241 ::difference_type _SeqNumber;
1242 typedef typename std::iterator_traits<_RAIterIterator>
1243 ::value_type::first_type
1246 std::iterator_traits<_RAIter1>::value_type _ValueType;
1250 seq_type* __ne_seqs =
new seq_type[__seqs_end - __seqs_begin];
1252 _DifferenceType __total_length = 0;
1253 for (_RAIterIterator __raii = __seqs_begin;
1254 __raii != __seqs_end; ++__raii)
1257 if(__seq_length > 0)
1259 __total_length += __seq_length;
1260 __ne_seqs[__k++] = *__raii;
1266 __length = std::min<_DifferenceTp>(__length, __total_length);
1268 if (__total_length == 0 || __k == 0)
1277 (std::min<_DifferenceType>(__num_threads, __total_length));
1279 # pragma omp parallel num_threads (__num_threads)
1283 __num_threads = omp_get_num_threads();
1288 __pieces[__s].resize(__k);
1290 _DifferenceType __num_samples =
1294 __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length,
1300 _DifferenceType __target_position = 0;
1302 for (_SeqNumber __c = 0; __c < __k; ++__c)
1303 __target_position += __pieces[__iam][__c].first;
1305 seq_type* __chunks =
new seq_type[__k];
1307 for (_SeqNumber __s = 0; __s < __k; ++__s)
1309 + __pieces[__iam][__s].first,
1310 __ne_seqs[__s].first
1311 + __pieces[__iam][__s].second);
1313 if(__length > __target_position)
1314 __sequential_multiway_merge<__stable, __sentinels>
1315 (__chunks, __chunks + __k, __target + __target_position,
1316 *(__seqs_begin->second), __length - __target_position, __comp);
1321 #if _GLIBCXX_ASSERTIONS
1322 _GLIBCXX_PARALLEL_ASSERT(
1323 __is_sorted(__target, __target + __length, __comp));
1328 for (_RAIterIterator __raii = __seqs_begin;
1329 __raii != __seqs_end; ++__raii)
1333 (*__raii).first += __pieces[__num_threads - 1][__k++].second;
1339 return __target + __length;
1413 template<
typename _RAIterPairIterator,
1414 typename _RAIterOut,
1415 typename _DifferenceTp,
1419 _RAIterPairIterator __seqs_end,
1420 _RAIterOut __target,
1421 _DifferenceTp __length, _Compare __comp,
1424 typedef _DifferenceTp _DifferenceType;
1428 if (__seqs_begin == __seqs_end)
1434 (__seqs_begin, __seqs_end, __target,
1435 *(__seqs_begin->second), __length, __comp);
1439 template<
typename _RAIterPairIterator,
1440 typename _RAIterOut,
1441 typename _DifferenceTp,
1445 _RAIterPairIterator __seqs_end,
1446 _RAIterOut __target,
1447 _DifferenceTp __length, _Compare __comp,
1450 typedef _DifferenceTp _DifferenceType;
1454 if (__seqs_begin == __seqs_end)
1460 if ((__seqs_end - __seqs_begin > 1)
1462 ((__seqs_end - __seqs_begin) >=
1468 (__seqs_begin, __seqs_end, __target,
1470 typename
std::iterator_traits<_RAIterPairIterator>
1471 ::value_type*, _Compare, _DifferenceTp>,
1472 static_cast<_DifferenceType>(__length), __comp,
1473 __tag.__get_num_threads());
1477 (__seqs_begin, __seqs_end, __target,
1478 *(__seqs_begin->second), __length, __comp);
1482 template<typename _RAIterPairIterator,
1483 typename _RAIterOut,
1484 typename _DifferenceTp,
1488 _RAIterPairIterator __seqs_end,
1489 _RAIterOut __target,
1490 _DifferenceTp __length, _Compare __comp,
1493 typedef _DifferenceTp _DifferenceType;
1497 if (__seqs_begin == __seqs_end)
1503 if ((__seqs_end - __seqs_begin > 1)
1505 ((__seqs_end - __seqs_begin) >=
1511 (__seqs_begin, __seqs_end, __target,
1513 typename
std::iterator_traits<_RAIterPairIterator>
1514 ::value_type*, _Compare, _DifferenceTp>,
1515 static_cast<_DifferenceType>(__length), __comp,
1516 __tag.__get_num_threads());
1520 (__seqs_begin, __seqs_end, __target,
1521 *(__seqs_begin->second), __length, __comp);
1525 template<typename _RAIterPairIterator,
1526 typename _RAIterOut,
1527 typename _DifferenceTp,
1531 _RAIterPairIterator __seqs_end,
1532 _RAIterOut __target,
1533 _DifferenceTp __length, _Compare __comp,
1534 parallel_tag __tag = parallel_tag(0))
1535 {
return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
1536 __comp, exact_tag(__tag.__get_num_threads())); }
1539 template<
typename _RAIterPairIterator,
1540 typename _RAIterOut,
1541 typename _DifferenceTp,
1545 _RAIterPairIterator __seqs_end,
1546 _RAIterOut __target,
1547 _DifferenceTp __length, _Compare __comp,
1548 default_parallel_tag __tag)
1549 {
return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
1550 __comp, exact_tag(__tag.__get_num_threads())); }
1554 template<
typename _RAIterPairIterator,
1555 typename _RAIterOut,
1556 typename _DifferenceTp,
1559 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1560 _RAIterPairIterator __seqs_end,
1561 _RAIterOut __target,
1562 _DifferenceTp __length, _Compare __comp,
1565 typedef _DifferenceTp _DifferenceType;
1569 if (__seqs_begin == __seqs_end)
1575 (__seqs_begin, __seqs_end, __target,
1576 *(__seqs_begin->second), __length, __comp);
1580 template<typename _RAIterPairIterator,
1581 typename _RAIterOut,
1582 typename _DifferenceTp,
1585 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1586 _RAIterPairIterator __seqs_end,
1587 _RAIterOut __target,
1588 _DifferenceTp __length, _Compare __comp,
1591 typedef _DifferenceTp _DifferenceType;
1595 if (__seqs_begin == __seqs_end)
1601 if ((__seqs_end - __seqs_begin > 1)
1603 ((__seqs_end - __seqs_begin) >=
1609 (__seqs_begin, __seqs_end, __target,
1611 typename
std::iterator_traits<_RAIterPairIterator>
1612 ::value_type*, _Compare, _DifferenceTp>,
1613 static_cast<_DifferenceType>(__length), __comp,
1614 __tag.__get_num_threads());
1618 (__seqs_begin, __seqs_end, __target,
1619 *(__seqs_begin->second), __length, __comp);
1623 template<typename _RAIterPairIterator,
1624 typename _RAIterOut,
1625 typename _DifferenceTp,
1628 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1629 _RAIterPairIterator __seqs_end,
1630 _RAIterOut __target,
1631 _DifferenceTp __length, _Compare __comp,
1634 typedef _DifferenceTp _DifferenceType;
1638 if (__seqs_begin == __seqs_end)
1644 if ((__seqs_end - __seqs_begin > 1)
1646 ((__seqs_end - __seqs_begin) >=
1652 (__seqs_begin, __seqs_end, __target,
1654 typename
std::iterator_traits<_RAIterPairIterator>
1655 ::value_type*, _Compare, _DifferenceTp>,
1656 static_cast<_DifferenceType>(__length), __comp,
1657 __tag.__get_num_threads());
1661 (__seqs_begin, __seqs_end, __target,
1662 *(__seqs_begin->second), __length, __comp);
1666 template<typename _RAIterPairIterator,
1667 typename _RAIterOut,
1668 typename _DifferenceTp,
1671 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1672 _RAIterPairIterator __seqs_end,
1673 _RAIterOut __target,
1674 _DifferenceTp __length, _Compare __comp,
1675 parallel_tag __tag = parallel_tag(0))
1677 return stable_multiway_merge
1678 (__seqs_begin, __seqs_end, __target, __length, __comp,
1679 exact_tag(__tag.__get_num_threads()));
1683 template<
typename _RAIterPairIterator,
1684 typename _RAIterOut,
1685 typename _DifferenceTp,
1688 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1689 _RAIterPairIterator __seqs_end,
1690 _RAIterOut __target,
1691 _DifferenceTp __length, _Compare __comp,
1692 default_parallel_tag __tag)
1694 return stable_multiway_merge
1695 (__seqs_begin, __seqs_end, __target, __length, __comp,
1696 exact_tag(__tag.__get_num_threads()));
1777 template<
typename _RAIterPairIterator,
1778 typename _RAIterOut,
1779 typename _DifferenceTp,
1783 _RAIterPairIterator __seqs_end,
1784 _RAIterOut __target,
1785 _DifferenceTp __length, _Compare __comp,
1788 typedef _DifferenceTp _DifferenceType;
1792 if (__seqs_begin == __seqs_end)
1798 (__seqs_begin, __seqs_end,
1799 __target, *(__seqs_begin->second), __length, __comp);
1803 template<
typename _RAIterPairIterator,
1804 typename _RAIterOut,
1805 typename _DifferenceTp,
1809 _RAIterPairIterator __seqs_end,
1810 _RAIterOut __target,
1811 _DifferenceTp __length, _Compare __comp,
1814 typedef _DifferenceTp _DifferenceType;
1818 if (__seqs_begin == __seqs_end)
1824 if ((__seqs_end - __seqs_begin > 1)
1826 ((__seqs_end - __seqs_begin) >=
1832 (__seqs_begin, __seqs_end, __target,
1834 typename
std::iterator_traits<_RAIterPairIterator>
1835 ::value_type*, _Compare, _DifferenceTp>,
1836 static_cast<_DifferenceType>(__length), __comp,
1837 __tag.__get_num_threads());
1841 (__seqs_begin, __seqs_end, __target,
1842 *(__seqs_begin->second), __length, __comp);
1846 template<typename _RAIterPairIterator,
1847 typename _RAIterOut,
1848 typename _DifferenceTp,
1852 _RAIterPairIterator __seqs_end,
1853 _RAIterOut __target,
1854 _DifferenceTp __length, _Compare __comp,
1857 typedef _DifferenceTp _DifferenceType;
1861 if (__seqs_begin == __seqs_end)
1867 if ((__seqs_end - __seqs_begin > 1)
1869 ((__seqs_end - __seqs_begin) >=
1875 (__seqs_begin, __seqs_end, __target,
1877 typename
std::iterator_traits<_RAIterPairIterator>
1878 ::value_type*, _Compare, _DifferenceTp>,
1879 static_cast<_DifferenceType>(__length), __comp,
1880 __tag.__get_num_threads());
1884 __seqs_begin, __seqs_end, __target,
1885 *(__seqs_begin->second), __length, __comp);
1889 template<typename _RAIterPairIterator,
1890 typename _RAIterOut,
1891 typename _DifferenceTp,
1895 _RAIterPairIterator __seqs_end,
1896 _RAIterOut __target,
1897 _DifferenceTp __length, _Compare __comp,
1898 parallel_tag __tag = parallel_tag(0))
1901 (__seqs_begin, __seqs_end, __target, __length, __comp,
1902 exact_tag(__tag.__get_num_threads()));
1906 template<
typename _RAIterPairIterator,
1907 typename _RAIterOut,
1908 typename _DifferenceTp,
1912 _RAIterPairIterator __seqs_end,
1913 _RAIterOut __target,
1914 _DifferenceTp __length, _Compare __comp,
1915 default_parallel_tag __tag)
1918 (__seqs_begin, __seqs_end, __target, __length, __comp,
1919 exact_tag(__tag.__get_num_threads()));
1924 template<
typename _RAIterPairIterator,
1925 typename _RAIterOut,
1926 typename _DifferenceTp,
1929 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1930 _RAIterPairIterator __seqs_end,
1931 _RAIterOut __target,
1932 _DifferenceTp __length, _Compare __comp,
1935 typedef _DifferenceTp _DifferenceType;
1939 if (__seqs_begin == __seqs_end)
1945 (__seqs_begin, __seqs_end, __target,
1946 *(__seqs_begin->second), __length, __comp);
1950 template<typename _RAIterPairIterator,
1951 typename _RAIterOut,
1952 typename _DifferenceTp,
1955 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1956 _RAIterPairIterator __seqs_end,
1957 _RAIterOut __target,
1958 _DifferenceTp __length, _Compare __comp,
1961 typedef _DifferenceTp _DifferenceType;
1965 if (__seqs_begin == __seqs_end)
1971 if ((__seqs_end - __seqs_begin > 1)
1973 ((__seqs_end - __seqs_begin) >=
1979 (__seqs_begin, __seqs_end, __target,
1981 typename
std::iterator_traits<_RAIterPairIterator>
1982 ::value_type*, _Compare, _DifferenceTp>,
1983 static_cast<_DifferenceType>(__length), __comp,
1984 __tag.__get_num_threads());
1988 (__seqs_begin, __seqs_end, __target,
1989 *(__seqs_begin->second), __length, __comp);
1993 template<typename _RAIterPairIterator,
1994 typename _RAIterOut,
1995 typename _DifferenceTp,
1998 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1999 _RAIterPairIterator __seqs_end,
2000 _RAIterOut __target,
2001 _DifferenceTp __length,
2005 typedef _DifferenceTp _DifferenceType;
2009 if (__seqs_begin == __seqs_end)
2015 if ((__seqs_end - __seqs_begin > 1)
2017 ((__seqs_end - __seqs_begin) >=
2023 (__seqs_begin, __seqs_end, __target,
2025 typename
std::iterator_traits<_RAIterPairIterator>
2026 ::value_type*, _Compare, _DifferenceTp>,
2027 static_cast<_DifferenceType>(__length), __comp,
2028 __tag.__get_num_threads());
2032 (__seqs_begin, __seqs_end, __target,
2033 *(__seqs_begin->second), __length, __comp);
2037 template<typename _RAIterPairIterator,
2038 typename _RAIterOut,
2039 typename _DifferenceTp,
2042 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
2043 _RAIterPairIterator __seqs_end,
2044 _RAIterOut __target,
2045 _DifferenceTp __length,
2047 parallel_tag __tag = parallel_tag(0))
2049 return stable_multiway_merge_sentinels
2050 (__seqs_begin, __seqs_end, __target, __length, __comp,
2051 exact_tag(__tag.__get_num_threads()));
2055 template<
typename _RAIterPairIterator,
2056 typename _RAIterOut,
2057 typename _DifferenceTp,
2060 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
2061 _RAIterPairIterator __seqs_end,
2062 _RAIterOut __target,
2063 _DifferenceTp __length, _Compare __comp,
2064 default_parallel_tag __tag)
2066 return stable_multiway_merge_sentinels
2067 (__seqs_begin, __seqs_end, __target, __length, __comp,
2068 exact_tag(__tag.__get_num_threads()));
_RAIter3 multiway_merge_loser_tree_unguarded(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits< typename std::iterator_traits< _RAIterIterator >::value_type::first_type >::value_type &__sentinel, _DifferenceTp __length, _Compare __comp)
Multi-way merging procedure for a high branching factor, unguarded case.
void multiseq_partition(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankIterator __begin_offsets, _Compare __comp=std::less< typename std::iterator_traits< typename std::iterator_traits< _RanSeqs >::value_type::first_type >::value_type >())
Splits several sorted sequences at a certain global __rank, resulting in a splitting point for each s...
void resize(size_type __new_size)
Resizes the vector to the specified number of elements.
_Iterator wrapper supporting an implicit supremum at the end of the sequence, dominating all comparis...
GNU parallel code for public use.
iterator begin() noexcept
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
A standard container which offers fixed time access to individual elements in any order...
_RAIter3 parallel_multiway_merge(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _Splitter __splitter, _DifferenceTp __length, _Compare __comp, _ThreadIndex __num_threads)
Parallel multi-way merge routine.
_RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag)
Multiway Merge Frontend.
uint16_t _ThreadIndex
Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit in...
Forces sequential execution at compile time.
uint64_t _SequenceIndex
Unsigned integer to index __elements. The total number of elements for each algorithm must fit into t...
_RAIter3 multiway_merge_3_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp)
Highly efficient 3-way merging procedure.
void multiway_merge_sampling_splitting(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length, _DifferenceType __total_length, _Compare __comp, std::vector< std::pair< _DifferenceType, _DifferenceType > > *__pieces)
Sampling based splitting for parallel multiway-merge routine.
Many generic loser tree variants. This file is a GNU parallel extension to the Standard C++ Library...
void multiway_merge_exact_splitting(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length, _DifferenceType __total_length, _Compare __comp, std::vector< std::pair< _DifferenceType, _DifferenceType > > *__pieces)
Exact splitting for parallel multiway-merge routine.
Stable _LoserTree implementation.
Defines on whether to include algorithm variants.
Switch for 4-way merging with __sentinels turned off.
unsigned int merge_oversampling
Oversampling factor for merge.
bool __is_sorted(_IIter __begin, _IIter __end, _Compare __comp)
Check whether [__begin, __end) is sorted according to __comp.
Routines for checking the correctness of algorithm results. This file is a GNU parallel extension to ...
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
ISO C++ entities toplevel namespace is std.
_RAIter3 multiway_merge_loser_tree_sentinel(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits< typename std::iterator_traits< _RAIterIterator >::value_type::first_type >::value_type &__sentinel, _DifferenceTp __length, _Compare __comp)
Multi-way merging procedure for a high branching factor, requiring sentinels to exist.
#define _GLIBCXX_PARALLEL_LENGTH(__s)
Length of a sequence described by a pair of iterators.
_RAIter3 multiway_merge_loser_tree(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp)
Multi-way merging procedure for a high branching factor, guarded case.
_GuardedIterator< _RAIter, _Compare > & operator++()
Pre-increment operator.
_OutputIterator __merge_advance(_RAIter1 &__begin1, _RAIter1 __end1, _RAIter2 &__begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp)
Merge routine being able to merge only the __max_length smallest elements.
Stable implementation of unguarded _LoserTree.
Stable _LoserTree variant.
static const bool _M_use_pointer
True iff to use pointers instead of values in loser trees.
_RAIter3 __sequential_multiway_merge(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits< typename std::iterator_traits< _RAIterIterator >::value_type::first_type >::value_type &__sentinel, _DifferenceTp __length, _Compare __comp)
Sequential multi-way merging switch.
End-user include file. Provides advanced settings and tuning options. This file is a GNU parallel ext...
#define _GLIBCXX_PARALLEL_CONDITION(__c)
Determine at compile(?)-time if the parallel variant of an algorithm should be called.
Stable unguarded _LoserTree variant storing pointers.
_RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag)
Multiway Merge Frontend.
Switch for k-way merging with __sentinels turned on.
static const _Settings & get()
Get the global settings.
std::iterator_traits< _RAIter >::value_type & operator*()
Dereference operator.
Functions to find elements of a certain global __rank in multiple sorted sequences. Also serves for splitting such sequence sets.
Switch for 3-way merging with __sentinels turned off.
_OutputIterator __equally_split(_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s)
function to split a sequence into parts of almost equal size.
_RAIter3 multiway_merge_4_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp)
Highly efficient 4-way merging procedure.
Struct holding two objects of arbitrary type.
Forces parallel merging with exact splitting, at compile time.
Traits for determining whether the loser tree should use pointers or copies.
_GuardedIterator(_RAIter __begin, _RAIter __end, _Compare &__comp)
Constructor. Sets iterator to beginning of sequence.