-
Notifications
You must be signed in to change notification settings - Fork 16
/
DiskStorage.Tc
298 lines (231 loc) · 6.69 KB
/
DiskStorage.Tc
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
#include "libconfig.h++"
#include "logging.h"
#include "DiskStorage.h"
#include <math.h>
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
using namespace tame;
tamed static void makeDirs(aiod *a, int num_hex_chars, std::string craqkey_dir) {
tvars {
int rc;
string name;
int num_folders;
int index;
int i;
}
LOG_DEBUG << "make dirs";
//create the high level key directory if it doesn't exist
twait { a->mkdir(craqkey_dir.c_str(), 0777, mkevent(rc)); }
if(rc == EEXIST) {
LOG_DEBUG << craqkey_dir << " already exists";
} else if(rc != 0) {
LOG_ERROR << "Error when creating directory - " << rc << " - " << strerror(rc) << "\n";
}
num_folders = (int) pow(16, num_hex_chars);
LOG_DEBUG << "num_folders: " << num_folders;
for (i = 0; i < num_folders; i++) {
name = "";
name += "0123456789abcdef"[i % 16];
for (int j = 1; j < num_hex_chars; j++) {
index = i / (16 * j) % 16;
name += "0123456789abcdef"[index];
}
LOG_DEBUG << "folder name: " << name;
//create the directory if it doesn't exist
twait { a->mkdir((craqkey_dir + name).c_str(), 0777, mkevent(rc)); }
if(rc == EEXIST) {
LOG_DEBUG << name << " already exists";
} else if(rc != 0) {
LOG_ERROR << "Error when creating directory - " << rc << " - " << strerror(rc) << "\n";
}
}
}
DiskStorage::DiskStorage(log4cpp::Appender *app, int num)
{
LOG.setAdditivity(false);
LOG.setAppender(app);
num_hex_chars = num;
craqkey_dir = "/tmp/craqKeyFiles/";
a_list = New aiod *[a_list_size];
for (int i = 0; i < a_list_size; i++) {
a_list[i] = New aiod (5, 0x20000, 0x10000);
}
makeDirs(a_list[a_list_size - 1], num_hex_chars, craqkey_dir);
a_index = 0;
LOG_DEBUG << "disk storage constructor";
}
DiskStorage::~DiskStorage()
{
}
static blob make_blob(const char * str) {
blob to_ret;
bzero(&to_ret, sizeof(blob));
to_ret.setsize(strlen(str));
for(int i=0; i<strlen(str); i++) {
to_ret[i] = str[i];
}
return to_ret;
}
tamed void DiskStorage::get(ID_Value key, cb_blob ret_blob) {
tvars {
int rc;
ptr<aiofh> fh;
struct stat *sb;
ptr<aiobuf> buf, b2;
bool eof;
off_t pos, sz;
ssize_t rsz;
ssize_t blocksz;
strbuf b;
blob value;
int index;
}
a_index = (a_index + 1) % a_list_size;
index = a_index;
//amount of bytes to read from file at once
blocksz = 0x4000;
//open the file for reading
LOG_INFO << "file name is: " << (craqkey_dir + key.toString().substr(0, num_hex_chars) + "/" + key.toString()).c_str() << "\n";
twait { a_list[index]->open((craqkey_dir + key.toString().substr(0, num_hex_chars) + "/" + key.toString()).c_str(), O_RDONLY, 0, mkevent (fh, rc)); }
if(rc != 0) {
LOG_FATAL << "could not open file\n";
}
//call stat to get the length
twait { fh->fstat(mkevent (sb, rc)); }
if(rc != 0) {
LOG_FATAL << "could not fstat\n";
}
sz = sb->st_size;
LOG_WARN << "size is: " << sz << "\n";
//allocate a buffer of size bufsize
if (!(buf = a_list[index]->bufalloc (blocksz))) {
LOG_FATAL << "error allocating buffer\n";
}
eof = false;
pos = 0;
while(!eof) {
//read into the buffer bufsize bytes
twait { fh->read(pos, buf, mkevent(b2, rsz, rc)); }
if (rc != 0) {
LOG_FATAL << "Read error on file\n";
}
if (rsz < 0) {
LOG_FATAL << "Got unexpected failed read\n";
}
if (rsz < blocksz) {
eof = true;
}
//copy bytes read into result string
b.tosuio ()->copy(b2->base (), rsz);
pos += rsz;
if(pos >= sz) eof = true;
}
if (b.tosuio()->resid() != size_t(sz)) {
LOG_FATAL << "While reading file, I "
<< "exepcted " << sz << " bytes; got "
<< b.tosuio()->resid() << " bytes instead\n";
}
//close the file
twait { fh->close(mkevent(rc)); }
fh = NULL;
//print out the file
LOG_INFO << "file contents: " << str(b).cstr() << "\n";
value = make_blob(str(b));
TRIGGER(ret_blob, New refcounted<blob>(value));
}
tamed void DiskStorage::set(ID_Value key, const blob* data, cbb ret_blob) {
tvars {
int rc;
ptr<aiofh> fh;
ptr<aiobuf> buf, b2;
off_t pos;
ssize_t blocksz, bufsz, writtensz;
const char *cur;
const char *end;
string dirName;
size_t keySize;
int index;
}
a_index = (a_index + 1) % a_list_size;
index = a_index;
//amount of bytes to write to file at once
blocksz = 0x4000;
//find directory name
dirName = craqkey_dir + key.toString().substr(0, num_hex_chars);
cur = data->base();
end = data->base() + data->size();
LOG_INFO << "directory name: " << dirName << "\n";
//try to open the file for writing (and create if doesn't exist)
twait { a_list[index]->open((dirName + "/" + key.toString()).c_str(), O_WRONLY | O_CREAT, 0777, mkevent (fh, rc)); }
if(rc != 0) {
LOG_FATAL << "could not open file for writing - " << rc << " - " << strerror(rc) << "\n";
}
//allocate a buffer of size bufsize
if (!(buf = a_list[index]->bufalloc (blocksz))) {
LOG_FATAL << "error allocating buffer\n";
}
pos = 0;
while( cur < end ) {
//calculate size we're writing
bufsz = std::min<ssize_t>(blocksz, end-cur);
//copy from the string to the buffer
memcpy(buf->base(), cur, bufsz);
//write it to the file
twait { fh->swrite(pos, buf, 0, bufsz, mkevent(b2, writtensz, rc)); }
if(rc != 0) {
LOG_ERROR << "Error while writing to file - " << rc << " - " << strerror(rc) << "\n";
} else if(writtensz != bufsz) {
LOG_ERROR << "Tried to write " << bufsz << " but only wrote " << writtensz << "\n";
}
//increment by amount written
pos += writtensz;
cur += writtensz;
}
//close the file
twait { fh->close(mkevent(rc)); }
fh = NULL;
TRIGGER(ret_blob, true);
}
tamed void DiskStorage::add(ID_Value key, const blob* data, cbb ret_blob) {
tvars {
ptr<blob> get_result;
bool set_result;
}
twait { get(key, mkevent(get_result)); }
if (get_result == NULL) {
twait { set(key, data, mkevent(set_result)); }
TRIGGER(ret_blob, set_result);
} else {
TRIGGER(ret_blob, false);
}
}
tamed void DiskStorage::replace(ID_Value key, const blob* data, cbb ret_blob) {
tvars {
ptr<blob> get_result;
bool set_result;
}
twait { get(key, mkevent(get_result)); }
if (get_result == NULL) {
TRIGGER(ret_blob, false);
} else {
twait { set(key, data, mkevent(set_result)); }
TRIGGER(ret_blob, set_result);
}
}
tamed void DiskStorage::del(ID_Value key, cbb ret_bool) {
tvars {
int rc;
int index;
}
a_index = (a_index + 1) % a_list_size;
index = a_index;
//delete the file
LOG_INFO << "file name to delete is: " << (craqkey_dir + key.toString().substr(0, num_hex_chars) + "/" + key.toString()).c_str() << "\n";
twait { a_list[index]->unlink((craqkey_dir + key.toString().substr(0, num_hex_chars) + "/" + key.toString()).c_str(), mkevent (rc)); }
if(rc != 0) {
LOG_ERROR << "could not delete file\n";
}
TRIGGER(ret_bool, rc != 0);
}