-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path05-buzzdb.cpp
158 lines (130 loc) · 3.72 KB
/
05-buzzdb.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
#include <iostream>
#include <map>
#include <vector>
#include <fstream>
#include <iostream>
#include <chrono>
#include <iostream>
#include <map>
#include <string>
#include <iostream>
#include <vector>
#include <string>
#include <variant>
enum FieldType { INT, FLOAT, STRING };
// Define a basic Field variant class that can hold different types
class Field {
public:
FieldType type;
union {
int i;
float f;
char* s;
} data;
public:
Field(int i) : type(INT) { data.i = i; }
Field(float f) : type(FLOAT) { data.f = f; }
Field(const std::string& s) : type(STRING) {
data.s = new char[s.size() + 1];
std::copy(s.begin(), s.end(), data.s);
data.s[s.size()] = '\0';
}
// Destructor
~Field() {
if (type == STRING) {
if (data.s != nullptr){
std::cout << "Field Destructor:: Free field: " << data.s << "\n";
delete[] data.s;
}
}
}
FieldType getType() const { return type; }
int asInt() const { return data.i; }
float asFloat() const { return data.f; }
std::string asString() const { return std::string(data.s); }
void print() const{
switch(getType()){
case INT: std::cout << data.i; break;
case FLOAT: std::cout << data.f; break;
case STRING: std::cout << data.s; break;
}
}
};
class Tuple {
std::vector<Field> fields;
public:
void addField(const Field& field) {
fields.push_back(field);
}
// Destructor
~Tuple() {
std::cout << "Tuple Destructor:: \n";
for (auto& field : fields) {
if (field.type == STRING){
field.~Field();
}
}
}
void print() const {
for (const auto& field : fields) {
field.print();
}
std::cout << "\n";
}
};
class BuzzDB {
private:
// a map is an ordered key-value container
std::map<int, std::vector<int>> index;
public:
// a vector of Tuple structs acting as a table
std::vector<Tuple> table;
// insert function
void insert(int key, int value) {
std::cout << "inserting: " << key << "\n";
Tuple newTuple;
Field key_field = Field(key);
Field value_field = Field(value);
float float_val = 132.04;
Field float_field = Field(float_val);
Field string_field = Field("buzzdb");
newTuple.addField(key_field);
newTuple.addField(value_field);
newTuple.addField(float_field);
newTuple.addField(string_field);
table.push_back(newTuple);
index[key].push_back(value);
std::cout << "Done \n";
}
// perform a SELECT ... GROUP BY ... SUM query
void selectGroupBySum() {
for (auto const& pair : index) { // for each unique key
int sum = 0;
for (auto const& value : pair.second) {
sum += value; // sum all values for the key
}
std::cout << "key: " << pair.first << ", sum: " << sum << '\n';
}
}
};
int main() {
// Get the start time
auto start = std::chrono::high_resolution_clock::now();
BuzzDB db;
std::ifstream inputFile("output.txt");
if (!inputFile) {
std::cerr << "Unable to open file" << std::endl;
return 1;
}
int field1, field2;
while (inputFile >> field1 >> field2) {
db.insert(field1, field2);
}
db.selectGroupBySum();
// Get the end time
auto end = std::chrono::high_resolution_clock::now();
// Calculate and print the elapsed time
std::chrono::duration<double> elapsed = end - start;
std::cout << "Elapsed time: " << elapsed.count() << " seconds" << std::endl;
return 0;
}