style: adopt TigerStyle across src/; add docs/TIGER_STYLE.md

Wrap signatures and long expressions to the 100-column limit and make every
file zig fmt clean. Semantics-preserving throughout: ignoring whitespace and
the trailing commas that wrapping introduces, every file here is byte-identical
to its predecessor, and the one apparent exception is a warning string split
with `++`, which concatenates at comptime to the same bytes.

src/index.zig and src/commands.zig are reformatted in the commits that follow,
because their reformat is interleaved with in-flight changes to them and
separating the two would need the reformat re-derived rather than moved.
This commit is contained in:
2026-08-03 17:08:21 +03:00
parent d4c9b04f21
commit 86ae8fa8af
14 changed files with 1130 additions and 126 deletions

View File

@@ -320,7 +320,13 @@ pub const Engine = struct {
/// shared); the collection lock is acquired before the exclusive catalog
/// lock is dropped, so a concurrent drop can never free it underneath.
/// Returns null when the collection does not exist (and create is off).
pub fn lock_collection(self: *Engine, db_name: []const u8, coll_name: []const u8, write: bool, create: bool) !?*Collection {
pub fn lock_collection(
self: *Engine,
db_name: []const u8,
coll_name: []const u8,
write: bool,
create: bool,
) !?*Collection {
var coll = self.get_collection(db_name, coll_name);
if (coll == null and create) {
self.catalog_lock.unlockShared(self.io);
@@ -425,7 +431,13 @@ pub const Engine = struct {
/// Log an append (and its seq increment) under the log lock, marking
/// the append as in flight so a commit leader's seal covers it.
fn log_append(self: *Engine, comptime kind: LogKind, db: []const u8, coll: []const u8, doc: []const u8) !void {
fn log_append(
self: *Engine,
comptime kind: LogKind,
db: []const u8,
coll: []const u8,
doc: []const u8,
) !void {
_ = self.pending_appends.fetchAdd(1, .acq_rel);
defer {
// The increment above pairs with this decrement on every return
@@ -468,12 +480,24 @@ pub const Engine = struct {
/// Insert a document. Fails with error.DuplicateKey if the _id exists.
/// Generates an ObjectId _id when absent.
pub fn insert(self: *Engine, db_name: []const u8, coll_name: []const u8, doc: *const bson.Document, oid_gen: *bson.ObjectIdGen) !void {
pub fn insert(
self: *Engine,
db_name: []const u8,
coll_name: []const u8,
doc: *const bson.Document,
oid_gen: *bson.ObjectIdGen,
) !void {
return self.upsert(db_name, coll_name, doc, oid_gen, .insert);
}
/// Insert or replace a document by _id (upsert without existence check).
pub fn replace(self: *Engine, db_name: []const u8, coll_name: []const u8, doc: *const bson.Document, oid_gen: *bson.ObjectIdGen) !void {
pub fn replace(
self: *Engine,
db_name: []const u8,
coll_name: []const u8,
doc: *const bson.Document,
oid_gen: *bson.ObjectIdGen,
) !void {
return self.upsert(db_name, coll_name, doc, oid_gen, .replace);
}
@@ -574,7 +598,12 @@ pub const Engine = struct {
/// Remove a document by its `_id` value. Returns true if it existed.
/// The serialized-key encoding stays private to the engine.
pub fn remove_by_id(self: *Engine, db_name: []const u8, coll_name: []const u8, id: bson.Value) !bool {
pub fn remove_by_id(
self: *Engine,
db_name: []const u8,
coll_name: []const u8,
id: bson.Value,
) !bool {
const id_key = try bson.serialize_value(self.gpa, id);
defer self.gpa.free(id_key);
return self.remove(db_name, coll_name, id_key);
@@ -610,7 +639,12 @@ pub const Engine = struct {
return db.collections.get(coll_name);
}
pub fn get_doc(self: *Engine, db_name: []const u8, coll_name: []const u8, id_key: []const u8) ?[]const u8 {
pub fn get_doc(
self: *Engine,
db_name: []const u8,
coll_name: []const u8,
id_key: []const u8,
) ?[]const u8 {
const coll = self.get_collection(db_name, coll_name) orelse return null;
const off = coll.docs.get(id_key) orelse return null;
return coll.doc_bytes(off);
@@ -636,7 +670,12 @@ pub const Engine = struct {
/// after the index builds over the existing documents and passes
/// uniqueness, so a rejected create persists nothing. Returns the new
/// index (or the existing one when the spec matches — idempotent).
pub fn create_index(self: *Engine, db_name: []const u8, coll_name: []const u8, spec_doc: *const bson.Document) !*index.Index {
pub fn create_index(
self: *Engine,
db_name: []const u8,
coll_name: []const u8,
spec_doc: *const bson.Document,
) !*index.Index {
const coll = try self.get_or_create_collection(db_name, coll_name);
var ix = try index.parse_spec(self.gpa, spec_doc);
var committed = false;
@@ -675,7 +714,12 @@ pub const Engine = struct {
/// Remove a secondary index by name, persisting a drop record first.
/// Returns false when no such index exists.
pub fn drop_index(self: *Engine, db_name: []const u8, coll_name: []const u8, index_name: []const u8) !bool {
pub fn drop_index(
self: *Engine,
db_name: []const u8,
coll_name: []const u8,
index_name: []const u8,
) !bool {
const db = self.dbs.get(db_name) orelse return false;
const coll = db.collections.get(coll_name) orelse return false;
if (coll.find_index(index_name) == null) return false;
@@ -722,7 +766,13 @@ pub const Engine = struct {
/// Sweep one collection under its write lock; the lock is released on
/// every return path. Returns how many documents were removed.
fn ttl_sweep_coll(self: *Engine, coll: *Collection, now_ms: i64, db_name: []const u8, coll_name: []const u8) !usize {
fn ttl_sweep_coll(
self: *Engine,
coll: *Collection,
now_ms: i64,
db_name: []const u8,
coll_name: []const u8,
) !usize {
try coll.lock.lock(self.io);
defer coll.lock.unlock(self.io);
// Ids are duped rather than aliased: `remove` frees the docs-map key
@@ -778,7 +828,11 @@ pub const Engine = struct {
while (it.next()) |entry| try out.append(self.gpa, entry.key_ptr.*);
}
pub fn collection_names(self: *Engine, db_name: []const u8, out: *std.ArrayListUnmanaged([]const u8)) !void {
pub fn collection_names(
self: *Engine,
db_name: []const u8,
out: *std.ArrayListUnmanaged([]const u8),
) !void {
const db = self.dbs.get(db_name) orelse return;
var it = db.collections.iterator();
while (it.next()) |entry| try out.append(self.gpa, entry.key_ptr.*);
@@ -786,7 +840,11 @@ pub const Engine = struct {
// -- internals -----------------------------------------------------------
pub fn get_or_create_collection(self: *Engine, db_name: []const u8, coll_name: []const u8) !*Collection {
pub fn get_or_create_collection(
self: *Engine,
db_name: []const u8,
coll_name: []const u8,
) !*Collection {
const db = self.dbs.getPtr(db_name) orelse {
const db_key = try self.gpa.dupe(u8, db_name);
errdefer self.gpa.free(db_key);
@@ -808,7 +866,11 @@ pub const Engine = struct {
/// generated ObjectId `_id` when absent.
/// The canonical bytes of `doc`, with an ObjectId `_id` generated when
/// absent. The result is owned by the caller.
fn serialize_with_id(self: *Engine, doc: *const bson.Document, oid_gen: *bson.ObjectIdGen) ![]u8 {
fn serialize_with_id(
self: *Engine,
doc: *const bson.Document,
oid_gen: *bson.ObjectIdGen,
) ![]u8 {
if (doc.get("_id") != null) return serialize_doc(self.gpa, doc);
var pairs: std.ArrayListUnmanaged(bson.Pair) = .empty;
defer pairs.deinit(self.gpa);
@@ -994,7 +1056,13 @@ pub const Engine = struct {
/// Re-emit one collection's index specs and documents into the compacted
/// log, under the collection's write lock (released on every return
/// path, including errors).
fn compact_snapshot_coll(self: *Engine, coll: *Collection, new_log: *storage.Log, db_name: []const u8, coll_name: []const u8) !void {
fn compact_snapshot_coll(
self: *Engine,
coll: *Collection,
new_log: *storage.Log,
db_name: []const u8,
coll_name: []const u8,
) !void {
try coll.lock.lock(self.io);
defer coll.lock.unlock(self.io);
// Re-emit the index definitions first: a compacted log that dropped
@@ -1045,7 +1113,13 @@ pub const Engine = struct {
while (doc_it.next()) |doc_entry| {
ix.append_doc_entries(self.gpa, coll.doc_bytes(doc_entry.value_ptr.*), doc_entry.key_ptr.*) catch |err| switch (err) {
error.ParallelArrays => {
std.debug.print("multiforadb: WARNING: index '{s}' cannot index an existing document; entry skipped\n", .{ix.name});
std.debug.print(
"multiforadb: WARNING: index '{s}' cannot index an existing " ++
"document; entry skipped\n",
.{
ix.name,
},
);
continue;
},
else => return err,
@@ -1053,13 +1127,23 @@ pub const Engine = struct {
}
// Tolerated, not enforced: the database must always open.
if (try ix.finish_bulk(self.gpa, false)) {
std.debug.print("multiforadb: WARNING: unique index '{s}' has duplicate keys in existing data; duplicates not enforced for existing documents\n", .{ix.name});
std.debug.print(
"multiforadb: WARNING: unique index '{s}' has duplicate keys in existing " ++
"data; duplicates not enforced for existing documents\n",
.{
ix.name,
},
);
}
}
/// Register an (empty) index from a persisted spec document. A repeated
/// create record for the same name is an idempotent no-op.
fn register_index_from_spec(self: *Engine, coll: *Collection, spec_doc: *const bson.Document) !void {
fn register_index_from_spec(
self: *Engine,
coll: *Collection,
spec_doc: *const bson.Document,
) !void {
var ix = try index.parse_spec(self.gpa, spec_doc);
var committed = false;
defer if (!committed) ix.deinit(self.gpa);
@@ -1103,7 +1187,9 @@ fn apply_record(ctx: *anyopaque, record: storage.Record, doc: *bson.Document) an
switch (record.type) {
storage.record_type_index_create => {
self.register_index_from_spec(coll, doc) catch |err| {
std.debug.print("multiforadb: index create record failed to apply: {s}\n", .{@errorName(err)});
std.debug.print("multiforadb: index create record failed to apply: {s}\n", .{
@errorName(err),
});
return;
};
return;
@@ -1455,7 +1541,12 @@ test "concurrent readers and writers on a threaded Io" {
var remaining = std.atomic.Value(usize).init(@intCast(total));
const Worker = struct {
fn writer(e: *Engine, id_counter: *std.atomic.Value(i32), pending: *std.atomic.Value(usize), alloc: std.mem.Allocator) error{Canceled}!void {
fn writer(
e: *Engine,
id_counter: *std.atomic.Value(i32),
pending: *std.atomic.Value(usize),
alloc: std.mem.Allocator,
) error{Canceled}!void {
while (true) {
const id = id_counter.fetchAdd(1, .monotonic);
if (id > total) return;
@@ -1605,7 +1696,11 @@ test "concurrent writers compacting: the log survives a reopen" {
}
}
fn writer(e: *Engine, id_counter: *std.atomic.Value(i32), alloc: std.mem.Allocator) error{Canceled}!void {
fn writer(
e: *Engine,
id_counter: *std.atomic.Value(i32),
alloc: std.mem.Allocator,
) error{Canceled}!void {
while (true) {
const id = id_counter.fetchAdd(1, .monotonic);
if (id > total) return;
@@ -1645,7 +1740,14 @@ test "concurrent writers compacting: the log survives a reopen" {
/// A spec document for a single-path index, built by serializing and
/// re-parsing so the pairs are arena-owned.
fn index_spec(gpa: std.mem.Allocator, path: []const u8, name: []const u8, unique: bool, sparse: bool, ttl: ?i64) !bson.Document {
fn index_spec(
gpa: std.mem.Allocator,
path: []const u8,
name: []const u8,
unique: bool,
sparse: bool,
ttl: ?i64,
) !bson.Document {
var out: std.ArrayListUnmanaged(u8) = .empty;
defer out.deinit(gpa);
var pairs: std.ArrayListUnmanaged(bson.Pair) = .empty;
@@ -1662,7 +1764,14 @@ fn index_spec(gpa: std.mem.Allocator, path: []const u8, name: []const u8, unique
}
/// Number of entries the named index has for a single-value equality key.
fn index_count(gpa: std.mem.Allocator, engine: *Engine, db_name: []const u8, coll_name: []const u8, name: []const u8, key_value: bson.Value) !usize {
fn index_count(
gpa: std.mem.Allocator,
engine: *Engine,
db_name: []const u8,
coll_name: []const u8,
name: []const u8,
key_value: bson.Value,
) !usize {
const coll = engine.get_collection(db_name, coll_name) orelse return 0;
for (coll.indexes.items) |*ix| {
if (std.mem.eql(u8, ix.name, name)) {