OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [parallel/] [multiway_merge.h] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// -*- C++ -*-
2
 
3
// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the terms
7
// of the GNU General Public License as published by the Free Software
8
// Foundation; either version 3, or (at your option) any later
9
// version.
10
 
11
// This library is distributed in the hope that it will be useful, but
12
// WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
// General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// <http://www.gnu.org/licenses/>.
24
 
25
/** @file parallel/multiway_merge.h
26
*  @brief Implementation of sequential and parallel multiway merge.
27
*
28
*  Explanations on the high-speed merging routines in the appendix of
29
*
30
*  P. Sanders.
31
*  Fast priority queues for cached memory.
32
*  ACM Journal of Experimental Algorithmics, 5, 2000.
33
*
34
*  This file is a GNU parallel extension to the Standard C++ Library.
35
*/
36
 
37
// Written by Johannes Singler and Manuel Holtgrewe.
38
 
39
#ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
40
#define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
41
 
42
#include <vector>
43
 
44
#include <bits/stl_algo.h>
45
#include <parallel/features.h>
46
#include <parallel/parallel.h>
47
#include <parallel/losertree.h>
48
#include <parallel/multiseq_selection.h>
49
#if _GLIBCXX_ASSERTIONS
50
#include <parallel/checkers.h>
51
#endif
52
 
53
/** @brief Length of a sequence described by a pair of iterators. */
54
#define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first)
55
 
56
namespace __gnu_parallel
57
{
58
  template<typename _RAIter1, typename _RAIter2, typename _OutputIterator,
59
           typename _DifferenceTp, typename _Compare>
60
    _OutputIterator
61
    __merge_advance(_RAIter1&, _RAIter1, _RAIter2&, _RAIter2,
62
                    _OutputIterator, _DifferenceTp, _Compare);
63
 
64
  /** @brief _Iterator wrapper supporting an implicit supremum at the end
65
   *         of the sequence, dominating all comparisons.
66
   *
67
   * The implicit supremum comes with a performance cost.
68
   *
69
   * Deriving from _RAIter is not possible since
70
   * _RAIter need not be a class.
71
   */
72
  template<typename _RAIter, typename _Compare>
73
    class _GuardedIterator
74
    {
75
    private:
76
      /** @brief Current iterator __position. */
77
      _RAIter _M_current;
78
 
79
      /** @brief End iterator of the sequence. */
80
      _RAIter _M_end;
81
 
82
      /** @brief _Compare. */
83
      _Compare& __comp;
84
 
85
    public:
86
      /** @brief Constructor. Sets iterator to beginning of sequence.
87
      *  @param __begin Begin iterator of sequence.
88
      *  @param __end End iterator of sequence.
89
      *  @param __comp Comparator provided for associated overloaded
90
      *  compare operators. */
91
      _GuardedIterator(_RAIter __begin, _RAIter __end, _Compare& __comp)
92
      : _M_current(__begin), _M_end(__end), __comp(__comp)
93
      { }
94
 
95
      /** @brief Pre-increment operator.
96
      *  @return This. */
97
      _GuardedIterator<_RAIter, _Compare>&
98
      operator++()
99
      {
100
        ++_M_current;
101
        return *this;
102
      }
103
 
104
      /** @brief Dereference operator.
105
      *  @return Referenced element. */
106
      typename std::iterator_traits<_RAIter>::value_type&
107
      operator*()
108
      { return *_M_current; }
109
 
110
      /** @brief Convert to wrapped iterator.
111
      *  @return Wrapped iterator. */
112
      operator _RAIter()
113
      { return _M_current; }
114
 
115
      /** @brief Compare two elements referenced by guarded iterators.
116
       *  @param __bi1 First iterator.
117
       *  @param __bi2 Second iterator.
118
       *  @return @c true if less. */
119
      friend bool
120
      operator<(_GuardedIterator<_RAIter, _Compare>& __bi1,
121
                _GuardedIterator<_RAIter, _Compare>& __bi2)
122
      {
123
        if (__bi1._M_current == __bi1._M_end)       // __bi1 is sup
124
          return __bi2._M_current == __bi2._M_end;  // __bi2 is not sup
125
        if (__bi2._M_current == __bi2._M_end)       // __bi2 is sup
126
          return true;
127
        return (__bi1.__comp)(*__bi1, *__bi2);      // normal compare
128
      }
129
 
130
      /** @brief Compare two elements referenced by guarded iterators.
131
       *  @param __bi1 First iterator.
132
       *  @param __bi2 Second iterator.
133
       *  @return @c True if less equal. */
134
      friend bool
135
      operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
136
                 _GuardedIterator<_RAIter, _Compare>& __bi2)
137
      {
138
        if (__bi2._M_current == __bi2._M_end)       // __bi1 is sup
139
          return __bi1._M_current != __bi1._M_end;  // __bi2 is not sup
140
        if (__bi1._M_current == __bi1._M_end)       // __bi2 is sup
141
          return false;
142
        return !(__bi1.__comp)(*__bi2, *__bi1);     // normal compare
143
      }
144
    };
145
 
146
  template<typename _RAIter, typename _Compare>
147
    class _UnguardedIterator
148
    {
149
    private:
150
      /** @brief Current iterator __position. */
151
      _RAIter _M_current;
152
      /** @brief _Compare. */
153
      _Compare& __comp;
154
 
155
    public:
156
      /** @brief Constructor. Sets iterator to beginning of sequence.
157
      *  @param __begin Begin iterator of sequence.
158
      *  @param __end Unused, only for compatibility.
159
      *  @param __comp Unused, only for compatibility. */
160
      _UnguardedIterator(_RAIter __begin,
161
                         _RAIter /* __end */, _Compare& __comp)
162
      : _M_current(__begin), __comp(__comp)
163
      { }
164
 
165
      /** @brief Pre-increment operator.
166
      *  @return This. */
167
      _UnguardedIterator<_RAIter, _Compare>&
168
      operator++()
169
      {
170
        ++_M_current;
171
        return *this;
172
      }
173
 
174
      /** @brief Dereference operator.
175
      *  @return Referenced element. */
176
      typename std::iterator_traits<_RAIter>::value_type&
177
      operator*()
178
      { return *_M_current; }
179
 
180
      /** @brief Convert to wrapped iterator.
181
      *  @return Wrapped iterator. */
182
      operator _RAIter()
183
      { return _M_current; }
184
 
185
      /** @brief Compare two elements referenced by unguarded iterators.
186
       *  @param __bi1 First iterator.
187
       *  @param __bi2 Second iterator.
188
       *  @return @c true if less. */
189
      friend bool
190
      operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1,
191
                _UnguardedIterator<_RAIter, _Compare>& __bi2)
192
      {
193
        // Normal compare.
194
        return (__bi1.__comp)(*__bi1, *__bi2);
195
      }
196
 
197
      /** @brief Compare two elements referenced by unguarded iterators.
198
       *  @param __bi1 First iterator.
199
       *  @param __bi2 Second iterator.
200
       *  @return @c True if less equal. */
201
      friend bool
202
      operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1,
203
                 _UnguardedIterator<_RAIter, _Compare>& __bi2)
204
      {
205
        // Normal compare.
206
        return !(__bi1.__comp)(*__bi2, *__bi1);
207
      }
208
    };
209
 
210
  /** @brief Highly efficient 3-way merging procedure.
211
   *
212
   * Merging is done with the algorithm implementation described by Peter
213
   * Sanders.  Basically, the idea is to minimize the number of necessary
214
   * comparison after merging an element.  The implementation trick
215
   * that makes this fast is that the order of the sequences is stored
216
   * in the instruction pointer (translated into labels in C++).
217
   *
218
   * This works well for merging up to 4 sequences.
219
   *
220
   * Note that making the merging stable does @a not come at a
221
   * performance hit.
222
   *
223
   * Whether the merging is done guarded or unguarded is selected by the
224
   * used iterator class.
225
   *
226
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
227
   * @param __seqs_end End iterator of iterator pair input sequence.
228
   * @param __target Begin iterator of output sequence.
229
   * @param __comp Comparator.
230
   * @param __length Maximum length to merge, less equal than the
231
   * total number of elements available.
232
   *
233
   * @return End iterator of output sequence.
234
   */
235
  template<template<typename RAI, typename C> class iterator,
236
           typename _RAIterIterator,
237
           typename _RAIter3,
238
           typename _DifferenceTp,
239
           typename _Compare>
240
    _RAIter3
241
    multiway_merge_3_variant(_RAIterIterator __seqs_begin,
242
                             _RAIterIterator __seqs_end,
243
                             _RAIter3 __target,
244
                             _DifferenceTp __length, _Compare __comp)
245
    {
246
      _GLIBCXX_CALL(__length);
247
 
248
      typedef _DifferenceTp _DifferenceType;
249
 
250
      typedef typename std::iterator_traits<_RAIterIterator>
251
        ::value_type::first_type
252
        _RAIter1;
253
      typedef typename std::iterator_traits<_RAIter1>::value_type
254
        _ValueType;
255
 
256
      if (__length == 0)
257
        return __target;
258
 
259
#if _GLIBCXX_ASSERTIONS
260
      _DifferenceTp __orig_length = __length;
261
#endif
262
 
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);
267
 
268
      if (__seq0 <= __seq1)
269
        {
270
          if (__seq1 <= __seq2)
271
            goto __s012;
272
          else
273
            if (__seq2 <  __seq0)
274
              goto __s201;
275
            else
276
              goto __s021;
277
        }
278
      else
279
        {
280
          if (__seq1 <= __seq2)
281
            {
282
              if (__seq0 <= __seq2)
283
                goto __s102;
284
              else
285
                goto __s120;
286
            }
287
          else
288
            goto __s210;
289
        }
290
#define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \
291
      __s ## __a ## __b ## __c :                            \
292
        *__target = *__seq ## __a;                          \
293
        ++__target;                                         \
294
        --__length;                                         \
295
        ++__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;
300
 
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, < , < );
307
 
308
#undef _GLIBCXX_PARALLEL_MERGE_3_CASE
309
 
310
    __finish:
311
      ;
312
 
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)
318
        == __orig_length);
319
#endif
320
 
321
      __seqs_begin[0].first = __seq0;
322
      __seqs_begin[1].first = __seq1;
323
      __seqs_begin[2].first = __seq2;
324
 
325
      return __target;
326
    }
327
 
328
  /**
329
   * @brief Highly efficient 4-way merging procedure.
330
   *
331
   * Merging is done with the algorithm implementation described by Peter
332
   * Sanders. Basically, the idea is to minimize the number of necessary
333
   * comparison after merging an element.  The implementation trick
334
   * that makes this fast is that the order of the sequences is stored
335
   * in the instruction pointer (translated into goto labels in C++).
336
   *
337
   * This works well for merging up to 4 sequences.
338
   *
339
   * Note that making the merging stable does @a not come at a
340
   * performance hit.
341
   *
342
   * Whether the merging is done guarded or unguarded is selected by the
343
   * used iterator class.
344
   *
345
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
346
   * @param __seqs_end End iterator of iterator pair input sequence.
347
   * @param __target Begin iterator of output sequence.
348
   * @param __comp Comparator.
349
   * @param __length Maximum length to merge, less equal than the
350
   * total number of elements available.
351
   *
352
   * @return End iterator of output sequence.
353
   */
354
  template<template<typename RAI, typename C> class iterator,
355
           typename _RAIterIterator,
356
           typename _RAIter3,
357
           typename _DifferenceTp,
358
           typename _Compare>
359
    _RAIter3
360
    multiway_merge_4_variant(_RAIterIterator __seqs_begin,
361
                             _RAIterIterator __seqs_end,
362
                             _RAIter3 __target,
363
                             _DifferenceTp __length, _Compare __comp)
364
    {
365
      _GLIBCXX_CALL(__length);
366
      typedef _DifferenceTp _DifferenceType;
367
 
368
      typedef typename std::iterator_traits<_RAIterIterator>
369
        ::value_type::first_type
370
        _RAIter1;
371
      typedef typename std::iterator_traits<_RAIter1>::value_type
372
        _ValueType;
373
 
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);
379
 
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;  }
388
 
389
      if (__seq0 <= __seq1)
390
        {
391
          if (__seq1 <= __seq2)
392
            _GLIBCXX_PARALLEL_DECISION(0,1,2,3)
393
            else
394
              if (__seq2 < __seq0)
395
                _GLIBCXX_PARALLEL_DECISION(2,0,1,3)
396
                else
397
                  _GLIBCXX_PARALLEL_DECISION(0,2,1,3)
398
                    }
399
      else
400
        {
401
          if (__seq1 <= __seq2)
402
            {
403
              if (__seq0 <= __seq2)
404
                _GLIBCXX_PARALLEL_DECISION(1,0,2,3)
405
                else
406
                  _GLIBCXX_PARALLEL_DECISION(1,2,0,3)
407
                    }
408
          else
409
            _GLIBCXX_PARALLEL_DECISION(2,1,0,3)
410
              }
411
 
412
#define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d,  \
413
                                       __c0, __c1, __c2)    \
414
      __s ## __a ## __b ## __c ## __d:                      \
415
      if (__length == 0) goto __finish;                     \
416
      *__target = *__seq ## __a;                            \
417
      ++__target;                                           \
418
      --__length;                                           \
419
      ++__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;
427
 
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, < , < , < );
452
 
453
#undef _GLIBCXX_PARALLEL_MERGE_4_CASE
454
#undef _GLIBCXX_PARALLEL_DECISION
455
 
456
    __finish:
457
      ;
458
 
459
      __seqs_begin[0].first = __seq0;
460
      __seqs_begin[1].first = __seq1;
461
      __seqs_begin[2].first = __seq2;
462
      __seqs_begin[3].first = __seq3;
463
 
464
      return __target;
465
    }
466
 
467
  /** @brief Multi-way merging procedure for a high branching factor,
468
   *         guarded case.
469
   *
470
   * This merging variant uses a LoserTree class as selected by <tt>_LT</tt>.
471
   *
472
   * Stability is selected through the used LoserTree class <tt>_LT</tt>.
473
   *
474
   * At least one non-empty sequence is required.
475
   *
476
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
477
   * @param __seqs_end End iterator of iterator pair input sequence.
478
   * @param __target Begin iterator of output sequence.
479
   * @param __comp Comparator.
480
   * @param __length Maximum length to merge, less equal than the
481
   * total number of elements available.
482
   *
483
   * @return End iterator of output sequence.
484
   */
485
  template<typename _LT,
486
           typename _RAIterIterator,
487
           typename _RAIter3,
488
           typename _DifferenceTp,
489
           typename _Compare>
490
    _RAIter3
491
    multiway_merge_loser_tree(_RAIterIterator __seqs_begin,
492
                              _RAIterIterator __seqs_end,
493
                              _RAIter3 __target,
494
                              _DifferenceTp __length, _Compare __comp)
495
    {
496
      _GLIBCXX_CALL(__length)
497
 
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
503
        _RAIter1;
504
      typedef typename std::iterator_traits<_RAIter1>::value_type
505
        _ValueType;
506
 
507
      _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
508
 
509
      _LT __lt(__k, __comp);
510
 
511
      // Default value for potentially non-default-constructible types.
512
      _ValueType* __arbitrary_element = 0;
513
 
514
      for (_SeqNumber __t = 0; __t < __k; ++__t)
515
        {
516
          if(!__arbitrary_element
517
             && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0)
518
            __arbitrary_element = &(*__seqs_begin[__t].first);
519
        }
520
 
521
      for (_SeqNumber __t = 0; __t < __k; ++__t)
522
        {
523
          if (__seqs_begin[__t].first == __seqs_begin[__t].second)
524
            __lt.__insert_start(*__arbitrary_element, __t, true);
525
          else
526
            __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
527
        }
528
 
529
      __lt.__init();
530
 
531
      _SeqNumber __source;
532
 
533
      for (_DifferenceType __i = 0; __i < __length; ++__i)
534
        {
535
          //take out
536
          __source = __lt.__get_min_source();
537
 
538
          *(__target++) = *(__seqs_begin[__source].first++);
539
 
540
          // Feed.
541
          if (__seqs_begin[__source].first == __seqs_begin[__source].second)
542
            __lt.__delete_min_insert(*__arbitrary_element, true);
543
          else
544
            // Replace from same __source.
545
            __lt.__delete_min_insert(*__seqs_begin[__source].first, false);
546
        }
547
 
548
      return __target;
549
    }
550
 
551
  /** @brief Multi-way merging procedure for a high branching factor,
552
   *         unguarded case.
553
   *
554
   * Merging is done using the LoserTree class <tt>_LT</tt>.
555
   *
556
   * Stability is selected by the used LoserTrees.
557
   *
558
   * @pre No input will run out of elements during the merge.
559
   *
560
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
561
   * @param __seqs_end End iterator of iterator pair input sequence.
562
   * @param __target Begin iterator of output sequence.
563
   * @param __comp Comparator.
564
   * @param __length Maximum length to merge, less equal than the
565
   * total number of elements available.
566
   *
567
   * @return End iterator of output sequence.
568
   */
569
  template<typename _LT,
570
           typename _RAIterIterator,
571
           typename _RAIter3,
572
           typename _DifferenceTp, typename _Compare>
573
    _RAIter3
574
    multiway_merge_loser_tree_unguarded(_RAIterIterator __seqs_begin,
575
                                        _RAIterIterator __seqs_end,
576
                                        _RAIter3 __target,
577
       const typename std::iterator_traits<typename std::iterator_traits<
578
          _RAIterIterator>::value_type::first_type>::value_type&
579
                                        __sentinel,
580
                                        _DifferenceTp __length,
581
                                        _Compare __comp)
582
    {
583
      _GLIBCXX_CALL(__length)
584
      typedef _DifferenceTp _DifferenceType;
585
 
586
      typedef typename std::iterator_traits<_RAIterIterator>
587
        ::difference_type _SeqNumber;
588
      typedef typename std::iterator_traits<_RAIterIterator>
589
        ::value_type::first_type
590
        _RAIter1;
591
      typedef typename std::iterator_traits<_RAIter1>::value_type
592
        _ValueType;
593
 
594
      _SeqNumber __k = __seqs_end - __seqs_begin;
595
 
596
      _LT __lt(__k, __sentinel, __comp);
597
 
598
      for (_SeqNumber __t = 0; __t < __k; ++__t)
599
        {
600
#if _GLIBCXX_ASSERTIONS
601
          _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
602
                                   != __seqs_begin[__t].second);
603
#endif
604
          __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
605
        }
606
 
607
      __lt.__init();
608
 
609
      _SeqNumber __source;
610
 
611
#if _GLIBCXX_ASSERTIONS
612
      _DifferenceType __i = 0;
613
#endif
614
 
615
      _RAIter3 __target_end = __target + __length;
616
      while (__target < __target_end)
617
        {
618
          // Take out.
619
          __source = __lt.__get_min_source();
620
 
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)));
625
#endif
626
 
627
          // Feed.
628
          *(__target++) = *(__seqs_begin[__source].first++);
629
 
630
#if _GLIBCXX_ASSERTIONS
631
          ++__i;
632
#endif
633
          // Replace from same __source.
634
          __lt.__delete_min_insert(*__seqs_begin[__source].first, false);
635
        }
636
 
637
      return __target;
638
    }
639
 
640
 
641
  /** @brief Multi-way merging procedure for a high branching factor,
642
   *         requiring sentinels to exist.
643
   *
644
   * @tparam UnguardedLoserTree _Loser Tree variant to use for the unguarded
645
   *   merging.
646
   *
647
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
648
   * @param __seqs_end End iterator of iterator pair input sequence.
649
   * @param __target Begin iterator of output sequence.
650
   * @param __comp Comparator.
651
   * @param __length Maximum length to merge, less equal than the
652
   * total number of elements available.
653
   *
654
   * @return End iterator of output sequence.
655
   */
656
  template<typename UnguardedLoserTree,
657
           typename _RAIterIterator,
658
           typename _RAIter3,
659
           typename _DifferenceTp,
660
           typename _Compare>
661
    _RAIter3
662
    multiway_merge_loser_tree_sentinel(_RAIterIterator __seqs_begin,
663
                                       _RAIterIterator __seqs_end,
664
                                       _RAIter3 __target,
665
      const typename std::iterator_traits<typename std::iterator_traits<
666
        _RAIterIterator>::value_type::first_type>::value_type&
667
                                       __sentinel,
668
                                       _DifferenceTp __length,
669
                                       _Compare __comp)
670
    {
671
      _GLIBCXX_CALL(__length)
672
 
673
      typedef _DifferenceTp _DifferenceType;
674
      typedef std::iterator_traits<_RAIterIterator> _TraitsType;
675
      typedef typename std::iterator_traits<_RAIterIterator>
676
        ::value_type::first_type
677
        _RAIter1;
678
      typedef typename std::iterator_traits<_RAIter1>::value_type
679
        _ValueType;
680
 
681
      _RAIter3 __target_end;
682
 
683
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
684
        // Move the sequence ends to the sentinel.  This has the
685
        // effect that the sentinel appears to be within the sequence. Then,
686
        // we can use the unguarded variant if we merge out as many
687
        // non-sentinel elements as we have.
688
        ++((*__s).second);
689
 
690
      __target_end = multiway_merge_loser_tree_unguarded<UnguardedLoserTree>
691
        (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
692
 
693
#if _GLIBCXX_ASSERTIONS
694
      _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length);
695
      _GLIBCXX_PARALLEL_ASSERT(__is_sorted(__target, __target_end, __comp));
696
#endif
697
 
698
      // Restore the sequence ends so the sentinels are not contained in the
699
      // sequence any more (see comment in loop above).
700
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
701
        --((*__s).second);
702
 
703
      return __target_end;
704
    }
705
 
706
  /**
707
   * @brief Traits for determining whether the loser tree should
708
   *   use pointers or copies.
709
   *
710
   * The field "_M_use_pointer" is used to determine whether to use pointers
711
   * in he loser trees or whether to copy the values into the loser tree.
712
   *
713
   * The default behavior is to use pointers if the data type is 4 times as
714
   * big as the pointer to it.
715
   *
716
   * Specialize for your data type to customize the behavior.
717
   *
718
   * Example:
719
   *
720
   *   template<>
721
   *   struct _LoserTreeTraits<int>
722
   *   { static const bool _M_use_pointer = false; };
723
   *
724
   *   template<>
725
   *   struct _LoserTreeTraits<heavyweight_type>
726
   *   { static const bool _M_use_pointer = true; };
727
   *
728
   * @param _Tp type to give the loser tree traits for.
729
   */
730
  template <typename _Tp>
731
    struct _LoserTreeTraits
732
    {
733
      /**
734
       * @brief True iff to use pointers instead of values in loser trees.
735
       *
736
       * The default behavior is to use pointers if the data type is four
737
       * times as big as the pointer to it.
738
       */
739
      static const bool _M_use_pointer = (sizeof(_Tp) > 4 * sizeof(_Tp*));
740
    };
741
 
742
  /**
743
   * @brief Switch for 3-way merging with __sentinels turned off.
744
   *
745
   * Note that 3-way merging is always stable!
746
   */
747
  template<bool __sentinels /*default == false*/,
748
           typename _RAIterIterator,
749
           typename _RAIter3,
750
           typename _DifferenceTp,
751
           typename _Compare>
752
    struct __multiway_merge_3_variant_sentinel_switch
753
    {
754
      _RAIter3
755
      operator()(_RAIterIterator __seqs_begin,
756
                 _RAIterIterator __seqs_end,
757
                 _RAIter3 __target,
758
                 _DifferenceTp __length, _Compare __comp)
759
      { return multiway_merge_3_variant<_GuardedIterator>
760
          (__seqs_begin, __seqs_end, __target, __length, __comp); }
761
    };
762
 
763
  /**
764
   * @brief Switch for 3-way merging with __sentinels turned on.
765
   *
766
   * Note that 3-way merging is always stable!
767
   */
768
  template<typename _RAIterIterator,
769
           typename _RAIter3,
770
           typename _DifferenceTp,
771
           typename _Compare>
772
    struct __multiway_merge_3_variant_sentinel_switch<true, _RAIterIterator,
773
                                                      _RAIter3, _DifferenceTp,
774
                                                      _Compare>
775
    {
776
      _RAIter3
777
      operator()(_RAIterIterator __seqs_begin,
778
                 _RAIterIterator __seqs_end,
779
                 _RAIter3 __target,
780
                 _DifferenceTp __length, _Compare __comp)
781
      { return multiway_merge_3_variant<_UnguardedIterator>
782
          (__seqs_begin, __seqs_end, __target, __length, __comp); }
783
    };
784
 
785
  /**
786
   * @brief Switch for 4-way merging with __sentinels turned off.
787
   *
788
   * Note that 4-way merging is always stable!
789
   */
790
  template<bool __sentinels /*default == false*/,
791
           typename _RAIterIterator,
792
           typename _RAIter3,
793
           typename _DifferenceTp,
794
           typename _Compare>
795
    struct __multiway_merge_4_variant_sentinel_switch
796
    {
797
      _RAIter3
798
      operator()(_RAIterIterator __seqs_begin,
799
                 _RAIterIterator __seqs_end,
800
                 _RAIter3 __target,
801
                 _DifferenceTp __length, _Compare __comp)
802
      { return multiway_merge_4_variant<_GuardedIterator>
803
          (__seqs_begin, __seqs_end, __target, __length, __comp); }
804
    };
805
 
806
  /**
807
   * @brief Switch for 4-way merging with __sentinels turned on.
808
   *
809
   * Note that 4-way merging is always stable!
810
   */
811
  template<typename _RAIterIterator,
812
           typename _RAIter3,
813
           typename _DifferenceTp,
814
           typename _Compare>
815
    struct __multiway_merge_4_variant_sentinel_switch<true, _RAIterIterator,
816
                                                      _RAIter3, _DifferenceTp,
817
                                                      _Compare>
818
    {
819
      _RAIter3
820
      operator()(_RAIterIterator __seqs_begin,
821
                 _RAIterIterator __seqs_end,
822
                 _RAIter3 __target,
823
                 _DifferenceTp __length, _Compare __comp)
824
      { return multiway_merge_4_variant<_UnguardedIterator>
825
          (__seqs_begin, __seqs_end, __target, __length, __comp); }
826
    };
827
 
828
  /**
829
   * @brief Switch for k-way merging with __sentinels turned on.
830
   */
831
  template<bool __sentinels,
832
           bool __stable,
833
           typename _RAIterIterator,
834
           typename _RAIter3,
835
           typename _DifferenceTp,
836
           typename _Compare>
837
    struct __multiway_merge_k_variant_sentinel_switch
838
    {
839
      _RAIter3
840
      operator()(_RAIterIterator __seqs_begin,
841
                 _RAIterIterator __seqs_end,
842
                 _RAIter3 __target,
843
      const typename std::iterator_traits<typename std::iterator_traits<
844
      _RAIterIterator>::value_type::first_type>::value_type&
845
                 __sentinel,
846
                 _DifferenceTp __length, _Compare __comp)
847
      {
848
        typedef typename std::iterator_traits<_RAIterIterator>
849
          ::value_type::first_type
850
          _RAIter1;
851
        typedef typename std::iterator_traits<_RAIter1>::value_type
852
          _ValueType;
853
 
854
        return multiway_merge_loser_tree_sentinel<
855
        typename __gnu_cxx::__conditional_type<
856
        _LoserTreeTraits<_ValueType>::_M_use_pointer,
857
          _LoserTreePointerUnguarded<__stable, _ValueType, _Compare>,
858
          _LoserTreeUnguarded<__stable, _ValueType, _Compare>
859
          >::__type>
860
          (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
861
      }
862
    };
863
 
864
  /**
865
   * @brief Switch for k-way merging with __sentinels turned off.
866
   */
867
  template<bool __stable,
868
           typename _RAIterIterator,
869
           typename _RAIter3,
870
           typename _DifferenceTp,
871
           typename _Compare>
872
    struct __multiway_merge_k_variant_sentinel_switch<false, __stable,
873
                                                      _RAIterIterator,
874
                                                      _RAIter3, _DifferenceTp,
875
                                                      _Compare>
876
    {
877
      _RAIter3
878
      operator()(_RAIterIterator __seqs_begin,
879
                 _RAIterIterator __seqs_end,
880
                 _RAIter3 __target,
881
       const typename std::iterator_traits<typename std::iterator_traits<
882
       _RAIterIterator>::value_type::first_type>::value_type&
883
                 __sentinel,
884
                 _DifferenceTp __length, _Compare __comp)
885
      {
886
        typedef typename std::iterator_traits<_RAIterIterator>
887
          ::value_type::first_type
888
          _RAIter1;
889
        typedef typename std::iterator_traits<_RAIter1>::value_type
890
          _ValueType;
891
 
892
        return multiway_merge_loser_tree<
893
        typename __gnu_cxx::__conditional_type<
894
        _LoserTreeTraits<_ValueType>::_M_use_pointer,
895
          _LoserTreePointer<__stable, _ValueType, _Compare>,
896
          _LoserTree<__stable, _ValueType, _Compare>
897
          >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp);
898
      }
899
    };
900
 
901
  /** @brief Sequential multi-way merging switch.
902
   *
903
   *  The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and
904
   *  runtime settings.
905
   *  @param __seqs_begin Begin iterator of iterator pair input sequence.
906
   *  @param __seqs_end End iterator of iterator pair input sequence.
907
   *  @param __target Begin iterator of output sequence.
908
   *  @param __comp Comparator.
909
   *  @param __length Maximum length to merge, possibly larger than the
910
   *  number of elements available.
911
   *  @param __sentinel The sequences have __a __sentinel element.
912
   *  @return End iterator of output sequence. */
913
  template<bool __stable,
914
           bool __sentinels,
915
           typename _RAIterIterator,
916
           typename _RAIter3,
917
           typename _DifferenceTp,
918
           typename _Compare>
919
    _RAIter3
920
    __sequential_multiway_merge(_RAIterIterator __seqs_begin,
921
                                _RAIterIterator __seqs_end,
922
                                _RAIter3 __target,
923
      const typename std::iterator_traits<typename std::iterator_traits<
924
        _RAIterIterator>::value_type::first_type>::value_type&
925
                                __sentinel,
926
                                _DifferenceTp __length, _Compare __comp)
927
    {
928
      _GLIBCXX_CALL(__length)
929
 
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
935
        _RAIter1;
936
      typedef typename std::iterator_traits<_RAIter1>::value_type
937
        _ValueType;
938
 
939
#if _GLIBCXX_ASSERTIONS
940
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
941
        {
942
          _GLIBCXX_PARALLEL_ASSERT(__is_sorted((*__s).first,
943
                                               (*__s).second, __comp));
944
        }
945
#endif
946
 
947
      _DifferenceTp __total_length = 0;
948
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
949
        __total_length += _GLIBCXX_PARALLEL_LENGTH(*__s);
950
 
951
      __length = std::min<_DifferenceTp>(__length, __total_length);
952
 
953
      if(__length == 0)
954
        return __target;
955
 
956
      _RAIter3 __return_target = __target;
957
      _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
958
 
959
      switch (__k)
960
        {
961
        case 0:
962
          break;
963
        case 1:
964
          __return_target = std::copy(__seqs_begin[0].first,
965
                                      __seqs_begin[0].first + __length,
966
                                      __target);
967
          __seqs_begin[0].first += __length;
968
          break;
969
        case 2:
970
          __return_target = __merge_advance(__seqs_begin[0].first,
971
                                            __seqs_begin[0].second,
972
                                            __seqs_begin[1].first,
973
                                            __seqs_begin[1].second,
974
                                            __target, __length, __comp);
975
          break;
976
        case 3:
977
          __return_target = __multiway_merge_3_variant_sentinel_switch
978
            <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
979
            (__seqs_begin, __seqs_end, __target, __length, __comp);
980
          break;
981
        case 4:
982
          __return_target = __multiway_merge_4_variant_sentinel_switch
983
            <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
984
            (__seqs_begin, __seqs_end, __target, __length, __comp);
985
          break;
986
        default:
987
          __return_target = __multiway_merge_k_variant_sentinel_switch
988
            <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp,
989
             _Compare>()
990
            (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
991
          break;
992
        }
993
#if _GLIBCXX_ASSERTIONS
994
      _GLIBCXX_PARALLEL_ASSERT(
995
        __is_sorted(__target, __target + __length, __comp));
996
#endif
997
 
998
      return __return_target;
999
    }
1000
 
1001
  /**
1002
   * @brief Stable sorting functor.
1003
   *
1004
   * Used to reduce code instanciation in multiway_merge_sampling_splitting.
1005
   */
1006
  template<bool __stable, class _RAIter, class _StrictWeakOrdering>
1007
    struct _SamplingSorter
1008
    {
1009
      void
1010
      operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
1011
      { __gnu_sequential::stable_sort(__first, __last, __comp); }
1012
    };
1013
 
1014
  /**
1015
   * @brief Non-__stable sorting functor.
1016
   *
1017
   * Used to reduce code instantiation in multiway_merge_sampling_splitting.
1018
   */
1019
  template<class _RAIter, class _StrictWeakOrdering>
1020
    struct _SamplingSorter<false, _RAIter, _StrictWeakOrdering>
1021
    {
1022
      void
1023
      operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
1024
      { __gnu_sequential::sort(__first, __last, __comp); }
1025
    };
1026
 
1027
  /**
1028
   * @brief Sampling based splitting for parallel multiway-merge routine.
1029
   */
1030
  template<bool __stable,
1031
           typename _RAIterIterator,
1032
           typename _Compare,
1033
           typename _DifferenceType>
1034
    void
1035
    multiway_merge_sampling_splitting(_RAIterIterator __seqs_begin,
1036
                                      _RAIterIterator __seqs_end,
1037
                                      _DifferenceType __length,
1038
                                      _DifferenceType __total_length,
1039
                                      _Compare __comp,
1040
     std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
1041
    {
1042
      typedef typename std::iterator_traits<_RAIterIterator>
1043
        ::difference_type _SeqNumber;
1044
      typedef typename std::iterator_traits<_RAIterIterator>
1045
        ::value_type::first_type
1046
        _RAIter1;
1047
      typedef typename std::iterator_traits<_RAIter1>::value_type
1048
        _ValueType;
1049
 
1050
      // __k sequences.
1051
      const _SeqNumber __k
1052
        = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
1053
 
1054
      const _ThreadIndex __num_threads = omp_get_num_threads();
1055
 
1056
      const _DifferenceType __num_samples =
1057
        __gnu_parallel::_Settings::get().merge_oversampling * __num_threads;
1058
 
1059
      _ValueType* __samples = static_cast<_ValueType*>
1060
        (::operator new(sizeof(_ValueType) * __k * __num_samples));
1061
      // Sample.
1062
      for (_SeqNumber __s = 0; __s < __k; ++__s)
1063
        for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
1064
          {
1065
            _DifferenceType sample_index = static_cast<_DifferenceType>
1066
              (_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__s])
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]);
1071
          }
1072
 
1073
      // Sort stable or non-stable, depending on value of template parameter
1074
      // "__stable".
1075
      _SamplingSorter<__stable, _ValueType*, _Compare>()
1076
        (__samples, __samples + (__num_samples * __k), __comp);
1077
 
1078
      for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
1079
        // For each slab / processor.
1080
        for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
1081
          {
1082
            // For each sequence.
1083
            if (__slab > 0)
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],
1087
                 __comp)
1088
                - __seqs_begin[__seq].first;
1089
            else
1090
              // Absolute beginning.
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],
1096
                 __comp)
1097
                - __seqs_begin[__seq].first;
1098
            else
1099
              // Absolute end.
1100
              __pieces[__slab][__seq].second =
1101
                _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
1102
          }
1103
 
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);
1108
    }
1109
 
1110
  /**
1111
   * @brief Exact splitting for parallel multiway-merge routine.
1112
   *
1113
   * None of the passed sequences may be empty.
1114
   */
1115
  template<bool __stable,
1116
           typename _RAIterIterator,
1117
           typename _Compare,
1118
           typename _DifferenceType>
1119
    void
1120
    multiway_merge_exact_splitting(_RAIterIterator __seqs_begin,
1121
                                   _RAIterIterator __seqs_end,
1122
                                   _DifferenceType __length,
1123
                                   _DifferenceType __total_length,
1124
                                   _Compare __comp,
1125
       std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
1126
    {
1127
      typedef typename std::iterator_traits<_RAIterIterator>
1128
        ::difference_type _SeqNumber;
1129
      typedef typename std::iterator_traits<_RAIterIterator>
1130
        ::value_type::first_type
1131
        _RAIter1;
1132
 
1133
      const bool __tight = (__total_length == __length);
1134
 
1135
      // __k sequences.
1136
      const _SeqNumber __k = __seqs_end - __seqs_begin;
1137
 
1138
      const _ThreadIndex __num_threads = omp_get_num_threads();
1139
 
1140
      // (Settings::multiway_merge_splitting
1141
      //  == __gnu_parallel::_Settings::EXACT).
1142
      std::vector<_RAIter1>* __offsets =
1143
        new std::vector<_RAIter1>[__num_threads];
1144
      std::vector<std::pair<_RAIter1, _RAIter1> > __se(__k);
1145
 
1146
      copy(__seqs_begin, __seqs_end, __se.begin());
1147
 
1148
      _DifferenceType* __borders =
1149
        new _DifferenceType[__num_threads + 1];
1150
      __equally_split(__length, __num_threads, __borders);
1151
 
1152
      for (_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s)
1153
        {
1154
          __offsets[__s].resize(__k);
1155
          multiseq_partition(__se.begin(), __se.end(), __borders[__s + 1],
1156
                             __offsets[__s].begin(), __comp);
1157
 
1158
          // Last one also needed and available.
1159
          if (!__tight)
1160
            {
1161
              __offsets[__num_threads - 1].resize(__k);
1162
              multiseq_partition(__se.begin(), __se.end(),
1163
                                 _DifferenceType(__length),
1164
                                 __offsets[__num_threads - 1].begin(),
1165
                                 __comp);
1166
            }
1167
        }
1168
      delete[] __borders;
1169
 
1170
      for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
1171
        {
1172
          // For each slab / processor.
1173
          for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
1174
            {
1175
              // For each sequence.
1176
              if (__slab == 0)
1177
                {
1178
                  // Absolute beginning.
1179
                  __pieces[__slab][__seq].first = 0;
1180
                }
1181
              else
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;
1187
              else
1188
                {
1189
                  // __slab == __num_threads - 1
1190
                  __pieces[__slab][__seq].second =
1191
                    _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
1192
                }
1193
            }
1194
        }
1195
      delete[] __offsets;
1196
    }
1197
 
1198
  /** @brief Parallel multi-way merge routine.
1199
   *
1200
   * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor
1201
   * and runtime settings.
1202
   *
1203
   * Must not be called if the number of sequences is 1.
1204
   *
1205
   * @tparam _Splitter functor to split input (either __exact or sampling based)
1206
   * @tparam __stable Stable merging incurs a performance penalty.
1207
   * @tparam __sentinel Ignored.
1208
   *
1209
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
1210
   * @param __seqs_end End iterator of iterator pair input sequence.
1211
   * @param __target Begin iterator of output sequence.
1212
   * @param __comp Comparator.
1213
   * @param __length Maximum length to merge, possibly larger than the
1214
   * number of elements available.
1215
   * @return End iterator of output sequence.
1216
   */
1217
  template<bool __stable,
1218
           bool __sentinels,
1219
           typename _RAIterIterator,
1220
           typename _RAIter3,
1221
           typename _DifferenceTp,
1222
           typename _Splitter,
1223
           typename _Compare>
1224
    _RAIter3
1225
    parallel_multiway_merge(_RAIterIterator __seqs_begin,
1226
                            _RAIterIterator __seqs_end,
1227
                            _RAIter3 __target,
1228
                            _Splitter __splitter,
1229
                            _DifferenceTp __length,
1230
                            _Compare __comp,
1231
                            _ThreadIndex __num_threads)
1232
      {
1233
#if _GLIBCXX_ASSERTIONS
1234
        _GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1);
1235
#endif
1236
 
1237
        _GLIBCXX_CALL(__length)
1238
 
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
1244
          _RAIter1;
1245
        typedef typename
1246
          std::iterator_traits<_RAIter1>::value_type _ValueType;
1247
 
1248
        // Leave only non-empty sequences.
1249
        typedef std::pair<_RAIter1, _RAIter1> seq_type;
1250
        seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin];
1251
        _SeqNumber __k = 0;
1252
        _DifferenceType __total_length = 0;
1253
        for (_RAIterIterator __raii = __seqs_begin;
1254
             __raii != __seqs_end; ++__raii)
1255
          {
1256
            _DifferenceTp __seq_length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
1257
            if(__seq_length > 0)
1258
              {
1259
                __total_length += __seq_length;
1260
                __ne_seqs[__k++] = *__raii;
1261
              }
1262
          }
1263
 
1264
        _GLIBCXX_CALL(__total_length)
1265
 
1266
        __length = std::min<_DifferenceTp>(__length, __total_length);
1267
 
1268
        if (__total_length == 0 || __k == 0)
1269
          {
1270
            delete[] __ne_seqs;
1271
            return __target;
1272
          }
1273
 
1274
        std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces;
1275
 
1276
        __num_threads = static_cast<_ThreadIndex>
1277
          (std::min<_DifferenceType>(__num_threads, __total_length));
1278
 
1279
#       pragma omp parallel num_threads (__num_threads)
1280
        {
1281
#         pragma omp single
1282
          {
1283
            __num_threads = omp_get_num_threads();
1284
            // Thread __t will have to merge pieces[__iam][0..__k - 1]
1285
            __pieces = new std::vector<
1286
            std::pair<_DifferenceType, _DifferenceType> >[__num_threads];
1287
            for (_ThreadIndex __s = 0; __s < __num_threads; ++__s)
1288
              __pieces[__s].resize(__k);
1289
 
1290
            _DifferenceType __num_samples =
1291
              __gnu_parallel::_Settings::get().merge_oversampling
1292
              * __num_threads;
1293
 
1294
            __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length,
1295
                       __comp, __pieces);
1296
          } //single
1297
 
1298
          _ThreadIndex __iam = omp_get_thread_num();
1299
 
1300
          _DifferenceType __target_position = 0;
1301
 
1302
          for (_SeqNumber __c = 0; __c < __k; ++__c)
1303
            __target_position += __pieces[__iam][__c].first;
1304
 
1305
          seq_type* __chunks = new seq_type[__k];
1306
 
1307
          for (_SeqNumber __s = 0; __s < __k; ++__s)
1308
            __chunks[__s] = std::make_pair(__ne_seqs[__s].first
1309
                                           + __pieces[__iam][__s].first,
1310
                                           __ne_seqs[__s].first
1311
                                           + __pieces[__iam][__s].second);
1312
 
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);
1317
 
1318
          delete[] __chunks;
1319
        } // parallel
1320
 
1321
#if _GLIBCXX_ASSERTIONS
1322
        _GLIBCXX_PARALLEL_ASSERT(
1323
          __is_sorted(__target, __target + __length, __comp));
1324
#endif
1325
 
1326
        __k = 0;
1327
        // Update ends of sequences.
1328
        for (_RAIterIterator __raii = __seqs_begin;
1329
             __raii != __seqs_end; ++__raii)
1330
          {
1331
            _DifferenceTp __length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
1332
            if(__length > 0)
1333
              (*__raii).first += __pieces[__num_threads - 1][__k++].second;
1334
          }
1335
 
1336
        delete[] __pieces;
1337
        delete[] __ne_seqs;
1338
 
1339
        return __target + __length;
1340
      }
1341
 
1342
  /**
1343
   * @brief Multiway Merge Frontend.
1344
   *
1345
   * Merge the sequences specified by seqs_begin and __seqs_end into
1346
   * __target.  __seqs_begin and __seqs_end must point to a sequence of
1347
   * pairs.  These pairs must contain an iterator to the beginning
1348
   * of a sequence in their first entry and an iterator the _M_end of
1349
   * the same sequence in their second entry.
1350
   *
1351
   * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
1352
   * that breaks ties by sequence number but is slower.
1353
   *
1354
   * The first entries of the pairs (i.e. the begin iterators) will be moved
1355
   * forward.
1356
   *
1357
   * The output sequence has to provide enough space for all elements
1358
   * that are written to it.
1359
   *
1360
   * This function will merge the input sequences:
1361
   *
1362
   * - not stable
1363
   * - parallel, depending on the input size and Settings
1364
   * - using sampling for splitting
1365
   * - not using sentinels
1366
   *
1367
   * Example:
1368
   *
1369
   * <pre>
1370
   *   int sequences[10][10];
1371
   *   for (int __i = 0; __i < 10; ++__i)
1372
   *     for (int __j = 0; __i < 10; ++__j)
1373
   *       sequences[__i][__j] = __j;
1374
   *
1375
   *   int __out[33];
1376
   *   std::vector<std::pair<int*> > seqs;
1377
   *   for (int __i = 0; __i < 10; ++__i)
1378
   *     { seqs.push(std::make_pair<int*>(sequences[__i],
1379
   *                                      sequences[__i] + 10)) }
1380
   *
1381
   *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
1382
   * </pre>
1383
   *
1384
   * @see stable_multiway_merge
1385
   *
1386
   * @pre All input sequences must be sorted.
1387
   * @pre Target must provide enough space to merge out length elements or
1388
   *    the number of elements in all sequences, whichever is smaller.
1389
   *
1390
   * @post [__target, return __value) contains merged __elements from the
1391
   *    input sequences.
1392
   * @post return __value - __target = min(__length, number of elements in all
1393
   *    sequences).
1394
   *
1395
   * @tparam _RAIterPairIterator iterator over sequence
1396
   *    of pairs of iterators
1397
   * @tparam _RAIterOut iterator over target sequence
1398
   * @tparam _DifferenceTp difference type for the sequence
1399
   * @tparam _Compare strict weak ordering type to compare elements
1400
   *    in sequences
1401
   *
1402
   * @param __seqs_begin  __begin of sequence __sequence
1403
   * @param __seqs_end    _M_end of sequence __sequence
1404
   * @param __target      target sequence to merge to.
1405
   * @param __comp        strict weak ordering to use for element comparison.
1406
   * @param __length Maximum length to merge, possibly larger than the
1407
   * number of elements available.
1408
   *
1409
   * @return _M_end iterator of output sequence
1410
   */
1411
  // multiway_merge
1412
  // public interface
1413
  template<typename _RAIterPairIterator,
1414
           typename _RAIterOut,
1415
           typename _DifferenceTp,
1416
           typename _Compare>
1417
    _RAIterOut
1418
    multiway_merge(_RAIterPairIterator __seqs_begin,
1419
                   _RAIterPairIterator __seqs_end,
1420
                   _RAIterOut __target,
1421
                   _DifferenceTp __length, _Compare __comp,
1422
                   __gnu_parallel::sequential_tag)
1423
    {
1424
      typedef _DifferenceTp _DifferenceType;
1425
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1426
 
1427
      // catch special case: no sequences
1428
      if (__seqs_begin == __seqs_end)
1429
        return __target;
1430
 
1431
      // Execute multiway merge *sequentially*.
1432
      return __sequential_multiway_merge
1433
        </* __stable = */ false, /* __sentinels = */ false>
1434
        (__seqs_begin, __seqs_end, __target,
1435
         *(__seqs_begin->second), __length, __comp);
1436
    }
1437
 
1438
  // public interface
1439
  template<typename _RAIterPairIterator,
1440
           typename _RAIterOut,
1441
           typename _DifferenceTp,
1442
           typename _Compare>
1443
    _RAIterOut
1444
    multiway_merge(_RAIterPairIterator __seqs_begin,
1445
                   _RAIterPairIterator __seqs_end,
1446
                   _RAIterOut __target,
1447
                   _DifferenceTp __length, _Compare __comp,
1448
                   __gnu_parallel::exact_tag __tag)
1449
    {
1450
      typedef _DifferenceTp _DifferenceType;
1451
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1452
 
1453
      // catch special case: no sequences
1454
      if (__seqs_begin == __seqs_end)
1455
        return __target;
1456
 
1457
      // Execute merge; maybe parallel, depending on the number of merged
1458
      // elements and the number of sequences and global thresholds in
1459
      // Settings.
1460
      if ((__seqs_end - __seqs_begin > 1)
1461
          && _GLIBCXX_PARALLEL_CONDITION(
1462
            ((__seqs_end - __seqs_begin) >=
1463
               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1464
            && ((_SequenceIndex)__length >=
1465
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1466
        return parallel_multiway_merge
1467
          </* __stable = */ false, /* __sentinels = */ false>
1468
          (__seqs_begin, __seqs_end, __target,
1469
           multiway_merge_exact_splitting</* __stable = */ false,
1470
           typename std::iterator_traits<_RAIterPairIterator>
1471
           ::value_type*, _Compare, _DifferenceTp>,
1472
           static_cast<_DifferenceType>(__length), __comp,
1473
           __tag.__get_num_threads());
1474
      else
1475
        return __sequential_multiway_merge
1476
          </* __stable = */ false, /* __sentinels = */ false>
1477
          (__seqs_begin, __seqs_end, __target,
1478
           *(__seqs_begin->second), __length, __comp);
1479
    }
1480
 
1481
  // public interface
1482
  template<typename _RAIterPairIterator,
1483
           typename _RAIterOut,
1484
           typename _DifferenceTp,
1485
           typename _Compare>
1486
    _RAIterOut
1487
    multiway_merge(_RAIterPairIterator __seqs_begin,
1488
                   _RAIterPairIterator __seqs_end,
1489
                   _RAIterOut __target,
1490
                   _DifferenceTp __length, _Compare __comp,
1491
                   __gnu_parallel::sampling_tag __tag)
1492
    {
1493
      typedef _DifferenceTp _DifferenceType;
1494
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1495
 
1496
      // catch special case: no sequences
1497
      if (__seqs_begin == __seqs_end)
1498
        return __target;
1499
 
1500
      // Execute merge; maybe parallel, depending on the number of merged
1501
      // elements and the number of sequences and global thresholds in
1502
      // Settings.
1503
      if ((__seqs_end - __seqs_begin > 1)
1504
          && _GLIBCXX_PARALLEL_CONDITION(
1505
            ((__seqs_end - __seqs_begin) >=
1506
               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1507
            && ((_SequenceIndex)__length >=
1508
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1509
        return parallel_multiway_merge
1510
          </* __stable = */ false, /* __sentinels = */ false>
1511
          (__seqs_begin, __seqs_end, __target,
1512
           multiway_merge_exact_splitting</* __stable = */ false,
1513
           typename std::iterator_traits<_RAIterPairIterator>
1514
           ::value_type*, _Compare, _DifferenceTp>,
1515
           static_cast<_DifferenceType>(__length), __comp,
1516
           __tag.__get_num_threads());
1517
      else
1518
        return __sequential_multiway_merge
1519
          </* __stable = */ false, /* __sentinels = */ false>
1520
          (__seqs_begin, __seqs_end, __target,
1521
           *(__seqs_begin->second), __length, __comp);
1522
    }
1523
 
1524
  // public interface
1525
  template<typename _RAIterPairIterator,
1526
           typename _RAIterOut,
1527
           typename _DifferenceTp,
1528
           typename _Compare>
1529
    _RAIterOut
1530
    multiway_merge(_RAIterPairIterator __seqs_begin,
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())); }
1537
 
1538
  // public interface
1539
  template<typename _RAIterPairIterator,
1540
           typename _RAIterOut,
1541
           typename _DifferenceTp,
1542
           typename _Compare>
1543
    _RAIterOut
1544
    multiway_merge(_RAIterPairIterator __seqs_begin,
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())); }
1551
 
1552
  // stable_multiway_merge
1553
  // public interface
1554
  template<typename _RAIterPairIterator,
1555
           typename _RAIterOut,
1556
           typename _DifferenceTp,
1557
           typename _Compare>
1558
    _RAIterOut
1559
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1560
                          _RAIterPairIterator __seqs_end,
1561
                          _RAIterOut __target,
1562
                          _DifferenceTp __length, _Compare __comp,
1563
                          __gnu_parallel::sequential_tag)
1564
    {
1565
      typedef _DifferenceTp _DifferenceType;
1566
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1567
 
1568
      // catch special case: no sequences
1569
      if (__seqs_begin == __seqs_end)
1570
        return __target;
1571
 
1572
      // Execute multiway merge *sequentially*.
1573
      return __sequential_multiway_merge
1574
        </* __stable = */ true, /* __sentinels = */ false>
1575
          (__seqs_begin, __seqs_end, __target,
1576
           *(__seqs_begin->second), __length, __comp);
1577
    }
1578
 
1579
  // public interface
1580
  template<typename _RAIterPairIterator,
1581
           typename _RAIterOut,
1582
           typename _DifferenceTp,
1583
           typename _Compare>
1584
    _RAIterOut
1585
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1586
                          _RAIterPairIterator __seqs_end,
1587
                          _RAIterOut __target,
1588
                          _DifferenceTp __length, _Compare __comp,
1589
                          __gnu_parallel::exact_tag __tag)
1590
    {
1591
      typedef _DifferenceTp _DifferenceType;
1592
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1593
 
1594
      // catch special case: no sequences
1595
      if (__seqs_begin == __seqs_end)
1596
        return __target;
1597
 
1598
      // Execute merge; maybe parallel, depending on the number of merged
1599
      // elements and the number of sequences and global thresholds in
1600
      // Settings.
1601
      if ((__seqs_end - __seqs_begin > 1)
1602
          && _GLIBCXX_PARALLEL_CONDITION(
1603
            ((__seqs_end - __seqs_begin) >=
1604
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1605
            && ((_SequenceIndex)__length >=
1606
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1607
        return parallel_multiway_merge
1608
          </* __stable = */ true, /* __sentinels = */ false>
1609
          (__seqs_begin, __seqs_end, __target,
1610
           multiway_merge_exact_splitting</* __stable = */ true,
1611
           typename std::iterator_traits<_RAIterPairIterator>
1612
           ::value_type*, _Compare, _DifferenceTp>,
1613
           static_cast<_DifferenceType>(__length), __comp,
1614
           __tag.__get_num_threads());
1615
      else
1616
        return __sequential_multiway_merge
1617
          </* __stable = */ true, /* __sentinels = */ false>
1618
          (__seqs_begin, __seqs_end, __target,
1619
           *(__seqs_begin->second), __length, __comp);
1620
    }
1621
 
1622
  // public interface
1623
  template<typename _RAIterPairIterator,
1624
           typename _RAIterOut,
1625
           typename _DifferenceTp,
1626
           typename _Compare>
1627
    _RAIterOut
1628
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1629
                          _RAIterPairIterator __seqs_end,
1630
                          _RAIterOut __target,
1631
                          _DifferenceTp __length, _Compare __comp,
1632
                          sampling_tag __tag)
1633
    {
1634
      typedef _DifferenceTp _DifferenceType;
1635
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1636
 
1637
      // catch special case: no sequences
1638
      if (__seqs_begin == __seqs_end)
1639
        return __target;
1640
 
1641
      // Execute merge; maybe parallel, depending on the number of merged
1642
      // elements and the number of sequences and global thresholds in
1643
      // Settings.
1644
      if ((__seqs_end - __seqs_begin > 1)
1645
          && _GLIBCXX_PARALLEL_CONDITION(
1646
            ((__seqs_end - __seqs_begin) >=
1647
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1648
            && ((_SequenceIndex)__length >=
1649
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1650
        return parallel_multiway_merge
1651
          </* __stable = */ true, /* __sentinels = */ false>
1652
          (__seqs_begin, __seqs_end, __target,
1653
           multiway_merge_sampling_splitting</* __stable = */ true,
1654
           typename std::iterator_traits<_RAIterPairIterator>
1655
           ::value_type*, _Compare, _DifferenceTp>,
1656
           static_cast<_DifferenceType>(__length), __comp,
1657
           __tag.__get_num_threads());
1658
      else
1659
        return __sequential_multiway_merge
1660
          </* __stable = */ true, /* __sentinels = */ false>
1661
          (__seqs_begin, __seqs_end, __target,
1662
           *(__seqs_begin->second), __length, __comp);
1663
    }
1664
 
1665
  // public interface
1666
  template<typename _RAIterPairIterator,
1667
           typename _RAIterOut,
1668
           typename _DifferenceTp,
1669
           typename _Compare>
1670
    _RAIterOut
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))
1676
    {
1677
      return stable_multiway_merge
1678
        (__seqs_begin, __seqs_end, __target, __length, __comp,
1679
         exact_tag(__tag.__get_num_threads()));
1680
    }
1681
 
1682
  // public interface
1683
  template<typename _RAIterPairIterator,
1684
           typename _RAIterOut,
1685
           typename _DifferenceTp,
1686
           typename _Compare>
1687
    _RAIterOut
1688
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1689
                          _RAIterPairIterator __seqs_end,
1690
                          _RAIterOut __target,
1691
                          _DifferenceTp __length, _Compare __comp,
1692
                          default_parallel_tag __tag)
1693
    {
1694
      return stable_multiway_merge
1695
        (__seqs_begin, __seqs_end, __target, __length, __comp,
1696
         exact_tag(__tag.__get_num_threads()));
1697
    }
1698
 
1699
  /**
1700
   * @brief Multiway Merge Frontend.
1701
   *
1702
   * Merge the sequences specified by seqs_begin and __seqs_end into
1703
   * __target.  __seqs_begin and __seqs_end must point to a sequence of
1704
   * pairs.  These pairs must contain an iterator to the beginning
1705
   * of a sequence in their first entry and an iterator the _M_end of
1706
   * the same sequence in their second entry.
1707
   *
1708
   * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
1709
   * that breaks ties by sequence number but is slower.
1710
   *
1711
   * The first entries of the pairs (i.e. the begin iterators) will be moved
1712
   * forward accordingly.
1713
   *
1714
   * The output sequence has to provide enough space for all elements
1715
   * that are written to it.
1716
   *
1717
   * This function will merge the input sequences:
1718
   *
1719
   * - not stable
1720
   * - parallel, depending on the input size and Settings
1721
   * - using sampling for splitting
1722
   * - using sentinels
1723
   *
1724
   * You have to take care that the element the _M_end iterator points to is
1725
   * readable and contains a value that is greater than any other non-sentinel
1726
   * value in all sequences.
1727
   *
1728
   * Example:
1729
   *
1730
   * <pre>
1731
   *   int sequences[10][11];
1732
   *   for (int __i = 0; __i < 10; ++__i)
1733
   *     for (int __j = 0; __i < 11; ++__j)
1734
   *       sequences[__i][__j] = __j; // __last one is sentinel!
1735
   *
1736
   *   int __out[33];
1737
   *   std::vector<std::pair<int*> > seqs;
1738
   *   for (int __i = 0; __i < 10; ++__i)
1739
   *     { seqs.push(std::make_pair<int*>(sequences[__i],
1740
   *                                      sequences[__i] + 10)) }
1741
   *
1742
   *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
1743
   * </pre>
1744
   *
1745
   * @pre All input sequences must be sorted.
1746
   * @pre Target must provide enough space to merge out length elements or
1747
   *    the number of elements in all sequences, whichever is smaller.
1748
   * @pre For each @c __i, @c __seqs_begin[__i].second must be the end
1749
   *    marker of the sequence, but also reference the one more __sentinel
1750
   *    element.
1751
   *
1752
   * @post [__target, return __value) contains merged __elements from the
1753
   *    input sequences.
1754
   * @post return __value - __target = min(__length, number of elements in all
1755
   *    sequences).
1756
   *
1757
   * @see stable_multiway_merge_sentinels
1758
   *
1759
   * @tparam _RAIterPairIterator iterator over sequence
1760
   *    of pairs of iterators
1761
   * @tparam _RAIterOut iterator over target sequence
1762
   * @tparam _DifferenceTp difference type for the sequence
1763
   * @tparam _Compare strict weak ordering type to compare elements
1764
   *    in sequences
1765
   *
1766
   * @param __seqs_begin  __begin of sequence __sequence
1767
   * @param __seqs_end    _M_end of sequence __sequence
1768
   * @param __target      target sequence to merge to.
1769
   * @param __comp        strict weak ordering to use for element comparison.
1770
   * @param __length Maximum length to merge, possibly larger than the
1771
   * number of elements available.
1772
   *
1773
   * @return _M_end iterator of output sequence
1774
   */
1775
  // multiway_merge_sentinels
1776
  // public interface
1777
  template<typename _RAIterPairIterator,
1778
           typename _RAIterOut,
1779
           typename _DifferenceTp,
1780
           typename _Compare>
1781
    _RAIterOut
1782
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1783
                             _RAIterPairIterator __seqs_end,
1784
                             _RAIterOut __target,
1785
                             _DifferenceTp __length, _Compare __comp,
1786
                             __gnu_parallel::sequential_tag)
1787
    {
1788
      typedef _DifferenceTp _DifferenceType;
1789
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1790
 
1791
      // catch special case: no sequences
1792
      if (__seqs_begin == __seqs_end)
1793
        return __target;
1794
 
1795
      // Execute multiway merge *sequentially*.
1796
      return __sequential_multiway_merge
1797
        </* __stable = */ false, /* __sentinels = */ true>
1798
          (__seqs_begin, __seqs_end,
1799
           __target, *(__seqs_begin->second), __length, __comp);
1800
    }
1801
 
1802
  // public interface
1803
  template<typename _RAIterPairIterator,
1804
           typename _RAIterOut,
1805
           typename _DifferenceTp,
1806
           typename _Compare>
1807
    _RAIterOut
1808
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1809
                             _RAIterPairIterator __seqs_end,
1810
                             _RAIterOut __target,
1811
                             _DifferenceTp __length, _Compare __comp,
1812
                             __gnu_parallel::exact_tag __tag)
1813
    {
1814
      typedef _DifferenceTp _DifferenceType;
1815
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1816
 
1817
      // catch special case: no sequences
1818
      if (__seqs_begin == __seqs_end)
1819
        return __target;
1820
 
1821
      // Execute merge; maybe parallel, depending on the number of merged
1822
      // elements and the number of sequences and global thresholds in
1823
      // Settings.
1824
      if ((__seqs_end - __seqs_begin > 1)
1825
          && _GLIBCXX_PARALLEL_CONDITION(
1826
            ((__seqs_end - __seqs_begin) >=
1827
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1828
            && ((_SequenceIndex)__length >=
1829
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1830
        return parallel_multiway_merge
1831
          </* __stable = */ false, /* __sentinels = */ true>
1832
          (__seqs_begin, __seqs_end, __target,
1833
           multiway_merge_exact_splitting</* __stable = */ false,
1834
           typename std::iterator_traits<_RAIterPairIterator>
1835
           ::value_type*, _Compare, _DifferenceTp>,
1836
           static_cast<_DifferenceType>(__length), __comp,
1837
           __tag.__get_num_threads());
1838
      else
1839
        return __sequential_multiway_merge
1840
          </* __stable = */ false, /* __sentinels = */ true>
1841
          (__seqs_begin, __seqs_end, __target,
1842
           *(__seqs_begin->second), __length, __comp);
1843
    }
1844
 
1845
  // public interface
1846
  template<typename _RAIterPairIterator,
1847
           typename _RAIterOut,
1848
           typename _DifferenceTp,
1849
           typename _Compare>
1850
    _RAIterOut
1851
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1852
                             _RAIterPairIterator __seqs_end,
1853
                             _RAIterOut __target,
1854
                             _DifferenceTp __length, _Compare __comp,
1855
                             sampling_tag __tag)
1856
    {
1857
      typedef _DifferenceTp _DifferenceType;
1858
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1859
 
1860
      // catch special case: no sequences
1861
      if (__seqs_begin == __seqs_end)
1862
        return __target;
1863
 
1864
      // Execute merge; maybe parallel, depending on the number of merged
1865
      // elements and the number of sequences and global thresholds in
1866
      // Settings.
1867
      if ((__seqs_end - __seqs_begin > 1)
1868
          && _GLIBCXX_PARALLEL_CONDITION(
1869
            ((__seqs_end - __seqs_begin) >=
1870
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1871
            && ((_SequenceIndex)__length >=
1872
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1873
        return parallel_multiway_merge
1874
          </* __stable = */ false, /* __sentinels = */ true>
1875
          (__seqs_begin, __seqs_end, __target,
1876
           multiway_merge_sampling_splitting</* __stable = */ false,
1877
           typename std::iterator_traits<_RAIterPairIterator>
1878
           ::value_type*, _Compare, _DifferenceTp>,
1879
           static_cast<_DifferenceType>(__length), __comp,
1880
           __tag.__get_num_threads());
1881
      else
1882
        return __sequential_multiway_merge
1883
          </* __stable = */false, /* __sentinels = */ true>(
1884
            __seqs_begin, __seqs_end, __target,
1885
            *(__seqs_begin->second), __length, __comp);
1886
    }
1887
 
1888
  // public interface
1889
  template<typename _RAIterPairIterator,
1890
           typename _RAIterOut,
1891
           typename _DifferenceTp,
1892
           typename _Compare>
1893
    _RAIterOut
1894
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1895
                             _RAIterPairIterator __seqs_end,
1896
                             _RAIterOut __target,
1897
                             _DifferenceTp __length, _Compare __comp,
1898
                             parallel_tag __tag = parallel_tag(0))
1899
    {
1900
      return multiway_merge_sentinels
1901
        (__seqs_begin, __seqs_end, __target, __length, __comp,
1902
         exact_tag(__tag.__get_num_threads()));
1903
    }
1904
 
1905
  // public interface
1906
  template<typename _RAIterPairIterator,
1907
           typename _RAIterOut,
1908
           typename _DifferenceTp,
1909
           typename _Compare>
1910
    _RAIterOut
1911
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1912
                             _RAIterPairIterator __seqs_end,
1913
                             _RAIterOut __target,
1914
                             _DifferenceTp __length, _Compare __comp,
1915
                             default_parallel_tag __tag)
1916
    {
1917
      return multiway_merge_sentinels
1918
        (__seqs_begin, __seqs_end, __target, __length, __comp,
1919
         exact_tag(__tag.__get_num_threads()));
1920
    }
1921
 
1922
  // stable_multiway_merge_sentinels
1923
  // public interface
1924
  template<typename _RAIterPairIterator,
1925
           typename _RAIterOut,
1926
           typename _DifferenceTp,
1927
           typename _Compare>
1928
    _RAIterOut
1929
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1930
                                    _RAIterPairIterator __seqs_end,
1931
                                    _RAIterOut __target,
1932
                                    _DifferenceTp __length, _Compare __comp,
1933
                                    __gnu_parallel::sequential_tag)
1934
    {
1935
      typedef _DifferenceTp _DifferenceType;
1936
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1937
 
1938
      // catch special case: no sequences
1939
      if (__seqs_begin == __seqs_end)
1940
        return __target;
1941
 
1942
      // Execute multiway merge *sequentially*.
1943
      return __sequential_multiway_merge
1944
        </* __stable = */ true, /* __sentinels = */ true>
1945
        (__seqs_begin, __seqs_end, __target,
1946
         *(__seqs_begin->second), __length, __comp);
1947
    }
1948
 
1949
  // public interface
1950
  template<typename _RAIterPairIterator,
1951
           typename _RAIterOut,
1952
           typename _DifferenceTp,
1953
           typename _Compare>
1954
    _RAIterOut
1955
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1956
                                    _RAIterPairIterator __seqs_end,
1957
                                    _RAIterOut __target,
1958
                                    _DifferenceTp __length, _Compare __comp,
1959
                                    __gnu_parallel::exact_tag __tag)
1960
    {
1961
      typedef _DifferenceTp _DifferenceType;
1962
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1963
 
1964
      // catch special case: no sequences
1965
      if (__seqs_begin == __seqs_end)
1966
        return __target;
1967
 
1968
      // Execute merge; maybe parallel, depending on the number of merged
1969
      // elements and the number of sequences and global thresholds in
1970
      // Settings.
1971
      if ((__seqs_end - __seqs_begin > 1)
1972
          && _GLIBCXX_PARALLEL_CONDITION(
1973
            ((__seqs_end - __seqs_begin) >=
1974
            __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1975
            && ((_SequenceIndex)__length >=
1976
            __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1977
        return parallel_multiway_merge
1978
          </* __stable = */ true, /* __sentinels = */ true>
1979
          (__seqs_begin, __seqs_end, __target,
1980
           multiway_merge_exact_splitting</* __stable = */ true,
1981
           typename std::iterator_traits<_RAIterPairIterator>
1982
           ::value_type*, _Compare, _DifferenceTp>,
1983
           static_cast<_DifferenceType>(__length), __comp,
1984
           __tag.__get_num_threads());
1985
      else
1986
        return __sequential_multiway_merge
1987
          </* __stable = */ true, /* __sentinels = */ true>
1988
          (__seqs_begin, __seqs_end, __target,
1989
           *(__seqs_begin->second), __length, __comp);
1990
    }
1991
 
1992
  // public interface
1993
  template<typename _RAIterPairIterator,
1994
           typename _RAIterOut,
1995
           typename _DifferenceTp,
1996
           typename _Compare>
1997
    _RAIterOut
1998
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1999
                                    _RAIterPairIterator __seqs_end,
2000
                                    _RAIterOut __target,
2001
                                    _DifferenceTp __length,
2002
                                    _Compare __comp,
2003
                                    sampling_tag __tag)
2004
    {
2005
      typedef _DifferenceTp _DifferenceType;
2006
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)
2007
 
2008
      // catch special case: no sequences
2009
      if (__seqs_begin == __seqs_end)
2010
        return __target;
2011
 
2012
      // Execute merge; maybe parallel, depending on the number of merged
2013
      // elements and the number of sequences and global thresholds in
2014
      // Settings.
2015
      if ((__seqs_end - __seqs_begin > 1)
2016
          && _GLIBCXX_PARALLEL_CONDITION(
2017
            ((__seqs_end - __seqs_begin) >=
2018
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
2019
            && ((_SequenceIndex)__length >=
2020
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
2021
        return parallel_multiway_merge
2022
          </* __stable = */ true, /* __sentinels = */ true>
2023
          (__seqs_begin, __seqs_end, __target,
2024
           multiway_merge_sampling_splitting</* __stable = */ true,
2025
           typename std::iterator_traits<_RAIterPairIterator>
2026
           ::value_type*, _Compare, _DifferenceTp>,
2027
           static_cast<_DifferenceType>(__length), __comp,
2028
           __tag.__get_num_threads());
2029
      else
2030
        return __sequential_multiway_merge
2031
          </* __stable = */ true, /* __sentinels = */ true>
2032
          (__seqs_begin, __seqs_end, __target,
2033
           *(__seqs_begin->second), __length, __comp);
2034
    }
2035
 
2036
  // public interface
2037
  template<typename _RAIterPairIterator,
2038
           typename _RAIterOut,
2039
           typename _DifferenceTp,
2040
           typename _Compare>
2041
    _RAIterOut
2042
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
2043
                                    _RAIterPairIterator __seqs_end,
2044
                                    _RAIterOut __target,
2045
                                    _DifferenceTp __length,
2046
                                    _Compare __comp,
2047
                                    parallel_tag __tag = parallel_tag(0))
2048
    {
2049
      return stable_multiway_merge_sentinels
2050
        (__seqs_begin, __seqs_end, __target, __length, __comp,
2051
         exact_tag(__tag.__get_num_threads()));
2052
    }
2053
 
2054
  // public interface
2055
  template<typename _RAIterPairIterator,
2056
           typename _RAIterOut,
2057
           typename _DifferenceTp,
2058
           typename _Compare>
2059
    _RAIterOut
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)
2065
    {
2066
      return stable_multiway_merge_sentinels
2067
        (__seqs_begin, __seqs_end, __target, __length, __comp,
2068
         exact_tag(__tag.__get_num_threads()));
2069
    }
2070
}; // namespace __gnu_parallel
2071
 
2072
#endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.