authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-13 16:49:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-16 13:12:47-07:00
log43397f22513c5769213c74a62822366f4d548364
treeed319bc85469bed7aade428325be3218f63f1546
parent9c325be987a2192228439e9cb536aae1667efde8

std.Build.Cache: implement populated requested contents


1 files changed, 66 insertions(+), 22 deletions(-)

lib/std/Build/Cache.zig+66-22
......@@ -1061,6 +1061,7 @@ pub const Manifest = struct {
10611061 const input_file = file_off.get(contents);
10621062 const parent_dir = cache.prefixes()[input_file.flags.prefix].handle;
10631063 const file_path = file_off.path(contents);
1064 const gpa = cache.gpa;
10641065
10651066 if (input_path.have_digest) return;
10661067
......@@ -1150,7 +1151,6 @@ pub const Manifest = struct {
11501151 }
11511152
11521153 const dir_contents_start = m.all_input_content.items.len;
1153 const gpa = cache.gpa;
11541154 hashDir(gpa, io, opened_dir, &input_file.digest, &m.all_input_content) catch |err| switch (err) {
11551155 error.Canceled, error.OutOfMemory => |e| return e,
11561156 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
......@@ -1194,17 +1194,28 @@ pub const Manifest = struct {
11941194 try input_file.setStat(m, .init(actual_stat));
11951195 }
11961196
1197 hashFile(io, opened_file, &input_file.digest) catch |err| switch (err) {
1198 error.Canceled => |e| return e,
1199 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
1200 .file_offset = file_off,
1201 .err = e,
1202 } }),
1203 };
1204
12051197 switch (input_path.contents.unwrap()) {
1206 .requested => @panic("TODO"),
1207 .unrequested => {},
1198 .requested => {
1199 const start = m.all_input_content.items.len;
1200 hashFileAppend(io, opened_file, &input_file.digest, &m.all_input_content, gpa) catch |err| switch (err) {
1201 error.Canceled, error.OutOfMemory => |e| return e,
1202 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
1203 .file_offset = file_off,
1204 .err = e,
1205 } }),
1206 };
1207 input_path.contents = .populated(.{
1208 .off = @intCast(start),
1209 .len = @intCast(m.all_input_content.items.len - start),
1210 });
1211 },
1212 .unrequested => hashFile(io, opened_file, &input_file.digest) catch |err| switch (err) {
1213 error.Canceled => |e| return e,
1214 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
1215 .file_offset = file_off,
1216 .err = e,
1217 } }),
1218 },
12081219 .populated => unreachable,
12091220 }
12101221 }
......@@ -1220,6 +1231,7 @@ pub const Manifest = struct {
12201231 ) CheckError!CheckResult {
12211232 const cache = m.cache;
12221233 const io = cache.io;
1234 const gpa = cache.gpa;
12231235 const disk_file = file_off.get(disk_contents);
12241236 const input_file = file_off.get(input_contents);
12251237 const parent_dir = cache.prefixes()[disk_file.flags.prefix].handle;
......@@ -1321,7 +1333,6 @@ pub const Manifest = struct {
13211333 }
13221334
13231335 const dir_contents_start = m.all_input_content.items.len;
1324 const gpa = cache.gpa;
13251336 hashDir(gpa, io, opened_dir, &disk_file.digest, &m.all_input_content) catch |err| switch (err) {
13261337 error.Canceled, error.OutOfMemory => |e| return e,
13271338 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
......@@ -1367,16 +1378,28 @@ pub const Manifest = struct {
13671378 if (!try disk_file.setStatChanged(m, .init(actual_stat))) return .hit;
13681379 }
13691380
1370 hashFile(io, opened_file, &disk_file.digest) catch |err| switch (err) {
1371 error.Canceled => |e| return e,
1372 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
1373 .file_offset = file_off,
1374 .err = e,
1375 } }),
1376 };
13771381 switch (input_path.contents.unwrap()) {
1378 .requested => @panic("TODO"),
1379 .unrequested => {},
1382 .requested => {
1383 const start = m.all_input_content.items.len;
1384 hashFileAppend(io, opened_file, &input_file.digest, &m.all_input_content, gpa) catch |err| switch (err) {
1385 error.Canceled, error.OutOfMemory => |e| return e,
1386 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
1387 .file_offset = file_off,
1388 .err = e,
1389 } }),
1390 };
1391 input_path.contents = .populated(.{
1392 .off = @intCast(start),
1393 .len = @intCast(m.all_input_content.items.len - start),
1394 });
1395 },
1396 .unrequested => hashFile(io, opened_file, &disk_file.digest) catch |err| switch (err) {
1397 error.Canceled => |e| return e,
1398 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
1399 .file_offset = file_off,
1400 .err = e,
1401 } }),
1402 },
13801403 .populated => unreachable,
13811404 }
13821405
......@@ -2032,6 +2055,27 @@ pub const Manifest = struct {
20322055 hasher.final(bin_digest);
20332056 }
20342057
2058 fn hashFileAppend(
2059 io: Io,
2060 file: Io.File,
2061 bin_digest: *[Hasher.mac_length]u8,
2062 al: *std.ArrayList(u8),
2063 gpa: Allocator,
2064 ) (Io.File.ReadPositionalError || Allocator.Error)!void {
2065 var hasher = hasher_init;
2066 var offset: u64 = 0;
2067 while (true) {
2068 try al.ensureUnusedCapacity(gpa, 2048);
2069 const buffer = al.unusedCapacitySlice();
2070 const n = try file.readPositional(io, &.{buffer}, offset);
2071 if (n == 0) break;
2072 hasher.update(buffer[0..n]);
2073 offset += n;
2074 al.items.len += n;
2075 }
2076 hasher.final(bin_digest);
2077 }
2078
20352079 const HashDirError = Io.Dir.Reader.Error || Allocator.Error;
20362080
20372081 /// Appends the sorted, encoded directory entries to `contents`.
......@@ -2198,7 +2242,7 @@ test "cache file and then recall it" {
21982242 }
21992243}
22002244
2201test "check that changing a file makes cache fail" {
2245test "check that changing a file causes cache miss" {
22022246 const io = testing.io;
22032247
22042248 var tmp = testing.tmpDir(.{});