-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExternalSort.h
More file actions
61 lines (52 loc) · 1.64 KB
/
ExternalSort.h
File metadata and controls
61 lines (52 loc) · 1.64 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
#pragma once
#include "all.h"
#include "External.h"
#include "Heap.h"
using std::pair;
template<typename T, class Comp>
class Heap_pair_comp{
private:
Comp compare;
public:
bool operator()(const pair<T, int>& a, const pair<T, int>& b) {
return compare(a.first, b.first) || (!compare(b.first, a.first) && a.second < b.second);
}
};
template<typename T, class Comp = std::less<T> >
class ExternalSort :
public ExternalAlgorithm<T> {
private:
Comp compare;
Heap<std::pair<T, int>, Heap_pair_comp<T, Comp> > heap;
virtual void calcBlock(vector<T>& block);
virtual void mergePrecalc();
virtual bool nextElem(T&);
public:
ExternalSort(IoSerialiser<T>, string, int);
};
template<typename T, class Comp>
ExternalSort<T, Comp>::ExternalSort(IoSerialiser<T> s, string tmpDir = ".\tmp", int maxNInRAM = 1E7)
: ExternalAlgorithm(s, tmpDir, maxNInRAM) {}
template<typename T, class Comp>
void ExternalSort<T, Comp>::calcBlock(vector<T>& block) {
std::sort(block.begin(), block.end(), compare);
}
template<typename T, class Comp>
void ExternalSort<T, Comp>::mergePrecalc() {
for (size_t i = 0; i < serialisers.size(); ++i) {
assert(!serialisers[i]->empty());
T elem = serialisers[i]->get();
heap.push(std::make_pair(elem, i));
}
}
template<typename T, class Comp>
bool ExternalSort<T, Comp>::nextElem(T& ans) {
if (heap.empty()) return 0;
std::pair<T, int> tmp = heap.getmin();
if (!serialisers[tmp.second]->empty())
heap.push(std::make_pair(serialisers[tmp.second]->get(), tmp.second));
else
serialisers[tmp.second]->close();
ans = tmp.first;
return 1;
}