Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

2073 lines
69KB

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