From 672d79cbea712e528ac0efacacc5f28fc6036aa1 Mon Sep 17 00:00:00 2001 From: MrBounty Date: Tue, 14 Jan 2025 22:32:31 +0100 Subject: [PATCH] Add config and schema for benchmark --- benchmark.zig | 176 +++++++++++++++++++-------------------- lib/config.zig | 16 +++- lib/config_benchmark.zig | 73 ++++++++++++++++ schema/benchmark | 20 +++++ 4 files changed, 193 insertions(+), 92 deletions(-) create mode 100644 lib/config_benchmark.zig create mode 100644 schema/benchmark diff --git a/benchmark.zig b/benchmark.zig index cb85c89..7ddf2ab 100644 --- a/benchmark.zig +++ b/benchmark.zig @@ -29,36 +29,49 @@ pub fn myLog( } pub fn main() !void { - const to_test = [_]usize{500_000}; - { - var line_buffer: [1024 * 1024]u8 = undefined; - var db_engine = DBEngine.init("benchmark", "schema/example"); + const to_test = [_]usize{ 500, 50_000, 5_000_000 }; + var line_buffer: [1024 * 1024]u8 = undefined; + for (to_test) |users_count| { + var db_engine = DBEngine.init("benchmarkDB", "schema/benchmark"); defer db_engine.deinit(); - for (to_test) |users_count| { - { - const null_term_query_str = try std.fmt.bufPrintZ(&line_buffer, "DELETE User {{}}", .{}); - var parser = ziqlParser.init(&db_engine.file_engine, &db_engine.schema_engine); - try parser.parse(null_term_query_str); - } - // Populate with random dummy value - // Need some speed up, spended times to find that it is the parsonConditionValue that take time, the last switch to be exact, that parse str to value - { - std.debug.print("\n=====================================\n\n", .{}); - std.debug.print("Populating with {d} users.\n", .{users_count}); + { + const null_term_query_str = try std.fmt.bufPrintZ(&line_buffer, "DELETE User {{}}", .{}); + var parser = ziqlParser.init(&db_engine.file_engine, &db_engine.schema_engine); + try parser.parse(null_term_query_str); + } + // Populate with random dummy value + // Need some speed up, spended times to find that it is the parsonConditionValue that take time, the last switch to be exact, that parse str to value + { + std.debug.print("\n=====================================\n\n", .{}); + std.debug.print("Populating with {d} users.\n", .{users_count}); - const allocator = std.heap.page_allocator; + const allocator = std.heap.page_allocator; - var prng = std.rand.DefaultPrng.init(0); - const rng = prng.random(); - const populate_start_time = std.time.nanoTimestamp(); + var prng = std.rand.DefaultPrng.init(0); + const rng = prng.random(); + const populate_start_time = std.time.nanoTimestamp(); - var array = std.ArrayList(u8).init(allocator); - defer array.deinit(); - var writer = array.writer(); + var array = std.ArrayList(u8).init(allocator); + defer array.deinit(); + var writer = array.writer(); + try writer.print( + "ADD User (name = '{s}', email='{s}')", + .{ + names[rng.uintAtMost(usize, names.len - 1)], + emails[rng.uintAtMost(usize, emails.len - 1)], + rng.uintAtMost(usize, 100), + scores[rng.uintAtMost(usize, scores.len - 1)], + dates[rng.uintAtMost(usize, dates.len - 1)], + times[rng.uintAtMost(usize, times.len - 1)], + datetimes[rng.uintAtMost(usize, datetimes.len - 1)], + }, + ); + + for (users_count - 1) |_| { try writer.print( - "ADD User (name = '{s}', email='{s}', age={d}, scores=[ {d} ], best_friend=none, friends=none, bday={s}, a_time={s}, last_order={s})", + "('{s}', '{s}', {d}, [ {d} ], none, none, {s}, {s}, {s})", .{ names[rng.uintAtMost(usize, names.len - 1)], emails[rng.uintAtMost(usize, emails.len - 1)], @@ -69,81 +82,66 @@ pub fn main() !void { datetimes[rng.uintAtMost(usize, datetimes.len - 1)], }, ); + } - for (users_count - 1) |_| { - try writer.print( - "('{s}', '{s}', {d}, [ {d} ], none, none, {s}, {s}, {s})", - .{ - names[rng.uintAtMost(usize, names.len - 1)], - emails[rng.uintAtMost(usize, emails.len - 1)], - rng.uintAtMost(usize, 100), - scores[rng.uintAtMost(usize, scores.len - 1)], - dates[rng.uintAtMost(usize, dates.len - 1)], - times[rng.uintAtMost(usize, times.len - 1)], - datetimes[rng.uintAtMost(usize, datetimes.len - 1)], - }, - ); - } + const null_term_query_str = try std.fmt.allocPrintZ(allocator, "{s}", .{array.items}); + defer allocator.free(null_term_query_str); - const null_term_query_str = try std.fmt.allocPrintZ(allocator, "{s}", .{array.items}); - defer allocator.free(null_term_query_str); + var parser = ziqlParser.init(&db_engine.file_engine, &db_engine.schema_engine); + try parser.parse(null_term_query_str); + 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", .{}); + } + + //{ + // for (db_engine.schema_engine.struct_array) |sstruct| { + // const mb: f64 = @as(f64, @floatFromInt(sstruct.uuid_file_index.arena.queryCapacity())) / 1024.0 / 1024.0; + // std.debug.print("Sstruct: {s}\n", .{sstruct.name}); + // std.debug.print("Memory: {d:.2}Mb\n", .{mb}); + // std.debug.print("Count: {d}\n\n", .{sstruct.uuid_file_index.map.count()}); + // 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}", + "GRAB User {bday > 2000/01/01}", + "GRAB User {age > 30 AND name = 'Charlie' AND bday > 2000/01/01}", + "GRAB User {best_friend IN {name = 'Charlie'}}", + "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 parser = ziqlParser.init(&db_engine.file_engine, &db_engine.schema_engine); try parser.parse(null_term_query_str); - const populate_end_time = std.time.nanoTimestamp(); - const populate_duration = @as(f64, @floatFromInt(populate_end_time - populate_start_time)) / 1e9; + const end_time = std.time.nanoTimestamp(); + const duration = @as(f64, @floatFromInt(end_time - start_time)) / 1e6; - 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", .{}); + std.debug.print("Query: \t\t{s}\nDuration: \t{d:.6} ms\n\n", .{ query, duration }); } - //{ - // for (db_engine.schema_engine.struct_array) |sstruct| { - // const mb: f64 = @as(f64, @floatFromInt(sstruct.uuid_file_index.arena.queryCapacity())) / 1024.0 / 1024.0; - // std.debug.print("Sstruct: {s}\n", .{sstruct.name}); - // std.debug.print("Memory: {d:.2}Mb\n", .{mb}); - // std.debug.print("Count: {d}\n\n", .{sstruct.uuid_file_index.map.count()}); - // 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}", - "GRAB User {bday > 2000/01/01}", - "GRAB User {age > 30 AND name = 'Charlie' AND bday > 2000/01/01}", - "GRAB User {best_friend IN {name = 'Charlie'}}", - "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 parser = ziqlParser.init(&db_engine.file_engine, &db_engine.schema_engine); - try parser.parse(null_term_query_str); - - const end_time = std.time.nanoTimestamp(); - const duration = @as(f64, @floatFromInt(end_time - start_time)) / 1e6; - - std.debug.print("Query: \t\t{s}\nDuration: \t{d:.6} ms\n\n", .{ query, duration }); - } - - std.debug.print("=====================================\n\n", .{}); - } + std.debug.print("=====================================\n\n", .{}); } } } diff --git a/lib/config.zig b/lib/config.zig index 894fd66..9ead0e9 100644 --- a/lib/config.zig +++ b/lib/config.zig @@ -17,6 +17,7 @@ pub const HELP_MESSAGE = struct { \\run To run a query. \\db Create or chose a database. \\schema Initialize the database schema. + \\dump To export data in other format and backup. \\quit Stop the CLI with memory safety. \\ \\For more informations: https://mrbounty.github.io/ZipponDB/cli @@ -24,9 +25,9 @@ pub const HELP_MESSAGE = struct { ; pub const db: []const u8 = \\Available commands: - \\new Create a new database using a path to a sub folder. - \\use Select an existing folder to use as database. + \\use Select or create a folder to use as database. \\metrics Print some metrics of the current database. + \\state Print the current db state (Ok, MissingSchemaEngine, MissingFileEngine). \\ \\For more informations: https://mrbounty.github.io/ZipponDB/cli \\ @@ -34,7 +35,16 @@ pub const HELP_MESSAGE = struct { pub const schema: []const u8 = \\Available commands: \\describe Print the schema use by the currently database. - \\init Take the path to a schema file and initialize the database. + \\use Take the path to a schema file and initialize the database. + \\ + \\For more informations: https://mrbounty.github.io/ZipponDB/cli + \\ + ; + pub const dump: []const u8 = + \\Available commands: + \\csv Export all database in a csv format. + \\json Export all database in a json format. (Not implemented) + \\zid Export all database in a zid format. (Not implemented) \\ \\For more informations: https://mrbounty.github.io/ZipponDB/cli \\ diff --git a/lib/config_benchmark.zig b/lib/config_benchmark.zig new file mode 100644 index 0000000..1d512ec --- /dev/null +++ b/lib/config_benchmark.zig @@ -0,0 +1,73 @@ +pub const BUFFER_SIZE = 1024 * 10; // Used a bit everywhere. The size for the schema for example. 10kB +pub const MAX_FILE_SIZE = 1024 * 1024; // 1MB +pub const CPU_CORE = 16; + +// 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 +pub const HELP_MESSAGE = struct { + pub const main: []const u8 = + \\Welcome to ZipponDB v0.2! + \\ + \\Available commands: + \\run To run a query. + \\db Create or chose a database. + \\schema Initialize the database schema. + \\dump To export data in other format and backup. + \\quit Stop the CLI with memory safety. + \\ + \\For more informations: https://mrbounty.github.io/ZipponDB/cli + \\ + ; + pub const db: []const u8 = + \\Available commands: + \\use Select or create a folder to use as database. + \\metrics Print some metrics of the current database. + \\state Print the current db state (Ok, MissingSchemaEngine, MissingFileEngine). + \\ + \\For more informations: https://mrbounty.github.io/ZipponDB/cli + \\ + ; + pub const schema: []const u8 = + \\Available commands: + \\describe Print the schema use by the currently database. + \\use Take the path to a schema file and initialize the database. + \\ + \\For more informations: https://mrbounty.github.io/ZipponDB/cli + \\ + ; + pub const dump: []const u8 = + \\Available commands: + \\csv Export all database in a csv format. + \\json Export all database in a json format. (Not implemented) + \\zid Export all database in a zid format. (Not implemented) + \\ + \\For more informations: https://mrbounty.github.io/ZipponDB/cli + \\ + ; + pub const no_engine: []const u8 = + \\To start using ZipponDB you need to create a new database. + \\This is a directory/folder that will be use to store data, logs, backup, ect. + \\To create one use 'db new path/to/directory'. E.g. 'db new data'. + \\Or use an existing one with 'db use'. + \\ + \\You can also set the environment variable ZIPPONDB_PATH to the desire path. + \\ + \\For more informations: https://mrbounty.github.io/ZipponDB/cli + \\ + ; + pub const no_schema: []const u8 = + \\A database was found here `{s}` but no schema find inside. + \\To start a database, you need to attach it a schema using a schema file. + \\By using 'schema init path/to/schema'. For more informations on how to create a schema: TODO add link + \\ + \\You can also set the environment variable ZIPPONDB_SCHEMA to the path to a schema file. + \\ + \\For more informations: https://mrbounty.github.io/ZipponDB/Schema + \\ + ; +}; diff --git a/schema/benchmark b/schema/benchmark new file mode 100644 index 0000000..84a9f5f --- /dev/null +++ b/schema/benchmark @@ -0,0 +1,20 @@ +User ( + name: str, + email: str, + orders: []Order, +) + +Order ( + items: []Item, + at: datetime, +) + +Item ( + name: str, + price: float, + category: Category, +) + +Category ( + name: str, +)