//! Assertions that survive the default ReleaseFast build. //! //! `std.debug.assert` lowers to `unreachable`, which in ReleaseFast (this //! project's default -- see build.zig) is not a skipped check but a promise to //! the optimizer that the condition holds. That is exactly the wrong lowering //! for a durability invariant that might actually be false: the compiler is //! then free to optimize on a lie. So the checks below stay active in every //! optimize mode. //! //! Use these for invariants whose violation means the database is already //! corrupt, where crashing loudly beats continuing and writing wrong bytes to //! disk. Every current use sits on a path that already takes a lock or fsyncs, //! so the branch is noise. Keep `std.debug.assert` for hot inner loops (see //! index.zig), where the cost is real and a wrong answer is not persistent. const std = @import("std"); /// Panic unless `ok`. Active in every optimize mode; see the module comment. pub fn assert(ok: bool) void { if (!ok) @panic("multiforadb: assertion failed"); } /// Panic unless `ok`, naming the invariant that broke. Prefer this where the /// condition alone does not say what went wrong -- the message lands in the /// crash output, which may be all an operator has to go on. pub fn assert_msg(ok: bool, comptime message: []const u8) void { if (!ok) @panic("multiforadb: assertion failed: " ++ message); } test "assert passes on true and is callable in every mode" { assert(true); assert_msg(true, "trivially true"); // The failing side cannot be tested in-process: it panics by design. // Its behavior is covered by the invariants it guards in db.zig. try std.testing.expect(true); }