Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

indexPackHashDelta

Attempts to determine the final object ID of the given deltified object. May return null if this is not yet possible (if the delta is a ref-based delta and we do not yet know the offset of the base object).

git.indexPackHashDelta
fn indexPackHashDelta(
    allocator: Allocator,
    format: Oid.Format,
    pack: *Io.File.Reader,
    delta: IndexEntry,
    index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry),
    cache: *ObjectCache,
) !?Oid

File

Code

fn indexPackHashDelta(
    allocator: Allocator,
    format: Oid.Format,
    pack: *Io.File.Reader,
    delta: IndexEntry,
    index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry),
    cache: *ObjectCache,
) !?Oid {
    // Figure out the chain of deltas to resolve
    var base_offset = delta.offset;
    var base_header: EntryHeader = undefined;
    var delta_offsets: std.ArrayList(u64) = .empty;
    defer delta_offsets.deinit(allocator);
    const base_object = while (true) {
        if (cache.get(base_offset)) |base_object| break base_object;

        try pack.seekTo(base_offset);
        base_header = try EntryHeader.read(format, &pack.interface);
        switch (base_header) {
            .ofs_delta => |ofs_delta| {
                try delta_offsets.append(allocator, base_offset);
                base_offset = std.math.sub(u64, base_offset, ofs_delta.offset) catch return error.InvalidObject;
            },
            .ref_delta => |ref_delta| {
                try delta_offsets.append(allocator, base_offset);
                base_offset = (index_entries.get(ref_delta.base_object) orelse return null).offset;
            },
            else => {
                const base_data = try readObjectRaw(allocator, &pack.interface, base_header.uncompressedLength());
                errdefer allocator.free(base_data);
                const base_object: Object = .{ .type = base_header.objectType(), .data = base_data };
                try cache.put(allocator, base_offset, base_object);
                break base_object;
            },
        }
    };

    const base_data = try resolveDeltaChain(allocator, format, pack, base_object, delta_offsets.items, cache);

    var entry_hasher_buffer: [64]u8 = undefined;
    var entry_hasher: Oid.Hashing = .init(format, &entry_hasher_buffer);
    const entry_hasher_w = entry_hasher.writer();
    // Writes to hashers cannot fail.
    entry_hasher_w.print("{t} {d}\x00", .{ base_object.type, base_data.len }) catch unreachable;
    entry_hasher_w.writeAll(base_data) catch unreachable;
    return entry_hasher.final();
}