-
Notifications
You must be signed in to change notification settings - Fork 3
/
06-buzzdb.cpp
177 lines (143 loc) · 4.55 KB
/
06-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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <iostream>
#include <map>
#include <vector>
#include <fstream>
#include <iostream>
#include <chrono>
#include <iostream>
#include <map>
#include <string>
#include <memory>
enum FieldType { INT, FLOAT, STRING };
// Define a basic Field variant class that can hold different types
class Field {
public:
FieldType type;
int data_i;
float data_f;
std::unique_ptr<char[]> data_s;
size_t data_s_length;
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_length = s.size() + 1;
data_s = std::make_unique<char[]>(data_s_length);
strcpy(data_s.get(), s.c_str());
}
// Copy assignment operator
Field& operator=(const Field& other) {
if (&other == this) {
return *this;
}
type = other.type;
switch(type){
case INT:
data_i = other.data_i; break;
case FLOAT:
data_f = other.data_f; break;
case STRING:
data_s_length = other.data_s_length;
data_s = std::make_unique<char[]>(data_s_length);
strcpy(data_s.get(), other.data_s.get());
break;
}
return *this;
}
// Copy constructor
Field(Field&& other){
type = other.type;
switch(type){
case INT:
data_i = other.data_i; break;
case FLOAT:
data_f = other.data_f; break;
case STRING:
data_s_length = other.data_s_length;
data_s = std::make_unique<char[]>(data_s_length);
strcpy(data_s.get(), other.data_s.get());
break;
}
}
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.get()); }
void print() const{
switch(getType()){
case INT: std::cout << data_i; break;
case FLOAT: std::cout << data_f; break;
case STRING: std::cout << std::string(data_s.get()); break;
}
}
};
class Tuple {
std::vector<std::unique_ptr<Field>> fields;
public:
void addField(std::unique_ptr<Field> field) {
fields.push_back(std::move(field));
}
void print() const {
for (const auto& field : fields) {
field->print();
std::cout << " ";
}
std::cout << "\n";
}
};
class BuzzDB {
private:
// a map is an ordered key-value container
std::map<int, std::vector<int>> index;
public:
size_t number_of_tuples = 4;
// a vector of Tuple unique pointers acting as a table
std::vector<std::unique_ptr<Tuple>> table;
// insert function
void insert(int key, int value) {
auto newTuple = std::make_unique<Tuple>();
auto key_field = std::make_unique<Field>(key);
auto value_field = std::make_unique<Field>(value);
float float_val = 132.04;
auto float_field = std::make_unique<Field>(float_val);
auto string_field = std::make_unique<Field>("buzzdb");
newTuple->addField(std::move(key_field));
newTuple->addField(std::move(value_field));
newTuple->addField(std::move(float_field));
newTuple->addField(std::move(string_field));
//newTuple->print();
table.push_back(std::move(newTuple));
index[key].push_back(value);
}
// 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;
}