-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathParallelRadixSort.h
More file actions
96 lines (81 loc) · 2.2 KB
/
ParallelRadixSort.h
File metadata and controls
96 lines (81 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <vector>
#include "ThreadPool.h"
#ifndef RADIX_SORT_MIN_SIZE
#define RADIX_SORT_MIN_SIZE 45
#endif
class ParallelRadixSort : public ThreadPool {
using T = unsigned int;
public:
ParallelRadixSort(size_t threads) : ThreadPool(threads) {}
// Just add the sorting task
void sort(std::vector<T> &v)
{
size_t size = v.size();
if (size > 1) {
submit([this, &v, size]{
sort(&v, &v[0], &v[0] + size, 1, false);
});
}
}
private:
// sort numbers in `v` into the memory pointed to by `begin`
void sort(std::vector<T> *v, T *begin, T *end, int digit, bool delete_v)
{
debug("sort: size=%zu\n", v->size());
if (!v->size()) {
return;
}
if (end - begin < RADIX_SORT_MIN_SIZE) {
std::copy(v->begin(), v->end(), begin);
if (delete_v) {
delete v;
}
std::sort(begin, end, [](T x, T y) {
return std::to_string(x) < std::to_string(y);
});
return;
}
std::vector<T> *bucket[10];
for (int i = -1; i < 10; ++i) {
bucket[i] = new std::vector<T>;
}
for (auto &x : *v) {
int d = get_digit(x, digit);
if (d >= 0) {
bucket[d]->push_back(x);
} else {
*begin++ = d;
}
}
if (delete_v) {
delete v;
}
digit += 1;
for (int i = 0; i < 10; ++i) {
v = bucket[i];
if (v->size() > 0) {
end = begin + v->size();
submit([this, v, begin, end, digit]{
sort(v, begin, end, digit, true);
});
begin = end;
} else {
delete v;
}
}
}
// return the the n-th digit if there is, -1 otherwise
int get_digit(T num, int n)
{
int digits[20];
int count = 0;
do {
digits[count++] = num % 10;
num /= 10;
}
while (num > 0);
count -= n;
if (count >= 0) return digits[count];
return -1;
}
};