diff --git a/benchmark.zig b/benchmark.zig index bdaec6e..a980234 100644 --- a/benchmark.zig +++ b/benchmark.zig @@ -28,75 +28,74 @@ pub fn myLog( } pub fn main() !void { + const to_test = [_]usize{ 1, 10, 100, 1_000, 10_000, 100_000, 1_000_000 }; var line_buffer: [1024 * 1024]u8 = undefined; // Initialize your DBEngine here var db_engine = DBEngine.init("benchmark", "schema/example"); defer db_engine.deinit(); - // Reset the database - { - const null_term_query_str = try std.fmt.bufPrintZ(&line_buffer, "DELETE User {{}}", .{}); - var toker = ziqlTokenizer.init(null_term_query_str); - var parser = ziqlParser.init(&toker, &db_engine.file_engine, &db_engine.schema_engine); - try parser.parse(); + for (to_test) |users_count| { + // Populate with random dummy value + { + std.debug.print("\n=====================================\n\n", .{}); + std.debug.print("Populating with {d} users.\n", .{users_count}); + + var gpa = std.rand.DefaultPrng.init(0); + const populate_start_time = std.time.nanoTimestamp(); + for (users_count) |_| { + const name = names[gpa.random().uintAtMost(usize, names.len - 1)]; + const email = emails[gpa.random().uintAtMost(usize, emails.len - 1)]; + const age = gpa.random().uintAtMost(usize, 100); + const score = scores[gpa.random().uintAtMost(usize, scores.len - 1)]; + const null_term_query_str = try std.fmt.bufPrintZ( + &line_buffer, + "ADD User (name = '{s}', email='{s}', age={d}, scores=[ {d} ], best_friend=none, friends=none, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45)", + .{ name, email, age, score }, + ); + var toker = ziqlTokenizer.init(null_term_query_str); + var parser = ziqlParser.init(&toker, &db_engine.file_engine, &db_engine.schema_engine); + try parser.parse(); + } + const populate_end_time = std.time.nanoTimestamp(); + const populate_duration = @as(f64, @floatFromInt(populate_end_time - populate_start_time)) / 1e9; + + std.debug.print("Populate duration: {d:.6} seconds\n\n", .{populate_duration}); + + var buffer = std.ArrayList(u8).init(std.heap.page_allocator); + defer buffer.deinit(); + try db_engine.file_engine.writeDbMetrics(&buffer); + std.debug.print("{s}\n", .{buffer.items}); + std.debug.print("--------------------------------------\n\n", .{}); + } + + // Define your benchmark queries + { + const queries = [_][]const u8{ + "GRAB User {}", + "GRAB User [1] {}", + "GRAB User [name] {}", + "GRAB User {name = 'Charlie'}", + "GRAB User {age > 30}", + "DELETE User {}", + }; + + // Run benchmarks + for (queries) |query| { + const start_time = std.time.nanoTimestamp(); + + // Execute the query here + const null_term_query_str = try std.fmt.bufPrintZ(&line_buffer, "{s}", .{query}); + var toker = ziqlTokenizer.init(null_term_query_str); + var parser = ziqlParser.init(&toker, &db_engine.file_engine, &db_engine.schema_engine); + try parser.parse(); + + const end_time = std.time.nanoTimestamp(); + const duration = @as(f64, @floatFromInt(end_time - start_time)) / 1e9; + + std.debug.print("Query: \t\t{s}\nDuration: \t{d:.6} seconds\n\n", .{ query, duration }); + } + + std.debug.print("=====================================\n\n", .{}); + } } - - // Populate with random dummy value - std.debug.print("\n=====================================\n\n", .{}); - std.debug.print("Populating with {d} users.\n", .{10_000}); - - var gpa = std.rand.DefaultPrng.init(0); - const populate_start_time = std.time.nanoTimestamp(); - for (10_000) |_| { - const name = names[gpa.random().uintAtMost(usize, names.len - 1)]; - const email = emails[gpa.random().uintAtMost(usize, emails.len - 1)]; - const age = gpa.random().uintAtMost(usize, 100); - const score = scores[gpa.random().uintAtMost(usize, scores.len - 1)]; - const null_term_query_str = try std.fmt.bufPrintZ( - &line_buffer, - "ADD User (name = '{s}', email='{s}', age={d}, scores=[ {d} ], best_friend=none, friends=none, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45)", - .{ name, email, age, score }, - ); - var toker = ziqlTokenizer.init(null_term_query_str); - var parser = ziqlParser.init(&toker, &db_engine.file_engine, &db_engine.schema_engine); - try parser.parse(); - } - const populate_end_time = std.time.nanoTimestamp(); - const populate_duration = @as(f64, @floatFromInt(populate_end_time - populate_start_time)) / 1e9; - - std.debug.print("Populate duration: {d:.6} seconds\n\n", .{populate_duration}); - - var buffer = std.ArrayList(u8).init(std.heap.page_allocator); - defer buffer.deinit(); - try db_engine.file_engine.writeDbMetrics(&buffer); - std.debug.print("{s}\n", .{buffer.items}); - std.debug.print("--------------------------------------\n\n", .{}); - - // Define your benchmark queries - const queries = [_][]const u8{ - "GRAB User {}", - "GRAB User [1] {}", - "GRAB User [name] {}", - "GRAB User {name = 'Charlie'}", - "GRAB User {age > 30}", - "DELETE User {}", - }; - - // Run benchmarks - for (queries) |query| { - const start_time = std.time.nanoTimestamp(); - - // Execute the query here - const null_term_query_str = try std.fmt.bufPrintZ(&line_buffer, "{s}", .{query}); - var toker = ziqlTokenizer.init(null_term_query_str); - var parser = ziqlParser.init(&toker, &db_engine.file_engine, &db_engine.schema_engine); - try parser.parse(); - - const end_time = std.time.nanoTimestamp(); - const duration = @as(f64, @floatFromInt(end_time - start_time)) / 1e9; - - std.debug.print("Query: \t\t{s}\nDuration: \t{d:.6} seconds\n\n", .{ query, duration }); - } - - std.debug.print("=====================================\n\n", .{}); } diff --git a/lib/config.zig b/lib/config.zig index a5499ca..7575b89 100644 --- a/lib/config.zig +++ b/lib/config.zig @@ -8,6 +8,7 @@ pub const TEST_DATA_DIR = "data"; // Debug pub const PRINT_STATE = false; pub const DONT_SEND = true; +pub const DONT_SEND_ERROR = false; pub const RESET_LOG_AT_RESTART = false; // If true, will reset the log file at the start of the db, otherwise just keep adding to it // Help message diff --git a/src/fileEngine.zig b/src/fileEngine.zig index 50096be..3d38408 100644 --- a/src/fileEngine.zig +++ b/src/fileEngine.zig @@ -872,7 +872,7 @@ pub const FileEngine = struct { _ = sync_context.completeThread(); } - /// Will delete all entity based on the filter. Will also write a JSON format list of all UUID deleted into the buffer + /// Delete all entity based on the filter. Will also write a JSON format list of all UUID deleted into the buffer pub fn deleteEntities( self: *FileEngine, struct_name: []const u8, @@ -927,6 +927,7 @@ pub const FileEngine = struct { writer.writeByte(']') catch return FileEngineError.WriteError; } + /// TODO: Delete the file if it is not 0 and is empty at the end fn deleteEntitiesOneFile( sstruct: SchemaStruct, filter: ?Filter, @@ -940,7 +941,7 @@ pub const FileEngine = struct { defer fa.reset(); const allocator = fa.allocator(); - const path = std.fmt.bufPrint(&path_buffer, "{d}.zid", .{file_index}) catch |err| { + const path = std.fmt.allocPrint(allocator, "{d}.zid", .{file_index}) catch |err| { sync_context.logError("Error creating file path", err); return; }; @@ -951,8 +952,7 @@ pub const FileEngine = struct { }; defer iter.deinit(); - var new_path_buffer: [128]u8 = undefined; - const new_path = std.fmt.bufPrint(&new_path_buffer, "{d}.zid.new", .{file_index}) catch |err| { + const new_path = std.fmt.allocPrint(allocator, "{d}.zid.new", .{file_index}) catch |err| { sync_context.logError("Error creating file path", err); return; }; @@ -968,19 +968,20 @@ pub const FileEngine = struct { }; defer new_writer.deinit(); + var finish_writing = false; while (iter.next() catch |err| { sync_context.logError("Error during iter", err); return; }) |row| { - if (sync_context.checkStructLimit()) break; - if (filter == null or filter.?.evaluate(row)) { + if (!finish_writing and (filter == null or filter.?.evaluate(row))) { writer.print("{{\"{s}\"}},", .{UUID.format_bytes(row[0].UUID)}) catch |err| { sync_context.logError("Error writting", err); return; }; - if (sync_context.incrementAndCheckStructLimit()) break; + finish_writing = sync_context.incrementAndCheckStructLimit(); } else { + std.debug.print("Oups", .{}); new_writer.write(row) catch |err| { sync_context.logError("Error writing unchanged data", err); return; diff --git a/src/stuffs/utils.zig b/src/stuffs/utils.zig index defe277..a3ed74b 100644 --- a/src/stuffs/utils.zig +++ b/src/stuffs/utils.zig @@ -58,7 +58,7 @@ pub fn send(comptime format: []const u8, args: anytype) void { /// Print an error and send it to the user pointing to the token pub fn printError(message: []const u8, err: ZipponError, query: ?[]const u8, start: ?usize, end: ?usize) ZipponError { - if (config.DONT_SEND) return err; + if (config.DONT_SEND_ERROR) return err; fa.reset(); var buffer = std.ArrayList(u8).init(allocator);