Skip to documentation
SLOP

tiny.smg.storage.names

Reference tiny.smg storage names

Defined in storage.

API (6)

Actions

Public operations.

Values and defaults

Public values and defaults.

No direct callersNo direct callsstoragenames
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callsprivate; no linktools.smg.src.storage.contextexactNodeNameprivate; no linktools.smg.src.storage.contextscanIndexedNamesstorage.nameswriteForHeadstorage.namesindexedName
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallssearchsyncStoredFromDatabasetest; no linktools.smg.src.searchtest: matched graph publication rebui...test; no linktools.smg.src.storage.contexttest: name projection preserves index...test; no linktools.smg.src.storage.graphtest: matched publication preserves t...private; no linktools.smg.src.storage.namescachePathstorage.namesmatchesHead
Static calls · unresolved targets: 1 · external targets: 3.
Called byCallsstorage.contextresolveNodeNameFromReadertest; no linktools.smg.src.storage.contexttest: name projection preserves index...private; no linktools.smg.src.storage.namescachePathprivate; no linktools.smg.src.storage.namesreadExactstorage.namesscan
Static calls · unresolved targets: 2 · external targets: 6.
Called byCallsprivate; no linktools.smg.src.searchrebuildStoredFromDatabasesearchsyncStoredFromDatabaseprivate; no linktools.smg.src.storage.contextwriteNameProjectiontest; no linktools.smg.src.storage.graphtest: matched publication preserves t...private; no linktools.smg.src.storage.namescachePathstorage.namesindexedNameprivate; no linktools.smg.src.storage.namesnodeNameIndexSlotstorage.nameswriteForHead
Static calls · unresolved targets: 2 · external targets: 13.

Source: tools/smg/src/storage/names.zig

zig
const std = @import("std");const sql = @import("sql");const sys = @import("sys");const smg = @import("../root.zig");const storage = smg.storage;const fs_io = std.Options.debug_io;pub const file_name = "names.bin";pub const temp_file_name = "names.bin.tmp";const magic = "tiny.smg.names/v1\n";const digest_bytes = std.crypto.hash.sha2.Sha256.digest_length;const read_buffer_bytes = 64 * 1024;const write_buffer_bytes = 64 * 1024;const max_cache_bytes: u64 = 512 * 1024 * 1024;const header_bytes = magic.len + @sizeOf(sql.Hash) + @sizeOf(u64);const minimum_file_bytes = header_bytes + digest_bytes;pub fn matchesHead(    allocator: std.mem.Allocator,    root: []const u8,    expected: sql.Hash,) std.mem.Allocator.Error!bool {    const path = try cachePath(allocator, root, file_name);    defer allocator.free(path);    var file = std.Io.Dir.openFileAbsolute(fs_io, path, .{}) catch return false;    defer file.close(fs_io);    const stat = file.stat(fs_io) catch return false;    if (stat.kind != .file or stat.size < minimum_file_bytes) return false;    if (stat.size > max_cache_bytes) return false;    var header: [header_bytes]u8 = undefined;    const read = file.readPositionalAll(fs_io, &header, 0) catch return false;    if (read != header.len) return false;    if (!std.mem.eql(u8, header[0..magic.len], magic)) return false;    return std.mem.eql(        u8,        header[magic.len .. magic.len + @sizeOf(sql.Hash)],        expected[0..],    );}pub fn scan(    allocator: std.mem.Allocator,    root: []const u8,    expected: sql.Hash,    visitor: anytype,) !void {    const path = try cachePath(allocator, root, file_name);    defer allocator.free(path);    var file = try std.Io.Dir.openFileAbsolute(fs_io, path, .{});    defer file.close(fs_io);    const stat = try file.stat(fs_io);    if (stat.kind != .file or stat.size < minimum_file_bytes) {        return error.InvalidNameProjection;    }    if (stat.size > max_cache_bytes) return error.InvalidNameProjection;    var read_buffer: [read_buffer_bytes]u8 = undefined;    var file_reader = file.reader(fs_io, &read_buffer);    const reader = &file_reader.interface;    var stored_magic: [magic.len]u8 = undefined;    try readExact(reader, &stored_magic);    if (!std.mem.eql(u8, &stored_magic, magic)) return error.InvalidNameProjection;    var stored_head: sql.Hash = undefined;    try readExact(reader, &stored_head);    if (!std.mem.eql(u8, &stored_head, &expected)) return error.StaleNameProjection;    var count_bytes: [@sizeOf(u64)]u8 = undefined;    try readExact(reader, &count_bytes);    const count = std.mem.readInt(u64, &count_bytes, .big);    const entry_bytes = stat.size - minimum_file_bytes;    if (count > entry_bytes / @sizeOf(u32)) return error.InvalidNameProjection;    var hasher = std.crypto.hash.sha2.Sha256.init(.{});    var name_buffer: [sql.page.size]u8 = undefined;    var index: u64 = 0;    while (index < count) : (index += 1) {        var length_bytes: [@sizeOf(u32)]u8 = undefined;        try readExact(reader, &length_bytes);        hasher.update(&length_bytes);        const length: usize = @intCast(std.mem.readInt(u32, &length_bytes, .big));        if (length == 0 or length > name_buffer.len) return error.InvalidNameProjection;        const name = name_buffer[0..length];        try readExact(reader, name);        hasher.update(name);        try visitor.visit(name);    }    var stored_digest: [digest_bytes]u8 = undefined;    try readExact(reader, &stored_digest);    var computed_digest: [digest_bytes]u8 = undefined;    hasher.final(&computed_digest);    if (!std.mem.eql(u8, &stored_digest, &computed_digest)) {        return error.InvalidNameProjection;    }    _ = reader.takeByte() catch |err| switch (err) {        error.EndOfStream => return,        else => return error.InvalidNameProjection,    };    return error.InvalidNameProjection;}pub fn writeForHead(    allocator: std.mem.Allocator,    root: []const u8,    database: *storage.database.Database,    head: sql.Hash,) !void {    const temporary = try cachePath(allocator, root, temp_file_name);    defer allocator.free(temporary);    const destination = try cachePath(allocator, root, file_name);    defer allocator.free(destination);    errdefer std.Io.Dir.deleteFileAbsolute(fs_io, temporary) catch {};    {        var file = try std.Io.Dir.createFileAbsolute(fs_io, temporary, .{ .truncate = true });        defer file.close(fs_io);        var write_buffer: [write_buffer_bytes]u8 = undefined;        var file_writer = file.writer(fs_io, &write_buffer);        const writer = &file_writer.interface;        try writer.writeAll(magic);        try writer.writeAll(&head);        var handle = try database.connection.catalog.openRelation(            database.allocator,            storage.rows.nodes_relation,        );        defer handle.deinit();        const count = try handle.relation.table.count();        var count_bytes: [@sizeOf(u64)]u8 = undefined;        std.mem.writeInt(u64, &count_bytes, @intCast(count), .big);        try writer.writeAll(&count_bytes);        const scan_index = try nodeNameIndexSlot(&handle);        var entries: sql.IndexScan = undefined;        try handle.relation.indexScan(            &entries,            database.allocator,            scan_index,            null,            null,        );        defer entries.deinit();        var values: [1]sql.row.Value = undefined;        var key_scratch: [sql.page.size]u8 = undefined;        var hasher = std.crypto.hash.sha2.Sha256.init(.{});        var projected_bytes: u64 = minimum_file_bytes;        var written: usize = 0;        while (written < count) : (written += 1) {            const entry = (try entries.next()) orelse return error.StorageIndexCorrupt;            const name = try indexedName(&values, &key_scratch, entry.key);            if (name.len == 0 or name.len > sql.page.size) return error.InvalidName;            const entry_bytes: u64 = @sizeOf(u32) + @as(u64, @intCast(name.len));            if (entry_bytes > max_cache_bytes - projected_bytes) {                return error.NameProjectionTooLarge;            }            projected_bytes += entry_bytes;            var length_bytes: [@sizeOf(u32)]u8 = undefined;            std.mem.writeInt(u32, &length_bytes, @intCast(name.len), .big);            try writer.writeAll(&length_bytes);            try writer.writeAll(name);            hasher.update(&length_bytes);            hasher.update(name);        }        if (try entries.next() != null) return error.StorageIndexCorrupt;        var digest: [digest_bytes]u8 = undefined;        hasher.final(&digest);        try writer.writeAll(&digest);        try writer.flush();        try file.sync(fs_io);    }    try sys.fs.rename(temporary, destination);}pub fn indexedName(    values: *[1]sql.row.Value,    scratch: []u8,    key_bytes: []const u8,) ![]const u8 {    const decoded = sql.key.decodeIndex(values, scratch, key_bytes) catch        return error.StorageIndexCorrupt;    if (decoded.values.len != 1) return error.StorageIndexCorrupt;    return switch (decoded.values[0]) {        .text => |name| name,        else => error.StorageIndexCorrupt,    };}fn nodeNameIndexSlot(handle: anytype) !usize {    for (handle.index_definitions, 0..) |definition, slot| {        if (std.mem.eql(u8, definition.name, storage.rows.node_name_index)) {            return slot;        }    }    return error.StorageIndexMissing;}fn readExact(reader: *std.Io.Reader, target: []u8) !void {    reader.readSliceAll(target) catch return error.InvalidNameProjection;}fn cachePath(    allocator: std.mem.Allocator,    root: []const u8,    name: []const u8,) std.mem.Allocator.Error![]const u8 {    return try std.fs.path.join(        allocator,        &.{ root, storage.paths.smg_dir_name, name },    );}

Source: tools/smg/src/storage/root.zig:5

zig
pub const names = @import("names.zig");

Audit

Definitions7
Public names7
Members0
Version26.7.0
Revisiondaab053ee433