19 #ifndef STXXL_PARALLEL_MULTISEQ_SELECTION_HEADER
20 #define STXXL_PARALLEL_MULTISEQ_SELECTION_HEADER
36 template <
typename T1,
typename T2,
typename Comparator>
38 :
public std::binary_function<std::pair<T1, T2>, std::pair<T1, T2>, bool>
46 inline bool operator () (
const std::pair<T1, T2>& p1,
47 const std::pair<T1, T2>& p2)
49 if (m_comp(p1.first, p2.first))
52 if (m_comp(p2.first, p1.first))
56 return p1.second < p2.second;
61 template <
typename T1,
typename T2,
typename Comparator>
63 :
public std::binary_function<std::pair<T1, T2>, std::pair<T1, T2>, bool>
71 inline bool operator () (
const std::pair<T1, T2>& p1,
72 const std::pair<T1, T2>& p2)
74 if (m_comp(p2.first, p1.first))
77 if (m_comp(p1.first, p2.first))
81 return p2.second < p1.second;
100 template <
typename RanSeqs,
typename RankType,
typename RankIterator,
103 const RanSeqs& begin_seqs,
const RanSeqs& end_seqs,
104 const RankType& rank,
105 RankIterator begin_offsets,
106 Comparator comp = std::less<
107 typename std::iterator_traits<
typename std::iterator_traits<RanSeqs>
108 ::value_type::first_type>::value_type
113 typedef typename std::iterator_traits<RanSeqs>
114 ::value_type::first_type iterator;
115 typedef typename std::iterator_traits<iterator>
116 ::difference_type diff_type;
117 typedef typename std::iterator_traits<iterator>
118 ::value_type value_type;
120 typedef std::pair<value_type, diff_type> sample_pair;
126 const diff_type m = std::distance(begin_seqs, end_seqs);
130 for (diff_type i = 0; i < m; ++i)
132 N += std::distance(begin_seqs[i].first, begin_seqs[i].second);
133 assert(std::distance(begin_seqs[i].first, begin_seqs[i].second) > 0);
138 for (diff_type i = 0; i < m; ++i)
139 begin_offsets[i] = begin_seqs[i].second;
143 assert(m != 0 && N != 0 && rank < N);
145 diff_type* seqlen =
new diff_type[m];
147 seqlen[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second);
149 for (diff_type i = 1; i < m; ++i)
151 seqlen[i] = std::distance(begin_seqs[i].first, begin_seqs[i].second);
159 diff_type* a =
new diff_type[m], * b =
new diff_type[m];
161 for (diff_type i = 0; i < m; ++i)
169 #define S(i) (begin_seqs[i].first)
173 std::vector<sample_pair> sample;
175 for (diff_type i = 0; i < m; ++i) {
178 sample.push_back(sample_pair(
S(i)[n], i));
182 std::sort(sample.begin(), sample.end(), lcomp);
184 for (diff_type i = 0; i < m; ++i) {
186 if (n >= seqlen[i]) {
188 sample.push_back(sample_pair(
S(i)[0] , i));
192 diff_type localrank = rank / l;
195 for (j = 0; j < localrank && ((n + 1) <= seqlen[sample[j].second]); ++j)
196 a[sample[j].second] += n + 1;
198 b[sample[j].second] -= n + 1;
206 const value_type* lmax = NULL;
207 for (diff_type i = 0; i < m; ++i)
212 lmax = &(
S(i)[a[i] - 1]);
216 if (!comp(
S(i)[a[i] - 1], *lmax))
217 lmax = &(
S(i)[a[i] - 1]);
222 for (diff_type i = 0; i < m; ++i)
224 diff_type middle = (b[i] + a[i]) / 2;
225 if (lmax && middle < seqlen[i] && comp(
S(i)[middle], *lmax))
226 a[i] =
std::min(a[i] + n + 1, seqlen[i]);
231 diff_type leftsize = 0;
232 for (diff_type i = 0; i < m; ++i)
233 leftsize += a[i] / (n + 1);
235 diff_type skew = rank / (n + 1) - leftsize;
240 std::priority_queue<sample_pair, std::vector<sample_pair>,
244 for (diff_type i = 0; i < m; ++i) {
245 if (b[i] < seqlen[i])
246 pq.push(sample_pair(
S(i)[b[i]], i));
249 for ( ; skew != 0 && !pq.empty(); --skew)
251 diff_type source = pq.top().second;
254 a[source] =
std::min(a[source] + n + 1, seqlen[source]);
257 if (b[source] < seqlen[source])
258 pq.push(sample_pair(
S(source)[b[source]], source));
264 std::priority_queue<sample_pair, std::vector<sample_pair>,
268 for (diff_type i = 0; i < m; ++i) {
270 pq.push(sample_pair(
S(i)[a[i] - 1], i));
273 for ( ; skew != 0; ++skew)
275 diff_type source = pq.top().second;
282 pq.push(sample_pair(
S(source)[a[source] - 1], source));
294 value_type* maxleft = NULL, * minright = NULL;
295 for (diff_type i = 0; i < m; ++i)
301 maxleft = &(
S(i)[a[i] - 1]);
306 if (!comp(
S(i)[a[i] - 1], *maxleft))
307 maxleft = &(
S(i)[a[i] - 1]);
310 if (b[i] < seqlen[i])
314 minright = &(
S(i)[b[i]]);
319 if (comp(
S(i)[b[i]], *minright))
320 minright = &(
S(i)[b[i]]);
325 for (diff_type i = 0; i < m; ++i)
326 begin_offsets[i] =
S(i) + a[i];
346 template <
typename ValueType,
typename RanSeqs,
typename RankType,
typename Comparator>
348 const RankType& rank,
350 Comparator comp = std::less<ValueType>())
354 typedef typename std::iterator_traits<RanSeqs>
355 ::value_type::first_type iterator;
356 typedef typename std::iterator_traits<iterator>
357 ::difference_type diff_type;
359 typedef std::pair<ValueType, diff_type> sample_pair;
365 const diff_type m = std::distance(begin_seqs, end_seqs);
369 for (diff_type i = 0; i < m; ++i)
370 N += std::distance(begin_seqs[i].first, begin_seqs[i].second);
372 if (m == 0 || N == 0 || rank < 0 || rank >= N)
374 throw std::exception();
376 diff_type* seqlen =
new diff_type[m];
378 seqlen[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second);
380 for (diff_type i = 1; i < m; ++i)
382 seqlen[i] = std::distance(begin_seqs[i].first, begin_seqs[i].second);
390 diff_type* a =
new diff_type[m], * b =
new diff_type[m];
392 for (diff_type i = 0; i < m; ++i)
400 #define S(i) (begin_seqs[i].first)
404 std::vector<sample_pair> sample;
406 for (diff_type i = 0; i < m; ++i) {
408 sample.push_back(sample_pair(
S(i)[n], i));
411 std::sort(sample.begin(), sample.end(), lcomp);
413 for (diff_type i = 0; i < m; ++i) {
416 sample.push_back(sample_pair(
S(i)[0] , i));
419 diff_type localrank = rank / l;
422 for (j = 0; j < localrank && ((n + 1) <= seqlen[sample[j].second]); ++j)
423 a[sample[j].second] += n + 1;
425 b[sample[j].second] -= n + 1;
433 const ValueType* lmax = NULL;
434 for (diff_type i = 0; i < m; ++i)
440 lmax = &(
S(i)[a[i] - 1]);
445 if (comp(*lmax,
S(i)[a[i] - 1]))
446 lmax = &(
S(i)[a[i] - 1]);
451 for (diff_type i = 0; i < m; ++i)
453 diff_type middle = (b[i] + a[i]) / 2;
454 if (lmax && middle < seqlen[i] && comp(
S(i)[middle], *lmax))
455 a[i] =
std::min(a[i] + n + 1, seqlen[i]);
460 diff_type leftsize = 0;
461 for (diff_type i = 0; i < m; ++i)
462 leftsize += a[i] / (n + 1);
464 diff_type skew = rank / (n + 1) - leftsize;
469 std::priority_queue<sample_pair, std::vector<sample_pair>,
473 for (diff_type i = 0; i < m; ++i) {
474 if (b[i] < seqlen[i])
475 pq.push(sample_pair(
S(i)[b[i]], i));
478 for ( ; skew != 0 && !pq.empty(); --skew)
480 diff_type source = pq.top().second;
483 a[source] =
std::min(a[source] + n + 1, seqlen[source]);
486 if (b[source] < seqlen[source])
487 pq.push(sample_pair(
S(source)[b[source]], source));
493 std::priority_queue<sample_pair, std::vector<sample_pair>,
497 for (diff_type i = 0; i < m; ++i) {
499 pq.push(sample_pair(
S(i)[a[i] - 1], i));
502 for ( ; skew != 0; ++skew)
504 diff_type source = pq.top().second;
511 pq.push(sample_pair(
S(source)[a[source] - 1], source));
523 ValueType* maxleft = NULL, * minright = NULL;
524 for (diff_type i = 0; i < m; ++i)
530 maxleft = &(
S(i)[a[i] - 1]);
535 if (comp(*maxleft,
S(i)[a[i] - 1]))
536 maxleft = &(
S(i)[a[i] - 1]);
539 if (b[i] < seqlen[i])
543 minright = &(
S(i)[b[i]]);
548 if (comp(
S(i)[b[i]], *minright))
549 minright = &(
S(i)[b[i]]);
556 if (!maxleft || comp(*minright, *maxleft))
566 for (diff_type i = 0; i < m; ++i)
568 diff_type lb = std::lower_bound(
S(i),
S(i) + seqlen[i], *minright, comp) -
S(i);
586 #endif // !STXXL_PARALLEL_MULTISEQ_SELECTION_HEADER
lexicographic_rev(Comparator &comp)
void multiseq_partition(const RanSeqs &begin_seqs, const RanSeqs &end_seqs, const RankType &rank, RankIterator begin_offsets, Comparator 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 seq...
void sort(ExtIterator first, ExtIterator last, StrictWeakOrdering cmp, unsigned_type M)
Sort records comparison-based, see stxxl::sort -- Sorting Comparison-Based.
static uint_pair min()
return an uint_pair instance containing the smallest value possible
Compare a pair of types lexcigraphically, ascending.
lexicographic(Comparator &comp)
ValueType multiseq_selection(const RanSeqs &begin_seqs, const RanSeqs &end_seqs, const RankType &rank, RankType &offset, Comparator comp=std::less< ValueType >())
Selects the element at a certain global rank from several sorted sequences.
#define STXXL_BEGIN_NAMESPACE
static uint_pair max()
return an uint_pair instance containing the largest value possible
#define STXXL_PARALLEL_PCALL(n)
Compare a pair of types lexcigraphically, descending.
static Integral round_up_to_power_of_two(Integral n)
#define STXXL_END_NAMESPACE