2008-04-23 Johannes Singler <singler@ira.uka.de>

* include/parallel/multiway_merge.h
        (multiway_merge_loser_tree):
        Leave checks to callers, add precondition instead.
        (multiway_merge_loser_tree_unguarded): Likewise.
        (multiway_merge_loser_tree_sentinel): Likewise.
        (sequential_multiway_merge): Added checks for total length 0.
        (parallel_multiway_merge): Skip empty sequences.
        (multiway_merge, all variants):
        Remove temporary variable, return directly.
        (stable_multiway_merge, all variants): Likewise.
        (multiway_merge_sentinels, all variants):  Likewise.
        (stable_multiway_merge_sentinels, all variants): Likewise.
        * include/parallel/multiseq_selection.h
        (multiseq_partition): More detailed assertions.

From-SVN: r134580
This commit is contained in:
Johannes Singler 2008-04-23 07:20:58 +00:00 committed by Johannes Singler
parent 7edc89d4c1
commit 214ece2920
3 changed files with 180 additions and 162 deletions

View file

@ -1,3 +1,20 @@
2008-04-23 Johannes Singler <singler@ira.uka.de>
* include/parallel/multiway_merge.h
(multiway_merge_loser_tree):
Leave checks to callers, add precondition instead.
(multiway_merge_loser_tree_unguarded): Likewise.
(multiway_merge_loser_tree_sentinel): Likewise.
(sequential_multiway_merge): Added checks for total length 0.
(parallel_multiway_merge): Skip empty sequences.
(multiway_merge, all variants):
Remove temporary variable, return directly.
(stable_multiway_merge, all variants): Likewise.
(multiway_merge_sentinels, all variants): Likewise.
(stable_multiway_merge_sentinels, all variants): Likewise.
* include/parallel/multiseq_selection.h
(multiseq_partition): More detailed assertions.
2008-04-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* acinclude.m4 (GLIBCXX_CHECK_SETRLIMIT, GLIBCXX_ENABLE_C99)

View file

@ -124,22 +124,22 @@ namespace __gnu_parallel
* @param comp The ordering functor, defaults to std::less<T>.
*/
template<typename RanSeqs, typename RankType, typename RankIterator,
typename Comparator>
typename Comparator>
void
multiseq_partition(RanSeqs begin_seqs, RanSeqs end_seqs,
RankType rank,
RankIterator begin_offsets,
Comparator comp = std::less<
typename std::iterator_traits<typename
std::iterator_traits<RanSeqs>::value_type::
first_type>::value_type>()) // std::less<T>
RankType rank,
RankIterator begin_offsets,
Comparator comp = std::less<
typename std::iterator_traits<typename
std::iterator_traits<RanSeqs>::value_type::
first_type>::value_type>()) // std::less<T>
{
_GLIBCXX_CALL(end_seqs - begin_seqs)
typedef typename std::iterator_traits<RanSeqs>::value_type::first_type
It;
It;
typedef typename std::iterator_traits<It>::difference_type
difference_type;
difference_type;
typedef typename std::iterator_traits<It>::value_type value_type;
lexicographic<value_type, int, Comparator> lcomp(comp);
@ -148,19 +148,27 @@ namespace __gnu_parallel
// Number of sequences, number of elements in total (possibly
// including padding).
difference_type m = std::distance(begin_seqs, end_seqs), N = 0,
nmax, n, r;
nmax, n, r;
for (int i = 0; i < m; i++)
N += std::distance(begin_seqs[i].first, begin_seqs[i].second);
{
N += std::distance(begin_seqs[i].first, begin_seqs[i].second);
_GLIBCXX_PARALLEL_ASSERT(
std::distance(begin_seqs[i].first, begin_seqs[i].second) > 0);
}
if (rank == N)
{
for (int i = 0; i < m; i++)
begin_offsets[i] = begin_seqs[i].second; // Very end.
// Return m - 1;
}
{
for (int i = 0; i < m; i++)
begin_offsets[i] = begin_seqs[i].second; // Very end.
// Return m - 1;
return;
}
_GLIBCXX_PARALLEL_ASSERT(m != 0 && N != 0 && rank >= 0 && rank < N);
_GLIBCXX_PARALLEL_ASSERT(m != 0);
_GLIBCXX_PARALLEL_ASSERT(N != 0);
_GLIBCXX_PARALLEL_ASSERT(rank >= 0);
_GLIBCXX_PARALLEL_ASSERT(rank < N);
difference_type* ns = new difference_type[m];
difference_type* a = new difference_type[m];

View file

@ -282,7 +282,8 @@ template<typename RandomAccessIterator, typename Comparator>
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param comp Comparator.
* @param length Maximum length to merge.
* @param length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
@ -401,7 +402,8 @@ template<template<typename RAI, typename C> class iterator,
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param comp Comparator.
* @param length Maximum length to merge.
* @param length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
@ -518,11 +520,14 @@ template<template<typename RAI, typename C> class iterator,
*
* Stability is selected through the used LoserTree class <tt>LT</tt>.
*
* At least one non-empty sequence is required.
*
* @param seqs_begin Begin iterator of iterator pair input sequence.
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param comp Comparator.
* @param length Maximum length to merge.
* @param length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
@ -551,22 +556,16 @@ template<typename LT,
LT lt(k, comp);
difference_type total_length = 0;
// Default value for potentially non-default-constructible types.
value_type* arbitrary_element = NULL;
for (int t = 0; t < k; ++t)
{
if(arbitrary_element == NULL
&& _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
&& _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
arbitrary_element = &(*seqs_begin[t].first);
total_length += _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]);
}
if(total_length == 0)
return target;
for (int t = 0; t < k; ++t)
{
if (seqs_begin[t].first == seqs_begin[t].second)
@ -577,11 +576,9 @@ template<typename LT,
lt.init();
const difference_type const_total_length(std::min(total_length, length));
int source;
for (difference_type i = 0; i < const_total_length; ++i)
for (difference_type i = 0; i < length; ++i)
{
//take out
source = lt.get_min_source();
@ -612,7 +609,8 @@ template<typename LT,
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param comp Comparator.
* @param length Maximum length to merge.
* @param length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
@ -644,23 +642,16 @@ template<typename LT,
LT lt(k, sentinel, comp);
difference_type total_length = 0;
for (int t = 0; t < k; ++t)
{
#if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(seqs_begin[t].first != seqs_begin[t].second);
#endif
lt.insert_start(*seqs_begin[t].first, t, false);
total_length += _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]);
}
lt.init();
// Do not go past end.
length = std::min(total_length, length);
int source;
#if _GLIBCXX_ASSERTIONS
@ -698,6 +689,7 @@ template<typename LT,
/** @brief Multi-way merging procedure for a high branching factor,
* requiring sentinels to exist.
*
* @param stable The value must the same as for the used LoserTrees.
* @param UnguardedLoserTree Loser Tree variant to use for the unguarded
* merging.
@ -708,7 +700,8 @@ template<typename LT,
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param comp Comparator.
* @param length Maximum length to merge.
* @param length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
@ -737,23 +730,16 @@ template<
RandomAccessIterator3 target_end;
difference_type total_length = 0;
for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
{
total_length += _GLIBCXX_PARALLEL_LENGTH(*s);
// Move the sequends end behind the sentinel spots. This has the
// effect that the sentinel appears to be within the sequence. Then,
// we can use the unguarded variant if we merge out as many
// non-sentinel elements as we have.
++((*s).second);
// Move the sequends end behind the sentinel spots. This has the
// effect that the sentinel appears to be within the sequence. Then,
// we can use the unguarded variant if we merge out as many
// non-sentinel elements as we have.
++((*s).second);
}
difference_type unguarded_length =
std::min(length, total_length);
target_end = multiway_merge_loser_tree_unguarded
<UnguardedLoserTree>
(seqs_begin, seqs_end, target, 0, comp, unguarded_length);
(seqs_begin, seqs_end, target, 0, comp, length);
#if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(target_end == target + length);
@ -763,7 +749,7 @@ template<
// Restore the sequence ends so the sentinels are not contained in the
// sequence any more (see comment in loop above).
for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
{ --((*s).second); }
--((*s).second);
return target_end;
}
@ -977,7 +963,8 @@ struct multiway_merge_k_variant_sentinel_switch
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param comp Comparator.
* @param length Maximum length to merge.
* @param length Maximum length to merge, possibly larger than the
* number of elements available.
* @param stable Stable merging incurs a performance penalty.
* @param sentinel The sequences have a sentinel element.
* @return End iterator of output sequence. */
@ -1010,7 +997,16 @@ template<
}
#endif
RandomAccessIterator3 return_target = target;
_DifferenceTp total_length = 0;
for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
total_length += _GLIBCXX_PARALLEL_LENGTH(*s);
length = std::min<_DifferenceTp>(length, total_length);
if(length == 0)
return target;
RandomAccessIterator3 return_target = target;
int k = static_cast<int>(seqs_end - seqs_begin);
switch (k)
@ -1079,7 +1075,7 @@ struct sampling_sorter
/**
* @brief Non-stable sorting functor.
*
* Used to reduce code instanciation in multiway_merge_sampling_splitting.
* Used to reduce code instantiation in multiway_merge_sampling_splitting.
*/
template<class RandomAccessIterator, class StrictWeakOrdering>
struct sampling_sorter<false, RandomAccessIterator, StrictWeakOrdering>
@ -1126,11 +1122,11 @@ void multiway_merge_sampling_splitting(
{
difference_type sample_index =
static_cast<difference_type>(
_GLIBCXX_PARALLEL_LENGTH(seqs_begin[s]) * (double(i + 1) /
(num_samples + 1)) * (double(length)
/ total_length));
new(&(samples[s * num_samples + i])) value_type(
seqs_begin[s].first[sample_index]);
_GLIBCXX_PARALLEL_LENGTH(seqs_begin[s])
* (double(i + 1) / (num_samples + 1))
* (double(length) / total_length));
new(&(samples[s * num_samples + i]))
value_type(seqs_begin[s].first[sample_index]);
}
// Sort stable or non-stable, depending on value of template parameter
@ -1152,10 +1148,8 @@ void multiway_merge_sampling_splitting(
comp)
- seqs_begin[seq].first;
else
{
// Absolute beginning.
pieces[slab][seq].first = 0;
}
// Absolute beginning.
pieces[slab][seq].first = 0;
if ((slab + 1) < num_threads)
pieces[slab][seq].second =
std::upper_bound(
@ -1165,13 +1159,16 @@ void multiway_merge_sampling_splitting(
num_threads], comp)
- seqs_begin[seq].first;
else
pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
// Absolute end.
pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
}
::operator delete(samples);
}
/**
* @brief Exact splitting for parallel multiway-merge routine.
*
* None of the passed sequences may be empty.
*/
template<
bool stable
@ -1269,7 +1266,8 @@ void multiway_merge_exact_splitting(
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param comp Comparator.
* @param length Maximum length to merge.
* @param length Maximum length to merge, possibly larger than the
* number of elements available.
* @param stable Stable merging incurs a performance penalty.
* @param sentinel Ignored.
* @return End iterator of output sequence.
@ -1304,23 +1302,41 @@ template<
typedef typename
std::iterator_traits<RandomAccessIterator1>::value_type value_type;
// k sequences.
int k = static_cast<int>(seqs_end - seqs_begin);
// Leave only non-empty sequences.
std::pair<RandomAccessIterator1, RandomAccessIterator1>* ne_seqs =
static_cast<std::pair<RandomAccessIterator1, RandomAccessIterator1>*>(
::operator new(
sizeof(std::pair<RandomAccessIterator1, RandomAccessIterator1>)
* (seqs_end - seqs_begin)));
int k = 0;
difference_type total_length = 0;
for (RandomAccessIteratorIterator raii = seqs_begin;
raii != seqs_end; ++raii)
total_length += _GLIBCXX_PARALLEL_LENGTH(*raii);
{
_DifferenceTp seq_length = _GLIBCXX_PARALLEL_LENGTH(*raii);
if(seq_length > 0)
{
total_length += seq_length;
//ne_seqs[k] = *raii;
new(&(ne_seqs[k++]))
std::pair<RandomAccessIterator1, RandomAccessIterator1>(*raii);
}
}
_GLIBCXX_CALL(total_length)
length = std::min<_DifferenceTp>(length, total_length);
if (total_length == 0 || k == 0)
{
::operator delete(ne_seqs);
return target;
}
std::vector<std::pair<difference_type, difference_type> >* pieces;
thread_index_t num_threads = static_cast<thread_index_t>(
std::min<difference_type>(get_max_threads(), total_length));
thread_index_t num_threads = static_cast<thread_index_t>
(std::min<difference_type>(get_max_threads(), total_length));
# pragma omp parallel num_threads (num_threads)
{
@ -1337,7 +1353,7 @@ template<
__gnu_parallel::_Settings::get().merge_oversampling *
num_threads;
splitter(seqs_begin, seqs_end, comp, length, total_length,
splitter(ne_seqs, ne_seqs + k, comp, length, total_length,
pieces);
} //single
@ -1348,50 +1364,37 @@ template<
for (int c = 0; c < k; ++c)
target_position += pieces[iam][c].first;
if (k > 2)
std::pair<RandomAccessIterator1, RandomAccessIterator1>* chunks
= new std::pair<RandomAccessIterator1, RandomAccessIterator1>[k];
for (int s = 0; s < k; ++s)
{
std::pair<RandomAccessIterator1, RandomAccessIterator1>* chunks
= new
std::pair<RandomAccessIterator1, RandomAccessIterator1>[k];
difference_type local_length = 0;
for (int s = 0; s < k; ++s)
{
chunks[s] = std::make_pair(
seqs_begin[s].first + pieces[iam][s].first,
seqs_begin[s].first + pieces[iam][s].second);
local_length += _GLIBCXX_PARALLEL_LENGTH(chunks[s]);
}
sequential_multiway_merge<stable, sentinels>(
chunks, chunks + k, target + target_position, comp,
std::min(local_length, length - target_position));
delete[] chunks;
}
else if (k == 2)
{
RandomAccessIterator1
begin0 = seqs_begin[0].first + pieces[iam][0].first,
begin1 = seqs_begin[1].first + pieces[iam][1].first;
merge_advance(begin0,
seqs_begin[0].first + pieces[iam][0].second,
begin1,
seqs_begin[1].first + pieces[iam][1].second,
target + target_position,
(pieces[iam][0].second - pieces[iam][0].first) +
(pieces[iam][1].second - pieces[iam][1].first),
comp);
chunks[s] = std::make_pair(
ne_seqs[s].first + pieces[iam][s].first,
ne_seqs[s].first + pieces[iam][s].second);
}
if(length > target_position)
sequential_multiway_merge<stable, sentinels>(
chunks, chunks + k, target + target_position, comp,
length - target_position);
delete[] chunks;
} // parallel
#if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target + length, comp));
#endif
k = 0;
// Update ends of sequences.
for (int s = 0; s < k; ++s)
seqs_begin[s].first += pieces[num_threads - 1][s].second;
for (RandomAccessIteratorIterator raii = seqs_begin;
raii != seqs_end; ++raii)
{
_DifferenceTp length = _GLIBCXX_PARALLEL_LENGTH(*raii);
if(length > 0)
(*raii).first += pieces[num_threads - 1][k++].second;
}
delete[] pieces;
@ -1430,12 +1433,12 @@ template<
* for (int i = 0; i < 10; ++i)
* for (int j = 0; i < 10; ++j)
* sequences[i][j] = j;
*
*
* int out[33];
* std::vector<std::pair<int*> > seqs;
* for (int i = 0; i < 10; ++i)
* { seqs.push(std::make_pair<int*>(sequences[i], sequences[i] + 10)) }
*
*
* multiway_merge(seqs.begin(), seqs.end(), target, std::less<int>(), 33);
* </pre>
*
@ -1461,10 +1464,12 @@ template<
* @param seqs_end end of sequence sequence
* @param target target sequence to merge to.
* @param comp strict weak ordering to use for element comparison.
* @param length the number of elements to merge into target.
* @param length Maximum length to merge, possibly larger than the
* number of elements available.
*
* @return end iterator of output sequence
*/
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1486,28 +1491,26 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge
return parallel_multiway_merge
</* stable = */ false, /* sentinels = */ false>
(seqs_begin, seqs_end, target, comp,
multiway_merge_sampling_splitting</* stable = */ false,
RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
target_end = sequential_multiway_merge
return sequential_multiway_merge
</* stable = */false, /* sentinels = */ false>(
seqs_begin, seqs_end,
target, comp, length);
return target_end;
}
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1533,6 +1536,7 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
(seqs_begin, seqs_end, target, comp, length);
}
//public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1555,14 +1559,13 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge
return parallel_multiway_merge
</* stable = */ false, /* sentinels = */ false>(
seqs_begin, seqs_end,
target, comp,
@ -1570,14 +1573,13 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
target_end = sequential_multiway_merge
return sequential_multiway_merge
</* stable = */ false, /* sentinels = */ false>(
seqs_begin, seqs_end,
target, comp, length);
return target_end;
}
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1599,14 +1601,13 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge
return parallel_multiway_merge
</* stable = */ true, /* sentinels = */ false>(
seqs_begin, seqs_end,
target, comp,
@ -1614,14 +1615,13 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
target_end = sequential_multiway_merge
return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ false>(
seqs_begin, seqs_end,
target, comp, length);
return target_end;
}
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1639,7 +1639,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences
if (seqs_begin == seqs_end)
{ return target; }
return target;
// Execute multiway merge *sequentially*.
return sequential_multiway_merge
@ -1647,6 +1647,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
(seqs_begin, seqs_end, target, comp, length);
}
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1664,19 +1665,18 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences
if (seqs_begin == seqs_end)
{ return target; }
return target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge
return parallel_multiway_merge
</* stable = */ true, /* sentinels = */ false>(
seqs_begin, seqs_end,
target, comp,
@ -1685,12 +1685,10 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
target_end = sequential_multiway_merge</* stable = */ true,
return sequential_multiway_merge</* stable = */ true,
/* sentinels = */ false>(
seqs_begin, seqs_end,
target, comp, length);
return target_end;
}
/**
@ -1706,7 +1704,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
* that breaks ties by sequence number but is slower.
*
* The first entries of the pairs (i.e. the begin iterators) will be moved
* forward.
* forward accordingly.
*
* The output sequence has to provide enough space for all elements
* that are written to it.
@ -1763,10 +1761,12 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
* @param seqs_end end of sequence sequence
* @param target target sequence to merge to.
* @param comp strict weak ordering to use for element comparison.
* @param length the number of elements to merge into target.
* @param length Maximum length to merge, possibly larger than the
* number of elements available.
*
* @return end iterator of output sequence
*/
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1783,19 +1783,18 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences
if (seqs_begin == seqs_end)
{ return target; }
return target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge
return parallel_multiway_merge
</* stable = */ false, /* sentinels = */ true>
(seqs_begin, seqs_end, target, comp,
multiway_merge_sampling_splitting
@ -1803,14 +1802,13 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
target_end = sequential_multiway_merge
return sequential_multiway_merge
</* stable = */false, /* sentinels = */ true>(
seqs_begin, seqs_end,
target, comp, length);
return target_end;
}
//public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1828,7 +1826,7 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences
if (seqs_begin == seqs_end)
{ return target; }
return target;
// Execute multiway merge *sequentially*.
return sequential_multiway_merge
@ -1836,6 +1834,7 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
(seqs_begin, seqs_end, target, comp, length);
}
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1853,19 +1852,18 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences
if (seqs_begin == seqs_end)
{ return target; }
return target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge
return parallel_multiway_merge
</* stable = */ false, /* sentinels = */ true>(
seqs_begin, seqs_end,
target, comp,
@ -1874,14 +1872,13 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
target_end = sequential_multiway_merge
return sequential_multiway_merge
</* stable = */ false, /* sentinels = */ true>(
seqs_begin, seqs_end,
target, comp, length);
return target_end;
}
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1898,19 +1895,18 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences
if (seqs_begin == seqs_end)
{ return target; }
return target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge
return parallel_multiway_merge
</* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end,
target, comp,
@ -1919,14 +1915,13 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
target_end = sequential_multiway_merge
return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end,
target, comp, length);
return target_end;
}
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1944,7 +1939,7 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences
if (seqs_begin == seqs_end)
{ return target; }
return target;
// Execute multiway merge *sequentially*.
return sequential_multiway_merge
@ -1952,6 +1947,7 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
(seqs_begin, seqs_end, target, comp, length);
}
// public interface
template<
typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut
@ -1969,19 +1965,18 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences
if (seqs_begin == seqs_end)
{ return target; }
return target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge
return parallel_multiway_merge
</* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end,
target, comp,
@ -1990,12 +1985,10 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
target_end = sequential_multiway_merge
return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end,
target, comp, length);
return target_end;
}
}; // namespace __gnu_parallel