Populate the UUIDFileIndex

Now each SchemaStruct have a UUIDFileIndex that allow to find the file
index of where an entity is based on it's UUID
This commit is contained in:
Adrien Bouvais 2024-11-17 16:40:12 +01:00
parent 5c8d2b6dc7
commit ca5de646d6
5 changed files with 26 additions and 14 deletions

View File

@ -192,14 +192,15 @@ pub const FileEngine = struct {
return count; return count;
} }
const UUIDFileIndex = @import("stuffs/UUIDFileIndex.zig").UUIDIndexMap;
/// Populate a map with all UUID bytes as key and file index as value /// Populate a map with all UUID bytes as key and file index as value
/// This map is store in the SchemaStruct to then by using a list of UUID, get a list of file_index to parse /// This map is store in the SchemaStruct to then by using a list of UUID, get a list of file_index to parse
pub fn populateFileIndexUUIDMap( pub fn populateFileIndexUUIDMap(
self: *FileEngine, self: *FileEngine,
struct_name: []const u8, sstruct: SchemaStruct,
map: *std.AutoHashMap(UUID, usize), map: *UUIDFileIndex,
) ZipponError!void { ) ZipponError!void {
const sstruct = try self.schema_engine.structName2SchemaStruct(struct_name);
const max_file_index = try self.maxFileIndex(sstruct.name); const max_file_index = try self.maxFileIndex(sstruct.name);
const dir = try utils.printOpenDir("{s}/DATA/{s}", .{ self.path_to_ZipponDB_dir, sstruct.name }, .{}); const dir = try utils.printOpenDir("{s}/DATA/{s}", .{ self.path_to_ZipponDB_dir, sstruct.name }, .{});
@ -211,14 +212,14 @@ pub const FileEngine = struct {
); );
// Create a thread-safe writer for each file // Create a thread-safe writer for each file
var thread_writer_list = self.allocator.alloc(std.ArrayList([16]u8), max_file_index + 1) catch return FileEngineError.MemoryError; var thread_writer_list = self.allocator.alloc(std.ArrayList(UUID), max_file_index + 1) catch return FileEngineError.MemoryError;
defer { defer {
for (thread_writer_list) |list| list.deinit(); for (thread_writer_list) |list| list.deinit();
self.allocator.free(thread_writer_list); self.allocator.free(thread_writer_list);
} }
for (thread_writer_list) |*list| { for (thread_writer_list) |*list| {
list.* = std.ArrayList([16]u8).init(self.allocator); list.* = std.ArrayList(UUID).init(self.allocator);
} }
// Spawn threads for each file // Spawn threads for each file

View File

@ -90,7 +90,7 @@ pub const DBEngine = struct {
defer allocator.free(schema_path); defer allocator.free(schema_path);
log.info("Schema founded in the database directory.", .{}); log.info("Schema founded in the database directory.", .{});
self.schema_engine = SchemaEngine.init(self.allocator, schema_path) catch |err| { self.schema_engine = SchemaEngine.init(self.allocator, schema_path, &self.file_engine) catch |err| {
log.err("Error when init SchemaEngine: {any}", .{err}); log.err("Error when init SchemaEngine: {any}", .{err});
self.state = .MissingSchemaEngine; self.state = .MissingSchemaEngine;
return self; return self;
@ -114,7 +114,7 @@ pub const DBEngine = struct {
if (potential_schema_path_or_environment_variable != null and potential_schema_path == null) allocator.free(potential_main_path_or_environment_variable.?); if (potential_schema_path_or_environment_variable != null and potential_schema_path == null) allocator.free(potential_main_path_or_environment_variable.?);
if (potential_schema_path_or_environment_variable) |schema_path| { if (potential_schema_path_or_environment_variable) |schema_path| {
log.info("Found schema path {s}.", .{schema_path}); log.info("Found schema path {s}.", .{schema_path});
self.schema_engine = SchemaEngine.init(self.allocator, schema_path) catch |err| { self.schema_engine = SchemaEngine.init(self.allocator, schema_path, &self.file_engine) catch |err| {
log.err("Error when init SchemaEngine: {any}", .{err}); log.err("Error when init SchemaEngine: {any}", .{err});
self.state = .MissingSchemaEngine; self.state = .MissingSchemaEngine;
return self; return self;

View File

@ -22,7 +22,7 @@ pub const SchemaEngine = struct {
struct_array: []SchemaStruct, struct_array: []SchemaStruct,
// The path is the path to the schema file // The path is the path to the schema file
pub fn init(allocator: Allocator, path: []const u8) ZipponError!SchemaEngine { pub fn init(allocator: Allocator, path: []const u8, file_engine: *FileEngine) ZipponError!SchemaEngine {
log.debug("Trying to init a SchemaEngine with path {s}", .{path}); log.debug("Trying to init a SchemaEngine with path {s}", .{path});
var schema_buf = allocator.alloc(u8, BUFFER_SIZE) catch return ZipponError.MemoryError; var schema_buf = allocator.alloc(u8, BUFFER_SIZE) catch return ZipponError.MemoryError;
defer allocator.free(schema_buf); defer allocator.free(schema_buf);
@ -40,6 +40,14 @@ pub const SchemaEngine = struct {
log.debug("SchemaEngine init with {d} SchemaStruct.", .{struct_array.items.len}); log.debug("SchemaEngine init with {d} SchemaStruct.", .{struct_array.items.len});
for (struct_array.items) |sstruct| {
file_engine.populateFileIndexUUIDMap(sstruct, sstruct.uuid_file_index) catch |err| {
log.err("Error populate file index UUID map {any}", .{err});
};
}
log.debug("SchemaEngine init with {d} SchemaStruct after populateFileIndexUUIDMap.", .{struct_array.items.len});
return SchemaEngine{ return SchemaEngine{
.allocator = allocator, .allocator = allocator,
.null_terminated_schema_buff = null_terminated_schema_buff, .null_terminated_schema_buff = null_terminated_schema_buff,
@ -119,13 +127,14 @@ pub const SchemaEngine = struct {
/// Chech if the name of a struct is in the current schema /// Chech if the name of a struct is in the current schema
pub fn isStructNameExists(self: *SchemaEngine, struct_name: []const u8) bool { pub fn isStructNameExists(self: *SchemaEngine, struct_name: []const u8) bool {
var i: u16 = 0; var i: u16 = 0;
log.debug("\n\n{any}\n\n", .{self.struct_array});
while (i < self.struct_array.len) : (i += 1) if (std.mem.eql(u8, self.struct_array[i].name, struct_name)) return true; while (i < self.struct_array.len) : (i += 1) if (std.mem.eql(u8, self.struct_array[i].name, struct_name)) return true;
return false; return false;
} }
/// Check if a struct have the member name /// Check if a struct have the member name
pub fn isMemberNameInStruct(self: *SchemaEngine, struct_name: []const u8, member_name: []const u8) ZipponError!bool { pub fn isMemberNameInStruct(self: *SchemaEngine, struct_name: []const u8, member_name: []const u8) ZipponError!bool {
for (try self.structName2structMembers(struct_name)) |mn| { // I do not return an error here because I should already check before is the struct exist for (try self.structName2structMembers(struct_name)) |mn| {
if (std.mem.eql(u8, mn, member_name)) return true; if (std.mem.eql(u8, mn, member_name)) return true;
} }
return false; return false;

View File

@ -44,8 +44,8 @@ pub const Parser = struct {
members: [][]const u8, members: [][]const u8,
types: []DataType, types: []DataType,
zid_schema: []zid.DType, zid_schema: []zid.DType,
links: std.StringHashMap([]const u8), // Map key as member_name and value as struct_name, like a dtype links: std.StringHashMap([]const u8), // Map key as member_name and value as struct_name of the link
uuid_file_index: UUIDFileIndex, // Map UUID to the index of the file it is are store in uuid_file_index: *UUIDFileIndex, // Map UUID to the index of the file store in
pub fn init( pub fn init(
allocator: Allocator, allocator: Allocator,
@ -54,6 +54,8 @@ pub const Parser = struct {
types: []DataType, types: []DataType,
links: std.StringHashMap([]const u8), links: std.StringHashMap([]const u8),
) SchemaParserError!SchemaStruct { ) SchemaParserError!SchemaStruct {
const uuid_file_index = allocator.create(UUIDFileIndex) catch return SchemaParserError.MemoryError;
uuid_file_index.* = UUIDFileIndex.init(allocator) catch return SchemaParserError.MemoryError;
return SchemaStruct{ return SchemaStruct{
.allocator = allocator, .allocator = allocator,
.name = name, .name = name,
@ -61,7 +63,7 @@ pub const Parser = struct {
.types = types, .types = types,
.zid_schema = SchemaStruct.fileDataSchema(allocator, types) catch return SchemaParserError.MemoryError, .zid_schema = SchemaStruct.fileDataSchema(allocator, types) catch return SchemaParserError.MemoryError,
.links = links, .links = links,
.uuid_file_index = UUIDFileIndex.init(allocator) catch return SchemaParserError.MemoryError, .uuid_file_index = uuid_file_index,
}; };
} }
@ -71,6 +73,7 @@ pub const Parser = struct {
self.allocator.free(self.zid_schema); self.allocator.free(self.zid_schema);
self.links.deinit(); self.links.deinit();
self.uuid_file_index.deinit(); self.uuid_file_index.deinit();
self.allocator.destroy(self.uuid_file_index);
} }
fn fileDataSchema(allocator: Allocator, dtypes: []DataType) SchemaParserError![]zid.DType { fn fileDataSchema(allocator: Allocator, dtypes: []DataType) SchemaParserError![]zid.DType {

View File

@ -145,7 +145,6 @@ test "Multiple Node UUIDIndexMap with Deep Subdivisions" {
for (non_existent_uuids) |uuid_str| { for (non_existent_uuids) |uuid_str| {
const uuid = try UUID.parse(uuid_str); const uuid = try UUID.parse(uuid_str);
std.debug.print("{s}\n", .{uuid_str});
try std.testing.expect(!imap.contains(uuid)); try std.testing.expect(!imap.contains(uuid));
try std.testing.expectEqual(imap.get(uuid), null); try std.testing.expectEqual(imap.get(uuid), null);
} }
@ -164,7 +163,7 @@ test "Multiple Node UUIDIndexMap with Deep Subdivisions" {
} }
} }
test "Radix benchmark insert" { test "UUIDIndexMap benchmark" {
const allocator = std.testing.allocator; const allocator = std.testing.allocator;
var imap = try UUIDIndexMap.init(allocator); var imap = try UUIDIndexMap.init(allocator);