-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExternal.h
More file actions
98 lines (85 loc) · 2.5 KB
/
External.h
File metadata and controls
98 lines (85 loc) · 2.5 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
97
98
#pragma once
#include "all.h"
#include "Serialiser.h"
#include "IoSerialiser.h"
#include <memory>
template<typename T>
class ExternalAlgorithm {
private:
void getBlocks();
void merge();
protected:
bool LOG;
int maxNInRAM;
int numOfBlocks;
int maxNPerBlock;
std::vector<std::unique_ptr<Serialiser<T> > > serialisers;
std::string tmpDir;
IoSerialiser<T> ioSerialiser;
virtual void calcBlock(vector<T>&) = 0;
virtual void mergePrecalc() = 0;
virtual bool nextElem(T&) = 0;
public:
void setLogging(bool f) { LOG = f; }
ExternalAlgorithm(IoSerialiser<T>, string, int);
~ExternalAlgorithm();
void start();
};
template<typename T>
ExternalAlgorithm<T>::ExternalAlgorithm(IoSerialiser<T> s, string tmpDir = ".\tmp", int maxNInRAM = 1E7)
: ioSerialiser(s), tmpDir(tmpDir), maxNInRAM(maxNInRAM), LOG(0) {}
template<typename T>
ExternalAlgorithm<T>::~ExternalAlgorithm() {
/*for (size_t i = 0; i < serialisers.size(); ++i)
if (serialisers[i])
delete serialisers[i];*/
}
template<typename T>
void ExternalAlgorithm<T>::merge() {
maxNPerBlock = maxNInRAM / numOfBlocks;
assert(maxNPerBlock > 0);
for (auto i = serialisers.begin(); i != serialisers.end(); ++i)
(*i)->openInMode('r', maxNPerBlock);
mergePrecalc();
OutputSerialiser<ELEM>* output = ioSerialiser.output;
output->open();
T tmp;
while (nextElem(tmp))
output->push(tmp);
output->close();
}
template<typename T>
void ExternalAlgorithm<T>::getBlocks() {
vector<T> elements;
elements.resize(maxNInRAM);
InputSerialiser<T>* input = ioSerialiser.input;
input->open();
int i = 0;
numOfBlocks = 0;
bool process = 1;
while (process) {
if (!input->empty())
elements[i++] = input->get();
else
process = 0;
if (i == maxNInRAM || (i != 0 && !process)) {
if(LOG) cout << "creating and calc block " << numOfBlocks;
elements.resize(i);
calcBlock(elements);
serialisers.push_back(std::unique_ptr<Serialiser<T> >(new Serialiser<T>(numOfBlocks++, tmpDir)));
auto ser = prev(serialisers.end());
(*ser)->openInMode('w');
for (int q = 0; q < i; ++q)
(*ser)->push(elements[q]);
(*ser)->close();
i = 0;
if(LOG) cout << " complited\n";
}
}
input->close();
}
template<typename T>
void ExternalAlgorithm<T>::start() {
getBlocks();
merge();
}