-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSortetStringTable.cpp
More file actions
130 lines (127 loc) · 4.78 KB
/
SortetStringTable.cpp
File metadata and controls
130 lines (127 loc) · 4.78 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <queue>
#include <sys/stat.h>
#include <cstring>
#include "SortetStringTable.h"
std::string SortetStringTable::get(std::string &key) {
std::string result;
if(index.empty())
return result;
int left = 0, right = index.size() - 1, middle;
while(left < right) {
middle = (left + right + 1) / 2;
if(index[middle] > key)
right = middle - 1;
else
left = middle;
}
std::ifstream fin("../data/" + std::to_string(left));
std::string tmp;
while(getline(fin, tmp)) {
bool find = true;
for(int i = 0; i < keyLength; i++)
if(tmp[i] != key[i]) {
find = false;
break;
}
if(find) {
for(int i = keyLength; i < tmp.size(); i++)
result += tmp[i];
}
}
return result;
}
void SortetStringTable::update(std::map<std::string, std::string> &data, std::map<std::string, std::string> &update, std::set<std::string> &deleted) {
if(index.empty()) {
deleted.clear();
int cntFileName = 0;
std::ofstream fout("../data/" + std::to_string(cntFileName));
if(!fout.is_open()) {
if(mkdir("../data/", 0777) == -1)
std::cerr << "Error : " << std::strerror(errno) << std::endl;
fout.close();
fout.open("../data/" + std::to_string(cntFileName), std::ios_base::out);
}
index.push_back(data.begin()->first);
int bufferSize = 0;
for (auto &it : data) {
if(bufferSize > bufferSizeForUpdate) {
bufferSize = 0;
fout.close();
cntFileName++;
fout.open("../data/" + std::to_string(cntFileName), std::ios_base::out);
index.push_back(it.first);
}
fout << (it.first) << it.second << "\n";
bufferSize += (it.first.size() + it.second.size());
}
fout.close();
}
else {
std::queue<std::string> lines;
int cntReadFile = 0, cntWriteFile = 0, cntOfFiles = index.size(), bufferSize = 0;
index.clear();
std::ifstream fin("../data/" + std::to_string(cntReadFile));
auto dataIterator = data.begin();
auto updateIterator = update.begin();
std::string tmp;
while(cntReadFile != cntOfFiles) {
if(getline(fin, tmp)) {
std::string key = tmp.substr(0, keyLength);
if(deleted.count(key))
continue;
if(updateIterator != update.end() && updateIterator->first == key) {
tmp = updateIterator->first + updateIterator->second;
key = tmp.substr(0, keyLength);
updateIterator++;
}
while(dataIterator != data.end() && dataIterator -> first < key) {
lines.push(dataIterator->first + dataIterator->second);
bufferSize += lines.back().size();
while(bufferSize >= bufferSizeForUpdate && cntWriteFile < cntReadFile)
writeDataToFile(lines, cntWriteFile++, bufferSize);
dataIterator++;
}
lines.push(tmp);
bufferSize += lines.back().size();
while(bufferSize >= bufferSizeForUpdate && cntWriteFile < cntReadFile)
writeDataToFile(lines, cntWriteFile++, bufferSize);
}
else {
cntReadFile++;
if(cntReadFile != cntOfFiles) {
fin.close();
fin.open("../data/" + std::to_string(cntReadFile), std::ios_base::in);
}
else {
while(dataIterator != data.end()) {
lines.push(dataIterator->first + dataIterator->second);
dataIterator++;
}
}
}
}
while(!lines.empty())
writeDataToFile(lines, cntWriteFile++, bufferSize);
std::ofstream fout;
while(cntWriteFile <= cntOfFiles) {
fout.open("../data/" + std::to_string(cntWriteFile), std::ios_base::out);
fout.close();
cntWriteFile++;
}
}
data.clear();
update.clear();
deleted.clear();
}
void SortetStringTable::writeDataToFile(std::queue<std::string> &lines, int cntOfFiles, int &bufferSize) {
std::ofstream fout("../data/" + std::to_string(cntOfFiles));
index.push_back(lines.front().substr(0, keyLength));
int tmpBufferSize = 0;
while(!lines.empty() && tmpBufferSize < bufferSizeForUpdate) {
fout << lines.front() << "\n";
bufferSize -= lines.front().size();
tmpBufferSize += lines.front().size();
lines.pop();
}
fout.close();
}