41 #ifndef _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H
42 #define _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H 1
51 namespace __gnu_parallel
54 template<
typename _T1,
typename _T2,
typename _Compare>
57 std::pair<_T1, _T2>, bool>
81 template<
typename _T1,
typename _T2,
typename _Compare>
121 template<
typename _RanSeqs,
typename _RankType,
typename _RankIterator,
126 _RankIterator __begin_offsets,
128 typename std::iterator_traits<
typename
129 std::iterator_traits<_RanSeqs>::value_type::
130 first_type>::value_type>())
134 typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type
136 typedef typename std::iterator_traits<_RanSeqs>::difference_type
138 typedef typename std::iterator_traits<_It>::difference_type
140 typedef typename std::iterator_traits<_It>::value_type _ValueType;
147 _DifferenceType __m =
std::distance(__begin_seqs, __end_seqs), __nn = 0,
150 for (_SeqNumber __i = 0; __i < __m; __i++)
153 __begin_seqs[__i].second);
154 _GLIBCXX_PARALLEL_ASSERT(
156 __begin_seqs[__i].second) > 0);
161 for (_SeqNumber __i = 0; __i < __m; __i++)
162 __begin_offsets[__i] = __begin_seqs[__i].second;
167 _GLIBCXX_PARALLEL_ASSERT(__m != 0);
168 _GLIBCXX_PARALLEL_ASSERT(__nn != 0);
169 _GLIBCXX_PARALLEL_ASSERT(__rank >= 0);
170 _GLIBCXX_PARALLEL_ASSERT(__rank < __nn);
172 _DifferenceType* __ns =
new _DifferenceType[__m];
173 _DifferenceType* __a =
new _DifferenceType[__m];
174 _DifferenceType* __b =
new _DifferenceType[__m];
177 __ns[0] =
std::distance(__begin_seqs[0].first, __begin_seqs[0].second);
179 for (_SeqNumber __i = 0; __i < __m; __i++)
182 __begin_seqs[__i].second);
183 __nmax =
std::max(__nmax, __ns[__i]);
190 __l = (1ULL << __r) - 1;
192 for (_SeqNumber __i = 0; __i < __m; __i++)
202 #define __S(__i) (__begin_seqs[__i].first)
207 for (_SeqNumber __i = 0; __i < __m; __i++)
210 __gnu_sequential::sort(__sample.
begin(), __sample.
end(), __lcomp);
212 for (_SeqNumber __i = 0; __i < __m; __i++)
213 if (__n >= __ns[__i])
217 _DifferenceType __localrank = __rank / __l;
221 __j < __localrank && ((__n + 1) <= __ns[__sample[__j].second]);
223 __a[__sample[__j].second] += __n + 1;
224 for (; __j < __m; __j++)
225 __b[__sample[__j].second] -= __n + 1;
232 _SeqNumber __lmax_seq = -1;
233 const _ValueType* __lmax = 0;
234 for (_SeqNumber __i = 0; __i < __m; __i++)
240 __lmax = &(__S(__i)[__a[__i] - 1]);
246 if (!__comp(__S(__i)[__a[__i] - 1], *__lmax))
248 __lmax = &(__S(__i)[__a[__i] - 1]);
256 for (__i = 0; __i < __m; __i++)
258 _DifferenceType __middle = (__b[__i] + __a[__i]) / 2;
259 if (__lmax && __middle < __ns[__i] &&
262 __a[__i] =
std::min(__a[__i] + __n + 1, __ns[__i]);
267 _DifferenceType __leftsize = 0;
268 for (_SeqNumber __i = 0; __i < __m; __i++)
269 __leftsize += __a[__i] / (__n + 1);
271 _DifferenceType __skew = __rank / (__n + 1) - __leftsize;
281 for (_SeqNumber __i = 0; __i < __m; __i++)
282 if (__b[__i] < __ns[__i])
285 for (; __skew != 0 && !__pq.
empty(); --__skew)
287 _SeqNumber __source = __pq.
top().second;
291 =
std::min(__a[__source] + __n + 1, __ns[__source]);
292 __b[__source] += __n + 1;
294 if (__b[__source] < __ns[__source])
307 for (_SeqNumber __i = 0; __i < __m; __i++)
311 for (; __skew != 0; ++__skew)
313 _SeqNumber __source = __pq.
top().second;
316 __a[__source] -= __n + 1;
317 __b[__source] -= __n + 1;
319 if (__a[__source] > 0)
321 __S(__source)[__a[__source] - 1], __source));
335 _ValueType* __maxleft = 0;
336 _ValueType* __minright = 0;
337 for (_SeqNumber __i = 0; __i < __m; __i++)
342 __maxleft = &(__S(__i)[__a[__i] - 1]);
346 if (!__comp(__S(__i)[__a[__i] - 1], *__maxleft))
347 __maxleft = &(__S(__i)[__a[__i] - 1]);
350 if (__b[__i] < __ns[__i])
353 __minright = &(__S(__i)[__b[__i]]);
357 if (__comp(__S(__i)[__b[__i]], *__minright))
358 __minright = &(__S(__i)[__b[__i]]);
363 _SeqNumber __seq = 0;
364 for (_SeqNumber __i = 0; __i < __m; __i++)
365 __begin_offsets[__i] = __S(__i) + __a[__i];
387 template<
typename _Tp,
typename _RanSeqs,
typename _RankType,
396 typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type
398 typedef typename std::iterator_traits<_RanSeqs>::difference_type
400 typedef typename std::iterator_traits<_It>::difference_type
408 _DifferenceType __m =
std::distance(__begin_seqs, __end_seqs);
409 _DifferenceType __nn = 0;
410 _DifferenceType __nmax, __n, __r;
412 for (_SeqNumber __i = 0; __i < __m; __i++)
414 __begin_seqs[__i].second);
416 if (__m == 0 || __nn == 0 || __rank < 0 || __rank >= __nn)
423 _DifferenceType* __ns =
new _DifferenceType[__m];
424 _DifferenceType* __a =
new _DifferenceType[__m];
425 _DifferenceType* __b =
new _DifferenceType[__m];
428 __ns[0] =
std::distance(__begin_seqs[0].first, __begin_seqs[0].second);
430 for (_SeqNumber __i = 0; __i < __m; ++__i)
433 __begin_seqs[__i].second);
434 __nmax =
std::max(__nmax, __ns[__i]);
443 for (_SeqNumber __i = 0; __i < __m; ++__i)
453 #define __S(__i) (__begin_seqs[__i].first)
458 for (_SeqNumber __i = 0; __i < __m; __i++)
461 __gnu_sequential::sort(__sample.
begin(), __sample.
end(),
465 for (_SeqNumber __i = 0; __i < __m; __i++)
466 if (__n >= __ns[__i])
470 _DifferenceType __localrank = __rank / __l;
474 __j < __localrank && ((__n + 1) <= __ns[__sample[__j].second]);
476 __a[__sample[__j].second] += __n + 1;
477 for (; __j < __m; ++__j)
478 __b[__sample[__j].second] -= __n + 1;
485 const _Tp* __lmax = 0;
486 for (_SeqNumber __i = 0; __i < __m; ++__i)
491 __lmax = &(__S(__i)[__a[__i] - 1]);
494 if (__comp(*__lmax, __S(__i)[__a[__i] - 1]))
495 __lmax = &(__S(__i)[__a[__i] - 1]);
501 for (__i = 0; __i < __m; __i++)
503 _DifferenceType __middle = (__b[__i] + __a[__i]) / 2;
504 if (__lmax && __middle < __ns[__i]
505 && __comp(__S(__i)[__middle], *__lmax))
506 __a[__i] =
std::min(__a[__i] + __n + 1, __ns[__i]);
511 _DifferenceType __leftsize = 0;
512 for (_SeqNumber __i = 0; __i < __m; ++__i)
513 __leftsize += __a[__i] / (__n + 1);
515 _DifferenceType __skew = __rank / (__n + 1) - __leftsize;
525 for (_SeqNumber __i = 0; __i < __m; ++__i)
526 if (__b[__i] < __ns[__i])
529 for (; __skew != 0 && !__pq.
empty(); --__skew)
531 _SeqNumber __source = __pq.
top().second;
535 =
std::min(__a[__source] + __n + 1, __ns[__source]);
536 __b[__source] += __n + 1;
538 if (__b[__source] < __ns[__source])
550 for (_SeqNumber __i = 0; __i < __m; ++__i)
554 for (; __skew != 0; ++__skew)
556 _SeqNumber __source = __pq.
top().second;
559 __a[__source] -= __n + 1;
560 __b[__source] -= __n + 1;
562 if (__a[__source] > 0)
564 __S(__source)[__a[__source] - 1], __source));
578 bool __maxleftset =
false, __minrightset =
false;
581 _Tp __maxleft, __minright;
582 for (_SeqNumber __i = 0; __i < __m; ++__i)
588 __maxleft = __S(__i)[__a[__i] - 1];
594 if (__comp(__maxleft, __S(__i)[__a[__i] - 1]))
595 __maxleft = __S(__i)[__a[__i] - 1];
598 if (__b[__i] < __ns[__i])
602 __minright = __S(__i)[__b[__i]];
603 __minrightset =
true;
608 if (__comp(__S(__i)[__b[__i]], __minright))
609 __minright = __S(__i)[__b[__i]];
616 if (!__maxleftset || __comp(__minright, __maxleft))
626 for (_SeqNumber __i = 0; __i < __m; ++__i)
629 = std::lower_bound(__S(__i), __S(__i) + __ns[__i],
632 __offset += __a[__i] - lb;
_Tp __round_up_to_pow2(_Tp __x)
Round up to the next greater power of 2.
void pop()
Removes first element.
Struct holding two objects of arbitrary type.
_T1 first
second_type is the second bound type
Compare __a pair of types lexicographically, ascending.
void push_back(const value_type &__x)
Add data to the end of the vector.
const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
Forces sequential execution at compile time.
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
Parallel sorting algorithm switch. This file is a GNU parallel extension to the Standard C++ Library...
_Tp multiseq_selection(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankType &__offset, _Compare __comp=std::less< _Tp >())
Selects the element at a certain global __rank from several sorted sequences.
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.
_Size __rd_log2(_Size __n)
Calculates the rounded-down logarithm of __n for base 2.
iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
A standard container which offers fixed time access to individual elements in any order...
One of the comparison functors.
Base class for all library exceptions.
const_reference top() const
A standard container automatically sorting its contents.
const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
Compare __a pair of types lexicographically, descending.
void push(const value_type &__x)
Add data to the queue.
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...
_T2 second
first is a copy of the first object