Skip to content

Commit 82c460f

Browse files
committed
Adding some small reworking in QPEMPI, QPEOMP
1 parent af1731e commit 82c460f

File tree

8 files changed

+308
-34
lines changed

8 files changed

+308
-34
lines changed

QPEMPI

2.66 KB
Binary file not shown.

QPEMPI.c

Lines changed: 247 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,133 @@
44
#include <stdio.h>
55
#include <stdlib.h>
66
#include <string.h>
7+
#include <strings.h> // For strcasecmp
78
#include <time.h>
89
#include <mpi.h>
910
#include "../include/executeEngine-serial.h"
1011
#include "../include/connectEngine.h"
12+
#include "../include/printHelper.h"
13+
14+
// Optimal indexes constant
15+
const char* optimalIndexes[] = {
16+
"command_id",
17+
"user_id",
18+
"risk_level",
19+
"exit_code",
20+
"sudo_used"
21+
};
22+
const FieldType optimalIndexTypes[] = {
23+
FIELD_UINT64,
24+
FIELD_INT,
25+
FIELD_INT,
26+
FIELD_INT,
27+
FIELD_BOOL
28+
};
29+
const int numOptimalIndexes = 5;
30+
1131
// ANSI color codes for pretty printing
1232
#define CYAN "\x1b[36m"
1333
#define YELLOW "\x1b[33m"
1434
#define BOLD "\x1b[1m"
1535
#define RESET "\x1b[0m"
1636

37+
// Helper to safely copy strings with truncation
38+
static inline void safe_copy(char *dst, size_t n, const char *src) {
39+
snprintf(dst, n, "%.*s", (int)n - 1, src);
40+
}
41+
42+
// Helper to map Parser OperatorType to string
43+
const char* get_operator_string(OperatorType op) {
44+
switch (op) {
45+
case OP_EQ: return "=";
46+
case OP_NEQ: return "!=";
47+
case OP_GT: return ">";
48+
case OP_LT: return "<";
49+
case OP_GTE: return ">=";
50+
case OP_LTE: return "<=";
51+
default: return "=";
52+
}
53+
}
54+
55+
// Helper to map Parser LogicOperator to string
56+
const char* get_logic_op_string(LogicOperator op) {
57+
switch (op) {
58+
case LOGIC_AND: return "AND";
59+
case LOGIC_OR: return "OR";
60+
default: return "AND";
61+
}
62+
}
63+
64+
// Helper to convert ParsedSQL conditions to engine's whereClauseS linked list
65+
struct whereClauseS* convert_conditions(ParsedSQL *parsed) {
66+
if (parsed->num_conditions == 0) return NULL;
67+
68+
struct whereClauseS *head = NULL;
69+
struct whereClauseS *current = NULL;
70+
71+
for (int i = 0; i < parsed->num_conditions; i++) {
72+
struct whereClauseS *node = malloc(sizeof(struct whereClauseS));
73+
74+
if (parsed->conditions[i].is_nested && parsed->conditions[i].nested_sql) {
75+
node->attribute = NULL;
76+
node->operator = NULL;
77+
node->value = NULL;
78+
node->value_type = 0;
79+
node->sub = convert_conditions(parsed->conditions[i].nested_sql);
80+
} else {
81+
node->attribute = parsed->conditions[i].column;
82+
node->operator = get_operator_string(parsed->conditions[i].op);
83+
node->value = parsed->conditions[i].value;
84+
85+
// Simple type inference for the test
86+
if (parsed->conditions[i].is_numeric) {
87+
node->value_type = 0; // Integer/Number
88+
} else {
89+
node->value_type = 1; // String
90+
}
91+
node->sub = NULL;
92+
}
93+
94+
node->next = NULL;
95+
96+
if (i < parsed->num_conditions - 1) {
97+
node->logical_op = get_logic_op_string(parsed->logic_ops[i]);
98+
} else {
99+
node->logical_op = NULL;
100+
}
101+
102+
if (head == NULL) {
103+
head = node;
104+
current = node;
105+
} else {
106+
current->next = node;
107+
current = node;
108+
}
109+
}
110+
return head;
111+
}
112+
113+
// Helper to free the manually constructed where clause
114+
void free_where_clause_list(struct whereClauseS *head) {
115+
while (head) {
116+
struct whereClauseS *temp = head;
117+
head = head->next;
118+
free(temp);
119+
}
120+
}
121+
17122
int main(int argc, char *argv[]) {
18123

19-
// NOTE: defaulting to sample queries file for ease of testing. Can implement CLI arg later.
20-
(void)argc; (void)argv; // Unused for now. Prevent warnings.
124+
// Initialize MPI Environment
125+
MPI_Init(&argc, &argv);
126+
int rank, size;
127+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
128+
MPI_Comm_size(MPI_COMM_WORLD, &size);
129+
130+
set_rank(rank);
21131

22132
// Start a timer for total runtime statistics
23-
clock_t totalStart = clock();
133+
double totalStart = MPI_Wtime();
24134

25135
// Instantiate an engine object to handle the execution of the query
26136
struct engineS *engine = initializeEngineSerial(
@@ -32,14 +142,15 @@ int main(int argc, char *argv[]) {
32142
);
33143

34144
// End timer for engine initialization
35-
double initTimeTaken = ((double)clock() - totalStart) / CLOCKS_PER_SEC;
145+
double initTimeTaken = MPI_Wtime() - totalStart;
36146

37147
// Load the COMMANDS into memory (from COMMAND text file)
38148
const char *query_file = "sample-queries.txt";
39149
FILE *fp = fopen(query_file, "r");
40150
if (!fp) {
41-
perror("Failed to open query file");
151+
if (rank == 0) perror("Failed to open query file");
42152
destroyEngineSerial(engine);
153+
MPI_Finalize();
43154
return EXIT_FAILURE;
44155
}
45156

@@ -49,47 +160,157 @@ int main(int argc, char *argv[]) {
49160

50161
char *buffer = malloc(fsize + 1);
51162
if (!buffer) {
52-
perror("Failed to allocate memory for query file");
163+
if (rank == 0) perror("Failed to allocate memory for query file");
53164
fclose(fp);
54165
destroyEngineSerial(engine);
166+
MPI_Finalize();
55167
return EXIT_FAILURE;
56168
}
57169
size_t read_size = fread(buffer, 1, fsize, fp);
58170
if (read_size != (size_t)fsize) {
59-
perror("Failed to read query file");
171+
if (rank == 0) perror("Failed to read query file");
60172
free(buffer);
61173
fclose(fp);
62174
destroyEngineSerial(engine);
175+
MPI_Finalize();
63176
return EXIT_FAILURE;
64177
}
65178
buffer[fsize] = 0;
66179
fclose(fp);
67180

68181
// End timer for loading queries
69-
double loadTimeTaken = ((double)clock() - totalStart) / CLOCKS_PER_SEC;
70-
71-
// Run each command from the command input file
72-
char *query = strtok(buffer, ";");
73-
while (query) {
74-
// Trim whitespace
75-
query = trim(query);
76-
if (*query) {
77-
run_test_query(engine, query, ROW_LIMIT); // Limit output to 10 rows for testing
182+
double loadTimeTaken = MPI_Wtime() - totalStart;
183+
184+
// Split queries into an array
185+
#define MAX_QUERIES 1000
186+
char *queries[MAX_QUERIES];
187+
int query_count = 0;
188+
189+
char *token = strtok(buffer, ";");
190+
while (token && query_count < MAX_QUERIES) {
191+
queries[query_count++] = token;
192+
token = strtok(NULL, ";");
193+
}
194+
195+
// Execute Queries
196+
for (int i = 0; i < query_count; i++) {
197+
char *query = trim(queries[i]);
198+
if (!*query) continue;
199+
200+
// Tokenize
201+
Token tokens[MAX_TOKENS];
202+
int num_tokens = tokenize(query, tokens, MAX_TOKENS);
203+
204+
ParsedSQL parsed;
205+
struct resultSetS *result = NULL;
206+
bool success = false;
207+
double execTime = 0;
208+
int rowsAffected = 0;
209+
bool parseFailed = false;
210+
211+
if (num_tokens > 0) {
212+
parsed = parse_tokens(tokens);
213+
214+
// Prepare Select Items
215+
const char *selectItems[parsed.num_columns > 0 ? parsed.num_columns : 1];
216+
int numSelectItems = 0;
217+
if (!parsed.select_all) {
218+
numSelectItems = parsed.num_columns;
219+
for (int k = 0; k < numSelectItems; k++) selectItems[k] = parsed.columns[k];
220+
}
221+
222+
double start = MPI_Wtime();
223+
224+
// Execute based on command type
225+
if (parsed.command == CMD_INSERT) {
226+
if (parsed.num_values == 12) {
227+
record r;
228+
r.command_id = strtoull(parsed.insert_values[0], NULL, 10);
229+
safe_copy(r.raw_command, sizeof(r.raw_command), parsed.insert_values[1]);
230+
safe_copy(r.base_command, sizeof(r.base_command), parsed.insert_values[2]);
231+
safe_copy(r.shell_type, sizeof(r.shell_type), parsed.insert_values[3]);
232+
r.exit_code = atoi(parsed.insert_values[4]);
233+
safe_copy(r.timestamp, sizeof(r.timestamp), parsed.insert_values[5]);
234+
r.sudo_used = (strcasecmp(parsed.insert_values[6], "true") == 0 || strcmp(parsed.insert_values[6], "1") == 0);
235+
safe_copy(r.working_directory, sizeof(r.working_directory), parsed.insert_values[7]);
236+
r.user_id = atoi(parsed.insert_values[8]);
237+
safe_copy(r.user_name, sizeof(r.user_name), parsed.insert_values[9]);
238+
safe_copy(r.host_name, sizeof(r.host_name), parsed.insert_values[10]);
239+
r.risk_level = atoi(parsed.insert_values[11]);
240+
241+
success = executeQueryInsertSerial(engine, parsed.table, &r);
242+
}
243+
}
244+
else if (parsed.command == CMD_DELETE) {
245+
struct whereClauseS *whereClause = convert_conditions(&parsed);
246+
result = executeQueryDeleteSerial(engine, parsed.table, whereClause);
247+
if (result) rowsAffected = result->numRecords;
248+
free_where_clause_list(whereClause);
249+
}
250+
else if (parsed.command == CMD_SELECT) {
251+
struct whereClauseS *whereClause = convert_conditions(&parsed);
252+
result = executeQuerySelectSerial(engine, selectItems, numSelectItems, parsed.table, whereClause);
253+
free_where_clause_list(whereClause);
254+
}
255+
256+
execTime = MPI_Wtime() - start;
257+
} else {
258+
parseFailed = true;
259+
}
260+
261+
// Print results (Rank 0 only)
262+
if (rank == 0) {
263+
printf("Executing Query: %s\n", query);
264+
265+
if (parseFailed) {
266+
printf("Tokenization failed.\n");
267+
} else {
268+
if (parsed.command == CMD_INSERT) {
269+
if (parsed.num_values != 12) {
270+
printf("Error: INSERT requires exactly 12 values.\n");
271+
} else if (success) {
272+
printf("Insert successful. Execution Time: %ld\n\n", (long)execTime);
273+
} else {
274+
printf("Insert failed. Execution Time: %ld\n\n", (long)execTime);
275+
}
276+
} else if (parsed.command == CMD_DELETE) {
277+
if (result) {
278+
printf("Delete successful. Rows affected: %d. Execution Time: %ld\n\n", rowsAffected, (long)execTime);
279+
} else {
280+
printf("Delete failed. Execution Time: %ld\n\n", (long)execTime);
281+
}
282+
} else if (parsed.command == CMD_SELECT) {
283+
printTable(NULL, result, ROW_LIMIT);
284+
printf("\n");
285+
} else if (parsed.command == CMD_NONE) {
286+
printf("No command detected.\n");
287+
} else {
288+
fprintf(stderr, "Unsupported command.\n");
289+
}
290+
}
78291
}
79-
query = strtok(NULL, ";");
292+
293+
// Cleanup
294+
if (result) freeResultSet(result);
295+
}
296+
297+
// Print total runtime statistics in pretty colors (Rank 0 only)
298+
if (rank == 0) {
299+
double totalTimeTaken = MPI_Wtime() - totalStart;
300+
printf(CYAN "======= Execution Summary =======" RESET "\n");
301+
printf(CYAN "Engine Initialization Time: " RESET YELLOW "%.4f seconds\n" RESET, initTimeTaken);
302+
printf(CYAN "Query Loading Time: " RESET YELLOW "%.4f seconds\n" RESET, loadTimeTaken - initTimeTaken);
303+
printf(CYAN "Query Execution Time: " RESET YELLOW "%.4f seconds\n" RESET, totalTimeTaken - loadTimeTaken);
304+
printf(BOLD CYAN "Total Execution Time: " RESET BOLD YELLOW "%.4f seconds" RESET "\n", totalTimeTaken);
305+
printf(CYAN "=================================" RESET "\n");
80306
}
81307

308+
printf("Rank %d: Freeing buffer...\n", rank);
82309
free(buffer);
310+
printf("Rank %d: Destroying engine...\n", rank);
83311
destroyEngineSerial(engine);
312+
printf("Rank %d: Finalizing MPI...\n", rank);
84313

85-
// Print total runtime statistics in pretty colors
86-
double totalTimeTaken = ((double)clock() - totalStart) / CLOCKS_PER_SEC;
87-
printf(CYAN "======= Execution Summary =======" RESET "\n");
88-
printf(CYAN "Engine Initialization Time: " RESET YELLOW "%.4f seconds\n" RESET, initTimeTaken);
89-
printf(CYAN "Query Loading Time: " RESET YELLOW "%.4f seconds\n" RESET, loadTimeTaken - initTimeTaken);
90-
printf(CYAN "Query Execution Time: " RESET YELLOW "%.4f seconds\n" RESET, totalTimeTaken - loadTimeTaken);
91-
printf(BOLD CYAN "Total Execution Time: " RESET BOLD YELLOW "%.4f seconds" RESET "\n", totalTimeTaken);
92-
printf(CYAN "=================================" RESET "\n");
93-
314+
MPI_Finalize();
94315
return EXIT_SUCCESS;
95316
}

QPEOMP

1.25 KB
Binary file not shown.

QPEOMP.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ int main(int argc, char *argv[]) {
8585
char *queries[MAX_QUERIES];
8686
int query_count = 0;
8787

88+
// Run sequentially to populate queries array
8889
char *token = strtok(buffer, ";");
8990
while (token && query_count < MAX_QUERIES) {
9091
queries[query_count++] = token;

data-generation/commands_50k.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:1d15318ad80df8c008791999259cac59361f92f9ff760d12ba2559e6ef16e355
3-
size 5926893
2+
oid sha256:6370fe8184a67ba00d77f3d85a70d304e6eaf9130dbca3ae7fe1a9ef08a5f997
3+
size 1689183

0 commit comments

Comments
 (0)