-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
299 lines (272 loc) · 9.39 KB
/
main.cpp
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
#include "main_ns.h"
#include <csignal>
#include <cerrno>
#include <iomanip>
#include <cstring>
#include "rollback/AbstractRollbackDoublyLinkedList.h"
#include "rollback/blackbox/DoublyLinkedList.h"
#include "rollback/eliminate_reorder/DoublyLinkedList.h"
#include "node_copying/DoublyLinkedList.h"
using namespace std;
double
rand01 ()
{
return (double) rand () / RAND_MAX;
}
static void
hdl (int sig, siginfo_t* siginfo, void* context)
{
if (sig == SIGUSR1) {
cout.setf (ios::showpoint);
cout << "Progress: " << setprecision (15) << main_ns::current_op_no <<
" / " << main_ns::count << " (" << setprecision (4)
<< (100.0 * main_ns::current_op_no) / main_ns::count << "%)" << endl;
}
}
int
main (int argc, char** argv)
{
// #ifndef MEASURE_SPACE
main_ns::start_time = main_ns::nano_time ();
// #endif
using namespace main_ns;
main_ns::mode_t mode = main_ns::eliminate_reorder;
bool only_measure_time_to_head = false;
unsigned int seed = start_time;
double p_remove = 0.25;
double p_modify = 0.25;
double p_access = 0.25;
double p_insert = 0.25;
struct sigaction act;
memset (&act, '\0', sizeof (act));
act.sa_sigaction = &hdl;
act.sa_flags = SA_SIGINFO;
if (sigaction (SIGUSR1, &act, NULL) < 0) {
perror ("sigaction");
return 1;
}
try {
for (int i = 1; i < argc; ++i) {
string arg = argv[i];
if ("-c" == arg || "--count" == arg) {
if (++i < argc) {
main_ns::count = atoi (argv[i]);
} else {
stringstream ss;
ss << "No argument given to " << arg;
throw ss.str ();
}
} else if ("-m" == arg || "--max-no-snapshots" == arg) {
if (++i < argc) {
max_no_snapshots = atoi (argv[i]);
} else {
stringstream ss;
ss << "No argument given to " << arg;
throw ss.str ();
}
} else if ("-d" == arg || "--max-snapshot-dist" == arg) {
if (++i < argc) {
max_snapshot_dist = atoi (argv[i]);
} else {
stringstream ss;
ss << "No argument given to " << arg;
throw ss.str ();
}
} else if ("-b" == arg || "--rollback-blackbox" == arg) {
mode = main_ns::blackbox;
} else if ("-e" == arg || "--rollback-eliminate-reorder" == arg) {
mode = main_ns::eliminate_reorder;
} else if ("-n" == arg || "--node-copying" == arg) {
mode = main_ns::node_copying;
} else if ("-s" == arg || "--store-results" == arg) {
store_results = true;
} else if ("-r" == arg || "--randomize-operations" == arg) {
randomize_operations = true;
} else if ("-h" == arg || "--head-only" == arg) {
only_measure_time_to_head = true;
} else if ("--seed" == arg) {
if (++i < argc) {
seed = atoi (argv[i]);
} else {
stringstream ss;
ss << "No argument given to " << arg;
throw ss.str ();
}
} else {
cerr << "Argument \"" << arg << "\" not understood." << endl;
exit (1);
}
}
cout.precision (15);
sqlite3* db;
char* zErrMsg;
int rc;
rc = sqlite3_open ("sqlite.db", &db);
if (rc) {
cerr << "Can't open database \"sqlite.db\": " << sqlite3_errmsg (db) <<
endl;
sqlite3_close (db);
return 1;
}
#ifndef MEASURE_SPACE
rc = sqlite3_exec (db,
"create table if not exists results (id integer primary key autoincrement not null, start_time integer not null, version text not null, implementation text not null, count integer not null, max_no_snapshots integer, max_snapshot_dist integer, begin_time integer not null, end_time integer not null, operation text not null, duration integer not null)",
callback, 0, &zErrMsg);
#else
rc = sqlite3_exec (db,
"create table if not exists space (id integer primary key autoincrement not null, usage_scenario text not null, version text not null, implementation text not null, count integer not null, max_no_snapshots integer, max_snapshot_dist integer, space integer)",
callback, 0, &zErrMsg);
#endif
if (rc != SQLITE_OK) {
cerr << "SQL error: " << zErrMsg << endl;
sqlite3_free (zErrMsg);
}
srand (seed);
AbstractDoublyLinkedList* list = 0x0;
switch (mode) {
case main_ns::node_copying:
list = new node_copying::DoublyLinkedList ();
break;
case main_ns::blackbox:
list =
new rollback::blackbox::DoublyLinkedList (max_no_snapshots,
max_snapshot_dist);
break;
case main_ns::eliminate_reorder:
list =
new rollback::eliminate_reorder::DoublyLinkedList (max_no_snapshots,
max_snapshot_dist);
break;
}
#ifndef MEASURE_SPACE
size_t insert_count = 0;
size_t modify_count = 0;
size_t remove_count = 0;
size_t access_count = 0;
long long insert_duration = 0;
long long modify_duration = 0;
long long remove_duration = 0;
long long access_duration = 0;
#endif
double p_sum = p_remove + p_modify + p_access + p_insert;
p_remove /= p_sum;
p_modify /= p_sum;
p_access /= p_sum;
p_insert /= p_sum;
double begin_operation;
for (size_t i = 0; i < main_ns::count; ++i) {
operation_type_t op;
if (randomize_operations) {
double r = rand01 ();
if (r < p_remove) {
op = main_ns::remove;
} else if (r < p_remove + p_modify) {
op = modify;
} else if (r < p_remove + p_modify + p_access) {
op = main_ns::access;
} else {
op = insert;
}
} else {
double progress = ( (double) i) / main_ns::count;
if (progress < p_insert) {
op = insert;
} else if (progress < p_insert + p_modify) {
op = modify;
} else if (progress < p_insert + p_modify + p_remove) {
op = main_ns::remove;
} else {
op = main_ns::access;
}
}
#ifndef MEASURE_SPACE
begin_operation = nano_time ();
#endif
size_t index = 0;
size_t version;
if (op == main_ns::access
&& list->a_size_at (version =
rand01 () * list->a_num_versions ()) > 0) {
#ifndef MEASURE_SPACE
++access_count;
#endif
if (!only_measure_time_to_head) {
index = rand01 () * list->a_size_at (version);
}
list->a_access (version, index);
#ifndef MEASURE_SPACE
access_duration += (long long) (nano_time () - begin_operation);
#endif
} else {
version = list->a_num_versions ();
size_t list_size = list->a_size ();
// if (!only_measure_time_to_head) {
index = (size_t) (rand01 () * list_size);
// }
if (op == main_ns::remove && list_size > 0) {
list->a_remove (index);
#ifndef MEASURE_SPACE
++remove_count;
remove_duration += (long long) (nano_time () - begin_operation);
#endif
} else if (op == modify && list_size > 0) {
list->a_modify (index, i);
#ifndef MEASURE_SPACE
++modify_count;
modify_duration += (long long) (nano_time () - begin_operation);
#endif
} else {
list->a_insert (index, i);
#ifndef MEASURE_SPACE
++insert_count;
insert_duration += (long long) (nano_time () - begin_operation);
#endif
}
}
++current_op_no;
}
#ifdef MEASURE_SPACE
size_t space = 0;
switch (mode) {
case main_ns::node_copying :
space += ( (node_copying::DoublyLinkedList*) list)->space + sizeof (*list) + sizeof (node_copying::DoublyLinkedList::version_info_t) * list->a_num_versions();
break;
case main_ns::eliminate_reorder:
case main_ns::blackbox: {
rollback::AbstractRollbackDoublyLinkedList* rlist = ( (rollback::AbstractRollbackDoublyLinkedList*) list);
space += sizeof (*rlist);
const std::vector < std::pair < std::size_t,
ephemeral::DoublyLinkedList* >> & snapshots = rlist->get_snapshots();
for (std::vector < std::pair < std::size_t,
ephemeral::DoublyLinkedList* >>::const_iterator iter = snapshots.cbegin(); iter != snapshots.cend(); ++iter) {
pair < size_t, ephemeral::DoublyLinkedList* > snaphot = *iter;
space += snaphot.second->size * sizeof (ephemeral::Node);
space += sizeof (*snaphot.second);
}
space += (rlist->a_num_versions() - 1) * sizeof (rollback::record_t);
break;
}
}
string usage_scenario = randomize_operations ? "random" : "sequential";
log_space_to_db (usage_scenario, mode, main_ns::count, max_no_snapshots, max_snapshot_dist, space);
#endif
#ifndef MEASURE_SPACE
if (store_results) {
log_operation_to_db (mode, insert_count, "insert", max_no_snapshots,
max_snapshot_dist, 0, insert_duration);
log_operation_to_db (mode, modify_count, "modify", max_no_snapshots,
max_snapshot_dist, 0, modify_duration);
log_operation_to_db (mode, remove_count, "remove", max_no_snapshots,
max_snapshot_dist, 0, remove_duration);
log_operation_to_db (mode, access_count, "access", max_no_snapshots,
max_snapshot_dist, 0, access_duration);
}
sqlite3_close (db);
#endif
return 0;
} catch (string e) {
cerr << "E: " << e << endl;
return 1;
}
}
// kate: indent-mode cstyle; indent-width 2; replace-tabs on; ;