Building flora64: A Deep Dive into the Architecture
flora64 is built with performance and flexibility in mind, using Zig as our core language for its low-level control and safety features. Let’s explore the architectural decisions that make flora64 unique.
Core Architecture Components
Database Core (db.zig)
The heart of flora64 is implemented in db.zig, which provides the main database interface:
pub fn init(path: []const u8, allocator: std.mem.Allocator) (Uri.ParseError || DbError)!Db {
return .{ .path = path, .tables = TableCollection.init(allocator), .allocator = allocator };
}
Key features of our database core:
- Memory-efficient table management using StringHashMap
- Custom allocator support for fine-grained memory control
- Table count limits for resource management
- Error handling for robustness
Table Management
Tables in flora64 are designed with flexibility in mind:
pub fn table(self: *@This(), name: []const u8, schema: Schema) !*Table {
if (self.tables.count() >= Options.max_number_tables) {
logger.err("Reached max count of tables {d}", .{self.tables.count()});
return error.TableCountExceed;
}
const table_ptr = try self.allocator.create(Table);
table_ptr.* = Table.init(schema, self.allocator);
try self.tables.put(name, table_ptr);
return table_ptr;
}
Design Philosophy
Memory Safety First
- Using Zig’s compile-time safety features
- Custom allocators for memory management
- Clear ownership semantics
Performance Optimization
- Arena allocators for bulk operations
- Efficient string and memory handling
- Optimized table operations
Developer Experience
- Clear error handling
- Consistent API design
- Comprehensive testing
Key Technical Decisions
Memory Management
We chose to use arena allocators for table operations to provide:
- Bulk memory deallocation
- Reduced fragmentation
- Improved performance for batch operations
Error Handling
flora64 uses Zig’s error unions for robust error handling:
const DbError = error{NotFilePath};
This ensures that error cases are handled explicitly and can’t be ignored.
Data Structure Choice
We use StringHashMap for table storage because:
- O(1) table lookups
- Memory efficiency
- Built-in string key optimization
What’s Next?
In the next post, we’ll dive deep into flora64’s table implementation and how it handles different data types efficiently. Stay tuned!