39 #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
40 #define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
48 #if _GLIBCXX_ASSERTIONS
53 #define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first)
55 namespace __gnu_parallel
65 template<
typename _RAIter,
typename _Compare>
85 : _M_current(__begin), _M_end(__end), __comp(__comp)
99 typename std::iterator_traits<_RAIter>::value_type&
101 {
return *_M_current; }
106 {
return _M_current; }
113 operator<(_GuardedIterator<_RAIter, _Compare>& __bi1,
116 if (__bi1._M_current == __bi1._M_end)
117 return __bi2._M_current == __bi2._M_end;
118 if (__bi2._M_current == __bi2._M_end)
120 return (__bi1.__comp)(*__bi1, *__bi2);
128 operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
131 if (__bi2._M_current == __bi2._M_end)
132 return __bi1._M_current != __bi1._M_end;
133 if (__bi1._M_current == __bi1._M_end)
135 return !(__bi1.__comp)(*__bi2, *__bi1);
139 template<
typename _RAIter,
typename _Compare>
140 class _UnguardedIterator
153 _UnguardedIterator(_RAIter __begin,
154 _RAIter , _Compare& __comp)
155 : _M_current(__begin), __comp(__comp)
160 _UnguardedIterator<_RAIter, _Compare>&
169 typename std::iterator_traits<_RAIter>::value_type&
171 {
return *_M_current; }
176 {
return _M_current; }
183 operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1,
184 _UnguardedIterator<_RAIter, _Compare>& __bi2)
187 return (__bi1.__comp)(*__bi1, *__bi2);
195 operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1,
196 _UnguardedIterator<_RAIter, _Compare>& __bi2)
199 return !(__bi1.__comp)(*__bi2, *__bi1);
228 template<
template<
typename RAI,
typename C>
class iterator,
229 typename _RAIterIterator,
231 typename _DifferenceTp,
235 _RAIterIterator __seqs_end,
237 _DifferenceTp __length, _Compare __comp)
241 typedef _DifferenceTp _DifferenceType;
243 typedef typename std::iterator_traits<_RAIterIterator>
244 ::value_type::first_type
246 typedef typename std::iterator_traits<_RAIter1>::value_type
252 #if _GLIBCXX_ASSERTIONS
253 _DifferenceTp __orig_length = __length;
256 iterator<_RAIter1, _Compare>
257 __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
258 __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
259 __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp);
261 if (__seq0 <= __seq1)
263 if (__seq1 <= __seq2)
273 if (__seq1 <= __seq2)
275 if (__seq0 <= __seq2)
283 #define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \
284 __s ## __a ## __b ## __c : \
285 *__target = *__seq ## __a; \
289 if (__length == 0) goto __finish; \
290 if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \
291 if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \
292 goto __s ## __b ## __c ## __a;
294 _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=);
295 _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < );
296 _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < );
297 _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=);
298 _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=);
299 _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < );
301 #undef _GLIBCXX_PARALLEL_MERGE_3_CASE
306 #if _GLIBCXX_ASSERTIONS
307 _GLIBCXX_PARALLEL_ASSERT(
308 ((_RAIter1)__seq0 - __seqs_begin[0].first) +
309 ((_RAIter1)__seq1 - __seqs_begin[1].first) +
310 ((_RAIter1)__seq2 - __seqs_begin[2].first)
314 __seqs_begin[0].first = __seq0;
315 __seqs_begin[1].first = __seq1;
316 __seqs_begin[2].first = __seq2;
347 template<
template<
typename RAI,
typename C>
class iterator,
348 typename _RAIterIterator,
350 typename _DifferenceTp,
354 _RAIterIterator __seqs_end,
356 _DifferenceTp __length, _Compare __comp)
359 typedef _DifferenceTp _DifferenceType;
361 typedef typename std::iterator_traits<_RAIterIterator>
362 ::value_type::first_type
364 typedef typename std::iterator_traits<_RAIter1>::value_type
367 iterator<_RAIter1, _Compare>
368 __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
369 __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
370 __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp),
371 __seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp);
373 #define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) { \
374 if (__seq ## __d < __seq ## __a) \
375 goto __s ## __d ## __a ## __b ## __c; \
376 if (__seq ## __d < __seq ## __b) \
377 goto __s ## __a ## __d ## __b ## __c; \
378 if (__seq ## __d < __seq ## __c) \
379 goto __s ## __a ## __b ## __d ## __c; \
380 goto __s ## __a ## __b ## __c ## __d; }
382 if (__seq0 <= __seq1)
384 if (__seq1 <= __seq2)
385 _GLIBCXX_PARALLEL_DECISION(0,1,2,3)
388 _GLIBCXX_PARALLEL_DECISION(2,0,1,3)
390 _GLIBCXX_PARALLEL_DECISION(0,2,1,3)
394 if (__seq1 <= __seq2)
396 if (__seq0 <= __seq2)
397 _GLIBCXX_PARALLEL_DECISION(1,0,2,3)
399 _GLIBCXX_PARALLEL_DECISION(1,2,0,3)
402 _GLIBCXX_PARALLEL_DECISION(2,1,0,3)
405 #define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d, \
407 __s ## __a ## __b ## __c ## __d: \
408 if (__length == 0) goto __finish; \
409 *__target = *__seq ## __a; \
413 if (__seq ## __a __c0 __seq ## __b) \
414 goto __s ## __a ## __b ## __c ## __d; \
415 if (__seq ## __a __c1 __seq ## __c) \
416 goto __s ## __b ## __a ## __c ## __d; \
417 if (__seq ## __a __c2 __seq ## __d) \
418 goto __s ## __b ## __c ## __a ## __d; \
419 goto __s ## __b ## __c ## __d ## __a;
421 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=);
422 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=);
423 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=);
424 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=);
425 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=);
426 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=);
427 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=);
428 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=);
429 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=);
430 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < );
431 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=);
432 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < );
433 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=);
434 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < );
435 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=);
436 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < );
437 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < );
438 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < );
439 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < );
440 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < );
441 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < );
442 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < );
443 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < );
444 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < );
446 #undef _GLIBCXX_PARALLEL_MERGE_4_CASE
447 #undef _GLIBCXX_PARALLEL_DECISION
452 __seqs_begin[0].first = __seq0;
453 __seqs_begin[1].first = __seq1;
454 __seqs_begin[2].first = __seq2;
455 __seqs_begin[3].first = __seq3;
478 template<
typename _LT,
479 typename _RAIterIterator,
481 typename _DifferenceTp,
485 _RAIterIterator __seqs_end,
487 _DifferenceTp __length, _Compare __comp)
491 typedef _DifferenceTp _DifferenceType;
492 typedef typename std::iterator_traits<_RAIterIterator>
493 ::difference_type _SeqNumber;
494 typedef typename std::iterator_traits<_RAIterIterator>
495 ::value_type::first_type
497 typedef typename std::iterator_traits<_RAIter1>::value_type
500 _SeqNumber __k =
static_cast<_SeqNumber
>(__seqs_end - __seqs_begin);
502 _LT __lt(__k, __comp);
505 _ValueType* __arbitrary_element = 0;
507 for (_SeqNumber __t = 0; __t < __k; ++__t)
509 if(!__arbitrary_element
511 __arbitrary_element = &(*__seqs_begin[__t].first);
514 for (_SeqNumber __t = 0; __t < __k; ++__t)
516 if (__seqs_begin[__t].first == __seqs_begin[__t].second)
517 __lt.__insert_start(*__arbitrary_element, __t,
true);
519 __lt.__insert_start(*__seqs_begin[__t].first, __t,
false);
526 for (_DifferenceType __i = 0; __i < __length; ++__i)
529 __source = __lt.__get_min_source();
531 *(__target++) = *(__seqs_begin[__source].first++);
534 if (__seqs_begin[__source].first == __seqs_begin[__source].second)
535 __lt.__delete_min_insert(*__arbitrary_element,
true);
538 __lt.__delete_min_insert(*__seqs_begin[__source].first,
false);
562 template<
typename _LT,
563 typename _RAIterIterator,
565 typename _DifferenceTp,
typename _Compare>
568 _RAIterIterator __seqs_end,
570 const typename std::iterator_traits<
typename std::iterator_traits<
571 _RAIterIterator>::value_type::first_type>::value_type&
573 _DifferenceTp __length,
577 typedef _DifferenceTp _DifferenceType;
579 typedef typename std::iterator_traits<_RAIterIterator>
580 ::difference_type _SeqNumber;
581 typedef typename std::iterator_traits<_RAIterIterator>
582 ::value_type::first_type
584 typedef typename std::iterator_traits<_RAIter1>::value_type
587 _SeqNumber __k = __seqs_end - __seqs_begin;
589 _LT __lt(__k, __sentinel, __comp);
591 for (_SeqNumber __t = 0; __t < __k; ++__t)
593 #if _GLIBCXX_ASSERTIONS
594 _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
595 != __seqs_begin[__t].second);
597 __lt.__insert_start(*__seqs_begin[__t].first, __t,
false);
604 #if _GLIBCXX_ASSERTIONS
605 _DifferenceType __i = 0;
608 _RAIter3 __target_end = __target + __length;
609 while (__target < __target_end)
612 __source = __lt.__get_min_source();
614 #if _GLIBCXX_ASSERTIONS
615 _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k);
616 _GLIBCXX_PARALLEL_ASSERT(__i == 0
617 || !__comp(*(__seqs_begin[__source].first), *(__target - 1)));
621 *(__target++) = *(__seqs_begin[__source].first++);
623 #if _GLIBCXX_ASSERTIONS
627 __lt.__delete_min_insert(*__seqs_begin[__source].first,
false);
652 template<
typename UnguardedLoserTree,
653 typename _RAIterIterator,
655 typename _DifferenceTp,
659 _RAIterIterator __seqs_end,
661 const typename std::iterator_traits<
typename std::iterator_traits<
662 _RAIterIterator>::value_type::first_type>::value_type&
664 _DifferenceTp __length,
669 typedef _DifferenceTp _DifferenceType;
670 typedef std::iterator_traits<_RAIterIterator> _TraitsType;
671 typedef typename std::iterator_traits<_RAIterIterator>
672 ::value_type::first_type
674 typedef typename std::iterator_traits<_RAIter1>::value_type
677 _RAIter3 __target_end;
679 for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
686 __target_end = multiway_merge_loser_tree_unguarded<UnguardedLoserTree>
687 (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
689 #if _GLIBCXX_ASSERTIONS
690 _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length);
691 _GLIBCXX_PARALLEL_ASSERT(
__is_sorted(__target, __target_end, __comp));
696 for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
726 template <
typename _Tp>
743 template<
bool __sentinels ,
744 typename _RAIterIterator,
746 typename _DifferenceTp,
751 operator()(_RAIterIterator __seqs_begin,
752 _RAIterIterator __seqs_end,
754 _DifferenceTp __length, _Compare __comp)
755 {
return multiway_merge_3_variant<_GuardedIterator>
756 (__seqs_begin, __seqs_end, __target, __length, __comp); }
764 template<
typename _RAIterIterator,
766 typename _DifferenceTp,
769 _RAIter3, _DifferenceTp,
773 operator()(_RAIterIterator __seqs_begin,
774 _RAIterIterator __seqs_end,
776 _DifferenceTp __length, _Compare __comp)
777 {
return multiway_merge_3_variant<_UnguardedIterator>
778 (__seqs_begin, __seqs_end, __target, __length, __comp); }
786 template<
bool __sentinels ,
787 typename _RAIterIterator,
789 typename _DifferenceTp,
794 operator()(_RAIterIterator __seqs_begin,
795 _RAIterIterator __seqs_end,
797 _DifferenceTp __length, _Compare __comp)
798 {
return multiway_merge_4_variant<_GuardedIterator>
799 (__seqs_begin, __seqs_end, __target, __length, __comp); }
807 template<
typename _RAIterIterator,
809 typename _DifferenceTp,
812 _RAIter3, _DifferenceTp,
816 operator()(_RAIterIterator __seqs_begin,
817 _RAIterIterator __seqs_end,
819 _DifferenceTp __length, _Compare __comp)
820 {
return multiway_merge_4_variant<_UnguardedIterator>
821 (__seqs_begin, __seqs_end, __target, __length, __comp); }
827 template<
bool __sentinels,
829 typename _RAIterIterator,
831 typename _DifferenceTp,
836 operator()(_RAIterIterator __seqs_begin,
837 _RAIterIterator __seqs_end,
839 const typename std::iterator_traits<
typename std::iterator_traits<
840 _RAIterIterator>::value_type::first_type>::value_type&
842 _DifferenceTp __length, _Compare __comp)
844 typedef typename std::iterator_traits<_RAIterIterator>
845 ::value_type::first_type
847 typedef typename std::iterator_traits<_RAIter1>::value_type
851 typename __gnu_cxx::__conditional_type<
856 (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
863 template<
bool __stable,
864 typename _RAIterIterator,
866 typename _DifferenceTp,
870 _RAIter3, _DifferenceTp,
874 operator()(_RAIterIterator __seqs_begin,
875 _RAIterIterator __seqs_end,
877 const typename std::iterator_traits<
typename std::iterator_traits<
878 _RAIterIterator>::value_type::first_type>::value_type&
880 _DifferenceTp __length, _Compare __comp)
882 typedef typename std::iterator_traits<_RAIterIterator>
883 ::value_type::first_type
885 typedef typename std::iterator_traits<_RAIter1>::value_type
889 typename __gnu_cxx::__conditional_type<
893 >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp);
910 template<
bool __stable,
912 typename _RAIterIterator,
914 typename _DifferenceTp,
918 _RAIterIterator __seqs_end,
920 const typename std::iterator_traits<
typename std::iterator_traits<
921 _RAIterIterator>::value_type::first_type>::value_type&
923 _DifferenceTp __length, _Compare __comp)
927 typedef _DifferenceTp _DifferenceType;
928 typedef typename std::iterator_traits<_RAIterIterator>
929 ::difference_type _SeqNumber;
930 typedef typename std::iterator_traits<_RAIterIterator>
931 ::value_type::first_type
933 typedef typename std::iterator_traits<_RAIter1>::value_type
936 #if _GLIBCXX_ASSERTIONS
937 for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
940 (*__s).second, __comp));
944 _DifferenceTp __total_length = 0;
945 for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
948 __length = std::min<_DifferenceTp>(__length, __total_length);
953 _RAIter3 __return_target = __target;
954 _SeqNumber __k =
static_cast<_SeqNumber
>(__seqs_end - __seqs_begin);
961 __return_target = std::copy(__seqs_begin[0].first,
962 __seqs_begin[0].first + __length,
964 __seqs_begin[0].first += __length;
968 __seqs_begin[0].second,
969 __seqs_begin[1].first,
970 __seqs_begin[1].second,
971 __target, __length, __comp);
975 <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
976 (__seqs_begin, __seqs_end, __target, __length, __comp);
980 <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
981 (__seqs_begin, __seqs_end, __target, __length, __comp);
985 <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp,
987 (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
990 #if _GLIBCXX_ASSERTIONS
991 _GLIBCXX_PARALLEL_ASSERT(
992 __is_sorted(__target, __target + __length, __comp));
995 return __return_target;
1003 template<
bool __stable,
class _RAIter,
class _StrictWeakOrdering>
1007 operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
1008 { __gnu_sequential::stable_sort(__first, __last, __comp); }
1016 template<
class _RAIter,
class _StrictWeakOrdering>
1020 operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
1021 { __gnu_sequential::sort(__first, __last, __comp); }
1027 template<
bool __stable,
1028 typename _RAIterIterator,
1030 typename _DifferenceType>
1033 _RAIterIterator __seqs_end,
1034 _DifferenceType __length,
1035 _DifferenceType __total_length,
1039 typedef typename std::iterator_traits<_RAIterIterator>
1040 ::difference_type _SeqNumber;
1041 typedef typename std::iterator_traits<_RAIterIterator>
1042 ::value_type::first_type
1044 typedef typename std::iterator_traits<_RAIter1>::value_type
1048 const _SeqNumber __k
1049 =
static_cast<_SeqNumber
>(__seqs_end - __seqs_begin);
1051 const _ThreadIndex __num_threads = omp_get_num_threads();
1053 const _DifferenceType __num_samples =
1056 _ValueType* __samples =
static_cast<_ValueType*
>
1057 (::operator
new(
sizeof(_ValueType) * __k * __num_samples));
1059 for (_SeqNumber __s = 0; __s < __k; ++__s)
1060 for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
1062 _DifferenceType sample_index =
static_cast<_DifferenceType
>
1064 * (double(__i + 1) / (__num_samples + 1))
1065 * (double(__length) / __total_length));
1066 new(&(__samples[__s * __num_samples + __i]))
1067 _ValueType(__seqs_begin[__s].first[sample_index]);
1073 (__samples, __samples + (__num_samples * __k), __comp);
1075 for (
_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
1077 for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
1081 __pieces[__slab][__seq].first = std::upper_bound
1082 (__seqs_begin[__seq].first, __seqs_begin[__seq].second,
1083 __samples[__num_samples * __k * __slab / __num_threads],
1085 - __seqs_begin[__seq].first;
1088 __pieces[__slab][__seq].first = 0;
1089 if ((__slab + 1) < __num_threads)
1090 __pieces[__slab][__seq].second = std::upper_bound
1091 (__seqs_begin[__seq].first, __seqs_begin[__seq].second,
1092 __samples[__num_samples * __k * (__slab + 1) / __num_threads],
1094 - __seqs_begin[__seq].first;
1097 __pieces[__slab][__seq].second =
1101 for (_SeqNumber __s = 0; __s < __k; ++__s)
1102 for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
1103 __samples[__s * __num_samples + __i].~_ValueType();
1104 ::operator
delete(__samples);
1112 template<
bool __stable,
1113 typename _RAIterIterator,
1115 typename _DifferenceType>
1118 _RAIterIterator __seqs_end,
1119 _DifferenceType __length,
1120 _DifferenceType __total_length,
1124 typedef typename std::iterator_traits<_RAIterIterator>
1125 ::difference_type _SeqNumber;
1126 typedef typename std::iterator_traits<_RAIterIterator>
1127 ::value_type::first_type
1130 const bool __tight = (__total_length == __length);
1133 const _SeqNumber __k = __seqs_end - __seqs_begin;
1135 const _ThreadIndex __num_threads = omp_get_num_threads();
1143 copy(__seqs_begin, __seqs_end, __se.
begin());
1145 _DifferenceType* __borders =
1146 new _DifferenceType[__num_threads + 1];
1149 for (
_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s)
1151 __offsets[__s].
resize(__k);
1153 __offsets[__s].
begin(), __comp);
1158 __offsets[__num_threads - 1].
resize(__k);
1160 _DifferenceType(__length),
1161 __offsets[__num_threads - 1].
begin(),
1167 for (
_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
1170 for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
1176 __pieces[__slab][__seq].first = 0;
1179 __pieces[__slab][__seq].first =
1180 __pieces[__slab - 1][__seq].second;
1181 if (!__tight || __slab < (__num_threads - 1))
1182 __pieces[__slab][__seq].second =
1183 __offsets[__slab][__seq] - __seqs_begin[__seq].first;
1187 __pieces[__slab][__seq].second =
1214 template<
bool __stable,
1216 typename _RAIterIterator,
1218 typename _DifferenceTp,
1223 _RAIterIterator __seqs_end,
1225 _Splitter __splitter,
1226 _DifferenceTp __length,
1230 #if _GLIBCXX_ASSERTIONS
1231 _GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1);
1236 typedef _DifferenceTp _DifferenceType;
1237 typedef typename std::iterator_traits<_RAIterIterator>
1238 ::difference_type _SeqNumber;
1239 typedef typename std::iterator_traits<_RAIterIterator>
1240 ::value_type::first_type
1243 std::iterator_traits<_RAIter1>::value_type _ValueType;
1247 seq_type* __ne_seqs =
new seq_type[__seqs_end - __seqs_begin];
1249 _DifferenceType __total_length = 0;
1250 for (_RAIterIterator __raii = __seqs_begin;
1251 __raii != __seqs_end; ++__raii)
1254 if(__seq_length > 0)
1256 __total_length += __seq_length;
1257 __ne_seqs[__k++] = *__raii;
1263 __length = std::min<_DifferenceTp>(__length, __total_length);
1265 if (__total_length == 0 || __k == 0)
1274 (std::min<_DifferenceType>(__num_threads, __total_length));
1276 # pragma omp parallel num_threads (__num_threads)
1280 __num_threads = omp_get_num_threads();
1285 __pieces[__s].resize(__k);
1287 _DifferenceType __num_samples =
1291 __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length,
1297 _DifferenceType __target_position = 0;
1299 for (_SeqNumber __c = 0; __c < __k; ++__c)
1300 __target_position += __pieces[__iam][__c].first;
1302 seq_type* __chunks =
new seq_type[__k];
1304 for (_SeqNumber __s = 0; __s < __k; ++__s)
1306 + __pieces[__iam][__s].first,
1307 __ne_seqs[__s].first
1308 + __pieces[__iam][__s].second);
1310 if(__length > __target_position)
1311 __sequential_multiway_merge<__stable, __sentinels>
1312 (__chunks, __chunks + __k, __target + __target_position,
1313 *(__seqs_begin->second), __length - __target_position, __comp);
1318 #if _GLIBCXX_ASSERTIONS
1319 _GLIBCXX_PARALLEL_ASSERT(
1320 __is_sorted(__target, __target + __length, __comp));
1325 for (_RAIterIterator __raii = __seqs_begin;
1326 __raii != __seqs_end; ++__raii)
1330 (*__raii).first += __pieces[__num_threads - 1][__k++].second;
1336 return __target + __length;
1410 template<
typename _RAIterPairIterator,
1411 typename _RAIterOut,
1412 typename _DifferenceTp,
1416 _RAIterPairIterator __seqs_end,
1417 _RAIterOut __target,
1418 _DifferenceTp __length, _Compare __comp,
1421 typedef _DifferenceTp _DifferenceType;
1425 if (__seqs_begin == __seqs_end)
1431 (__seqs_begin, __seqs_end, __target,
1432 *(__seqs_begin->second), __length, __comp);
1436 template<
typename _RAIterPairIterator,
1437 typename _RAIterOut,
1438 typename _DifferenceTp,
1442 _RAIterPairIterator __seqs_end,
1443 _RAIterOut __target,
1444 _DifferenceTp __length, _Compare __comp,
1447 typedef _DifferenceTp _DifferenceType;
1451 if (__seqs_begin == __seqs_end)
1457 if ((__seqs_end - __seqs_begin > 1)
1459 ((__seqs_end - __seqs_begin) >=
1460 __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1462 __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1465 (__seqs_begin, __seqs_end, __target,
1467 typename std::iterator_traits<_RAIterPairIterator>
1468 ::value_type*, _Compare, _DifferenceTp>,
1469 static_cast<_DifferenceType>(__length), __comp,
1470 __tag.__get_num_threads());
1474 (__seqs_begin, __seqs_end, __target,
1475 *(__seqs_begin->second), __length, __comp);
1479 template<typename _RAIterPairIterator,
1480 typename _RAIterOut,
1481 typename _DifferenceTp,
1485 _RAIterPairIterator __seqs_end,
1486 _RAIterOut __target,
1487 _DifferenceTp __length, _Compare __comp,
1488 __gnu_parallel::sampling_tag __tag)
1490 typedef _DifferenceTp _DifferenceType;
1494 if (__seqs_begin == __seqs_end)
1500 if ((__seqs_end - __seqs_begin > 1)
1502 ((__seqs_end - __seqs_begin) >=
1503 __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1505 __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1508 (__seqs_begin, __seqs_end, __target,
1510 typename std::iterator_traits<_RAIterPairIterator>
1511 ::value_type*, _Compare, _DifferenceTp>,
1512 static_cast<_DifferenceType>(__length), __comp,
1513 __tag.__get_num_threads());
1517 (__seqs_begin, __seqs_end, __target,
1518 *(__seqs_begin->second), __length, __comp);
1522 template<typename _RAIterPairIterator,
1523 typename _RAIterOut,
1524 typename _DifferenceTp,
1528 _RAIterPairIterator __seqs_end,
1529 _RAIterOut __target,
1530 _DifferenceTp __length, _Compare __comp,
1531 parallel_tag __tag = parallel_tag(0))
1532 {
return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
1533 __comp, exact_tag(__tag.__get_num_threads())); }
1536 template<
typename _RAIterPairIterator,
1537 typename _RAIterOut,
1538 typename _DifferenceTp,
1542 _RAIterPairIterator __seqs_end,
1543 _RAIterOut __target,
1544 _DifferenceTp __length, _Compare __comp,
1545 default_parallel_tag __tag)
1546 {
return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
1547 __comp, exact_tag(__tag.__get_num_threads())); }
1551 template<
typename _RAIterPairIterator,
1552 typename _RAIterOut,
1553 typename _DifferenceTp,
1556 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1557 _RAIterPairIterator __seqs_end,
1558 _RAIterOut __target,
1559 _DifferenceTp __length, _Compare __comp,
1562 typedef _DifferenceTp _DifferenceType;
1566 if (__seqs_begin == __seqs_end)
1572 (__seqs_begin, __seqs_end, __target,
1573 *(__seqs_begin->second), __length, __comp);
1577 template<typename _RAIterPairIterator,
1578 typename _RAIterOut,
1579 typename _DifferenceTp,
1582 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1583 _RAIterPairIterator __seqs_end,
1584 _RAIterOut __target,
1585 _DifferenceTp __length, _Compare __comp,
1586 __gnu_parallel::exact_tag __tag)
1588 typedef _DifferenceTp _DifferenceType;
1592 if (__seqs_begin == __seqs_end)
1598 if ((__seqs_end - __seqs_begin > 1)
1600 ((__seqs_end - __seqs_begin) >=
1601 __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1603 __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1606 (__seqs_begin, __seqs_end, __target,
1608 typename std::iterator_traits<_RAIterPairIterator>
1609 ::value_type*, _Compare, _DifferenceTp>,
1610 static_cast<_DifferenceType>(__length), __comp,
1611 __tag.__get_num_threads());
1615 (__seqs_begin, __seqs_end, __target,
1616 *(__seqs_begin->second), __length, __comp);
1620 template<typename _RAIterPairIterator,
1621 typename _RAIterOut,
1622 typename _DifferenceTp,
1625 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1626 _RAIterPairIterator __seqs_end,
1627 _RAIterOut __target,
1628 _DifferenceTp __length, _Compare __comp,
1631 typedef _DifferenceTp _DifferenceType;
1635 if (__seqs_begin == __seqs_end)
1641 if ((__seqs_end - __seqs_begin > 1)
1643 ((__seqs_end - __seqs_begin) >=
1644 __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1646 __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1649 (__seqs_begin, __seqs_end, __target,
1651 typename std::iterator_traits<_RAIterPairIterator>
1652 ::value_type*, _Compare, _DifferenceTp>,
1653 static_cast<_DifferenceType>(__length), __comp,
1654 __tag.__get_num_threads());
1658 (__seqs_begin, __seqs_end, __target,
1659 *(__seqs_begin->second), __length, __comp);
1663 template<typename _RAIterPairIterator,
1664 typename _RAIterOut,
1665 typename _DifferenceTp,
1668 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1669 _RAIterPairIterator __seqs_end,
1670 _RAIterOut __target,
1671 _DifferenceTp __length, _Compare __comp,
1672 parallel_tag __tag = parallel_tag(0))
1674 return stable_multiway_merge
1675 (__seqs_begin, __seqs_end, __target, __length, __comp,
1676 exact_tag(__tag.__get_num_threads()));
1680 template<
typename _RAIterPairIterator,
1681 typename _RAIterOut,
1682 typename _DifferenceTp,
1685 stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1686 _RAIterPairIterator __seqs_end,
1687 _RAIterOut __target,
1688 _DifferenceTp __length, _Compare __comp,
1689 default_parallel_tag __tag)
1691 return stable_multiway_merge
1692 (__seqs_begin, __seqs_end, __target, __length, __comp,
1693 exact_tag(__tag.__get_num_threads()));
1774 template<
typename _RAIterPairIterator,
1775 typename _RAIterOut,
1776 typename _DifferenceTp,
1780 _RAIterPairIterator __seqs_end,
1781 _RAIterOut __target,
1782 _DifferenceTp __length, _Compare __comp,
1785 typedef _DifferenceTp _DifferenceType;
1789 if (__seqs_begin == __seqs_end)
1795 (__seqs_begin, __seqs_end,
1796 __target, *(__seqs_begin->second), __length, __comp);
1800 template<
typename _RAIterPairIterator,
1801 typename _RAIterOut,
1802 typename _DifferenceTp,
1806 _RAIterPairIterator __seqs_end,
1807 _RAIterOut __target,
1808 _DifferenceTp __length, _Compare __comp,
1811 typedef _DifferenceTp _DifferenceType;
1815 if (__seqs_begin == __seqs_end)
1821 if ((__seqs_end - __seqs_begin > 1)
1823 ((__seqs_end - __seqs_begin) >=
1824 __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1826 __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1829 (__seqs_begin, __seqs_end, __target,
1831 typename std::iterator_traits<_RAIterPairIterator>
1832 ::value_type*, _Compare, _DifferenceTp>,
1833 static_cast<_DifferenceType>(__length), __comp,
1834 __tag.__get_num_threads());
1838 (__seqs_begin, __seqs_end, __target,
1839 *(__seqs_begin->second), __length, __comp);
1843 template<typename _RAIterPairIterator,
1844 typename _RAIterOut,
1845 typename _DifferenceTp,
1849 _RAIterPairIterator __seqs_end,
1850 _RAIterOut __target,
1851 _DifferenceTp __length, _Compare __comp,
1854 typedef _DifferenceTp _DifferenceType;
1858 if (__seqs_begin == __seqs_end)
1864 if ((__seqs_end - __seqs_begin > 1)
1866 ((__seqs_end - __seqs_begin) >=
1867 __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1869 __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1872 (__seqs_begin, __seqs_end, __target,
1874 typename std::iterator_traits<_RAIterPairIterator>
1875 ::value_type*, _Compare, _DifferenceTp>,
1876 static_cast<_DifferenceType>(__length), __comp,
1877 __tag.__get_num_threads());
1881 __seqs_begin, __seqs_end, __target,
1882 *(__seqs_begin->second), __length, __comp);
1886 template<typename _RAIterPairIterator,
1887 typename _RAIterOut,
1888 typename _DifferenceTp,
1892 _RAIterPairIterator __seqs_end,
1893 _RAIterOut __target,
1894 _DifferenceTp __length, _Compare __comp,
1895 parallel_tag __tag = parallel_tag(0))
1898 (__seqs_begin, __seqs_end, __target, __length, __comp,
1899 exact_tag(__tag.__get_num_threads()));
1903 template<
typename _RAIterPairIterator,
1904 typename _RAIterOut,
1905 typename _DifferenceTp,
1909 _RAIterPairIterator __seqs_end,
1910 _RAIterOut __target,
1911 _DifferenceTp __length, _Compare __comp,
1912 default_parallel_tag __tag)
1915 (__seqs_begin, __seqs_end, __target, __length, __comp,
1916 exact_tag(__tag.__get_num_threads()));
1921 template<
typename _RAIterPairIterator,
1922 typename _RAIterOut,
1923 typename _DifferenceTp,
1926 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1927 _RAIterPairIterator __seqs_end,
1928 _RAIterOut __target,
1929 _DifferenceTp __length, _Compare __comp,
1932 typedef _DifferenceTp _DifferenceType;
1936 if (__seqs_begin == __seqs_end)
1942 (__seqs_begin, __seqs_end, __target,
1943 *(__seqs_begin->second), __length, __comp);
1947 template<typename _RAIterPairIterator,
1948 typename _RAIterOut,
1949 typename _DifferenceTp,
1952 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1953 _RAIterPairIterator __seqs_end,
1954 _RAIterOut __target,
1955 _DifferenceTp __length, _Compare __comp,
1956 __gnu_parallel::exact_tag __tag)
1958 typedef _DifferenceTp _DifferenceType;
1962 if (__seqs_begin == __seqs_end)
1968 if ((__seqs_end - __seqs_begin > 1)
1970 ((__seqs_end - __seqs_begin) >=
1971 __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1973 __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1976 (__seqs_begin, __seqs_end, __target,
1978 typename std::iterator_traits<_RAIterPairIterator>
1979 ::value_type*, _Compare, _DifferenceTp>,
1980 static_cast<_DifferenceType>(__length), __comp,
1981 __tag.__get_num_threads());
1985 (__seqs_begin, __seqs_end, __target,
1986 *(__seqs_begin->second), __length, __comp);
1990 template<typename _RAIterPairIterator,
1991 typename _RAIterOut,
1992 typename _DifferenceTp,
1995 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1996 _RAIterPairIterator __seqs_end,
1997 _RAIterOut __target,
1998 _DifferenceTp __length,
2002 typedef _DifferenceTp _DifferenceType;
2006 if (__seqs_begin == __seqs_end)
2012 if ((__seqs_end - __seqs_begin > 1)
2014 ((__seqs_end - __seqs_begin) >=
2015 __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
2017 __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
2020 (__seqs_begin, __seqs_end, __target,
2022 typename std::iterator_traits<_RAIterPairIterator>
2023 ::value_type*, _Compare, _DifferenceTp>,
2024 static_cast<_DifferenceType>(__length), __comp,
2025 __tag.__get_num_threads());
2029 (__seqs_begin, __seqs_end, __target,
2030 *(__seqs_begin->second), __length, __comp);
2034 template<typename _RAIterPairIterator,
2035 typename _RAIterOut,
2036 typename _DifferenceTp,
2039 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
2040 _RAIterPairIterator __seqs_end,
2041 _RAIterOut __target,
2042 _DifferenceTp __length,
2044 parallel_tag __tag = parallel_tag(0))
2046 return stable_multiway_merge_sentinels
2047 (__seqs_begin, __seqs_end, __target, __length, __comp,
2048 exact_tag(__tag.__get_num_threads()));
2052 template<
typename _RAIterPairIterator,
2053 typename _RAIterOut,
2054 typename _DifferenceTp,
2057 stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
2058 _RAIterPairIterator __seqs_end,
2059 _RAIterOut __target,
2060 _DifferenceTp __length, _Compare __comp,
2061 default_parallel_tag __tag)
2063 return stable_multiway_merge_sentinels
2064 (__seqs_begin, __seqs_end, __target, __length, __comp,
2065 exact_tag(__tag.__get_num_threads()));
static const _Settings & get()
Get the global settings.
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.
_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.
Routines for checking the correctness of algorithm results. This file is a GNU parallel extension to ...
static const bool _M_use_pointer
True iff to use pointers instead of values in loser trees.
Struct holding two objects of arbitrary type.
Forces parallel merging with exact splitting, at compile time.
_GuardedIterator< _RAIter, _Compare > & operator++()
Pre-increment operator.
Stable implementation of unguarded _LoserTree.
#define _GLIBCXX_PARALLEL_LENGTH(__s)
Length of a sequence described by a pair of iterators.
uint16_t _ThreadIndex
Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit in...
_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.
_RAIter3 multiway_merge_4_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp)
Highly efficient 4-way merging procedure.
_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.
_OutputIterator equally_split(_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s)
function to split a sequence into parts of almost equal size.
Forces sequential execution at compile time.
_RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag)
Multiway Merge Frontend.
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
End-user include file. Provides advanced settings and tuning options. This file is a GNU parallel ext...
Defines on whether to include algorithm variants.
Traits for determining whether the loser tree should use pointers or copies.
_RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag)
Multiway Merge Frontend.
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.
Switch for 3-way merging with __sentinels turned off.
_RAIter3 multiway_merge_3_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp)
Highly efficient 3-way merging procedure.
std::iterator_traits< _RAIter >::value_type & operator*()
Dereference operator.
Many generic loser tree variants. This file is a GNU parallel extension to the Standard C++ Library...
_GuardedIterator(_RAIter __begin, _RAIter __end, _Compare &__comp)
Constructor. Sets iterator to beginning of sequence.
Stable _LoserTree variant.
#define _GLIBCXX_PARALLEL_CONDITION(__c)
Determine at compile(?)-time if the parallel variant of an algorithm should be called.
_Iterator wrapper supporting an implicit supremum at the end of the sequence, dominating all comparis...
void resize(size_type __new_size)
Resizes the vector to the specified number of elements.
A standard container which offers fixed time access to individual elements in any order...
Switch for k-way merging with __sentinels turned on.
Stable unguarded _LoserTree variant storing pointers.
Switch for 4-way merging with __sentinels turned off.
bool __is_sorted(_IIter __begin, _IIter __end, _Compare __comp)
Check whether [__begin, __end) is sorted according to __comp.
_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.
_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.
uint64_t _SequenceIndex
Unsigned integer to index __elements. The total number of elements for each algorithm must fit into t...
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.
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...
unsigned int merge_oversampling
Oversampling factor for merge.
Stable _LoserTree implementation.
_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.