15 #ifndef THRILL_COMMON_RADIX_SORT_HEADER 16 #define THRILL_COMMON_RADIX_SORT_HEADER 24 #include <type_traits> 33 size_t MaxDepth,
typename Iterator,
typename Char,
35 std::less<typename std::iterator_traits<Iterator>::value_type>,
39 const Comparator& cmp,
40 const SubSorter& sub_sort,
size_t depth,
43 const size_t size = end - begin;
45 return std::sort(begin, end, cmp);
47 using value_type =
typename std::iterator_traits<Iterator>::value_type;
50 Char* cc = char_cache;
51 for (Iterator it = begin; it != end; ++it, ++cc) {
52 *cc = it->at_radix(depth);
53 assert(static_cast<size_t>(*cc) < K);
57 size_t* bkt_size =
reinterpret_cast<size_t*
>(alloca(K *
sizeof(
size_t)));
58 std::fill(bkt_size, bkt_size + K, 0);
59 for (
const Char* cci = char_cache; cci != char_cache + size; ++cci)
63 size_t* bkt_index =
reinterpret_cast<size_t*
>(alloca(K *
sizeof(
size_t)));
64 bkt_index[0] = bkt_size[0];
65 size_t last_bkt_size = bkt_size[0];
66 for (
size_t i = 1; i <
K; ++i) {
67 bkt_index[i] = bkt_index[i - 1] + bkt_size[i];
68 if (bkt_size[i]) last_bkt_size = bkt_size[i];
72 for (
size_t i = 0, j; i < size - last_bkt_size; )
74 value_type v = std::move(begin[i]);
75 Char vc = std::move(char_cache[i]);
76 while ((j = --bkt_index[vc]) > i)
80 swap(vc, char_cache[j]);
82 begin[i] = std::move(v);
86 if (depth + 1 == MaxDepth) {
89 for (
size_t i = 0; i <
K; bsum += bkt_size[i++]) {
90 if (bkt_size[i] <= 1)
continue;
91 sub_sort(begin + bsum, begin + bsum + bkt_size[i], cmp);
97 for (
size_t i = 0; i <
K; bsum += bkt_size[i++]) {
98 if (bkt_size[i] <= 1)
continue;
99 radix_sort_CI<MaxDepth>(
100 begin + bsum, begin + bsum + bkt_size[i],
101 K, cmp, sub_sort, depth + 1, char_cache);
114 size_t MaxDepth,
typename Iterator,
115 typename Comparator =
116 std::less<typename std::iterator_traits<Iterator>::value_type>,
120 const Comparator& cmp = Comparator(),
121 const SubSorter& sub_sort = SubSorter()) {
125 sub_sort(begin, end, cmp);
129 const size_t size = end - begin;
131 using CharRet = decltype(begin->at_radix(0));
132 using Char =
typename std::remove_cv<
133 typename std::remove_reference<CharRet>::type>::type;
136 Char* char_cache =
new Char[size];
137 radix_sort_CI<MaxDepth>(
138 begin, end,
K, cmp, sub_sort, 0, char_cache);
146 template <
typename Type,
size_t MaxDepth>
151 template <
typename Iterator,
typename CompareFunction>
153 const CompareFunction& cmp)
const {
155 thrill::common::radix_sort_CI<MaxDepth>(begin, end,
K_, cmp);
157 std::sort(begin, end, cmp);
167 #endif // !THRILL_COMMON_RADIX_SORT_HEADER Specialized noop functor which returns a void.
static void radix_sort_CI(Iterator begin, Iterator end, size_t K, const Comparator &cmp, const SubSorter &sub_sort, size_t depth, Char *char_cache)
Internal helper method, use radix_sort_CI below.
void operator()(Iterator begin, Iterator end, const CompareFunction &cmp) const
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
static const uint64_t K[80]
SortAlgorithm class for use with api::Sort() which calls radix_sort_CI() if K is small enough...