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 {...@@ -1061,6 +1061,7 @@ pub const Manifest = struct {
1061 const input_file = file_off.get(contents);1061 const input_file = file_off.get(contents);
1062 const parent_dir = cache.prefixes()[input_file.flags.prefix].handle;1062 const parent_dir = cache.prefixes()[input_file.flags.prefix].handle;
1063 const file_path = file_off.path(contents);1063 const file_path = file_off.path(contents);
1064 const gpa = cache.gpa;
10641065
1065 if (input_path.have_digest) return;1066 if (input_path.have_digest) return;
10661067
...@@ -1150,7 +1151,6 @@ pub const Manifest = struct {...@@ -1150,7 +1151,6 @@ pub const Manifest = struct {
1150 }1151 }
11511152
1152 const dir_contents_start = m.all_input_content.items.len;1153 const dir_contents_start = m.all_input_content.items.len;
1153 const gpa = cache.gpa;
1154 hashDir(gpa, io, opened_dir, &input_file.digest, &m.all_input_content) catch |err| switch (err) {1154 hashDir(gpa, io, opened_dir, &input_file.digest, &m.all_input_content) catch |err| switch (err) {
1155 error.Canceled, error.OutOfMemory => |e| return e,1155 error.Canceled, error.OutOfMemory => |e| return e,
1156 else => |e| return fail(&m.diagnostic, .{ .file_read = .{1156 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
...@@ -1194,17 +1194,28 @@ pub const Manifest = struct {...@@ -1194,17 +1194,28 @@ pub const Manifest = struct {
1194 try input_file.setStat(m, .init(actual_stat));1194 try input_file.setStat(m, .init(actual_stat));
1195 }1195 }
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
1205 switch (input_path.contents.unwrap()) {1197 switch (input_path.contents.unwrap()) {
1206 .requested => @panic("TODO"),1198 .requested => {
1207 .unrequested => {},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 },
1208 .populated => unreachable,1219 .populated => unreachable,
1209 }1220 }
1210 }1221 }
...@@ -1220,6 +1231,7 @@ pub const Manifest = struct {...@@ -1220,6 +1231,7 @@ pub const Manifest = struct {
1220 ) CheckError!CheckResult {1231 ) CheckError!CheckResult {
1221 const cache = m.cache;1232 const cache = m.cache;
1222 const io = cache.io;1233 const io = cache.io;
1234 const gpa = cache.gpa;
1223 const disk_file = file_off.get(disk_contents);1235 const disk_file = file_off.get(disk_contents);
1224 const input_file = file_off.get(input_contents);1236 const input_file = file_off.get(input_contents);
1225 const parent_dir = cache.prefixes()[disk_file.flags.prefix].handle;1237 const parent_dir = cache.prefixes()[disk_file.flags.prefix].handle;
...@@ -1321,7 +1333,6 @@ pub const Manifest = struct {...@@ -1321,7 +1333,6 @@ pub const Manifest = struct {
1321 }1333 }
13221334
1323 const dir_contents_start = m.all_input_content.items.len;1335 const dir_contents_start = m.all_input_content.items.len;
1324 const gpa = cache.gpa;
1325 hashDir(gpa, io, opened_dir, &disk_file.digest, &m.all_input_content) catch |err| switch (err) {1336 hashDir(gpa, io, opened_dir, &disk_file.digest, &m.all_input_content) catch |err| switch (err) {
1326 error.Canceled, error.OutOfMemory => |e| return e,1337 error.Canceled, error.OutOfMemory => |e| return e,
1327 else => |e| return fail(&m.diagnostic, .{ .file_read = .{1338 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
...@@ -1367,16 +1378,28 @@ pub const Manifest = struct {...@@ -1367,16 +1378,28 @@ pub const Manifest = struct {
1367 if (!try disk_file.setStatChanged(m, .init(actual_stat))) return .hit;1378 if (!try disk_file.setStatChanged(m, .init(actual_stat))) return .hit;
1368 }1379 }
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 };
1377 switch (input_path.contents.unwrap()) {1381 switch (input_path.contents.unwrap()) {
1378 .requested => @panic("TODO"),1382 .requested => {
1379 .unrequested => {},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 },
1380 .populated => unreachable,1403 .populated => unreachable,
1381 }1404 }
13821405
...@@ -2032,6 +2055,27 @@ pub const Manifest = struct {...@@ -2032,6 +2055,27 @@ pub const Manifest = struct {
2032 hasher.final(bin_digest);2055 hasher.final(bin_digest);
2033 }2056 }
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
2035 const HashDirError = Io.Dir.Reader.Error || Allocator.Error;2079 const HashDirError = Io.Dir.Reader.Error || Allocator.Error;
20362080
2037 /// Appends the sorted, encoded directory entries to `contents`.2081 /// Appends the sorted, encoded directory entries to `contents`.
...@@ -2198,7 +2242,7 @@ test "cache file and then recall it" {...@@ -2198,7 +2242,7 @@ test "cache file and then recall it" {
2198 }2242 }
2199}2243}
22002244
2201test "check that changing a file makes cache fail" {2245test "check that changing a file causes cache miss" {
2202 const io = testing.io;2246 const io = testing.io;
22032247
2204 var tmp = testing.tmpDir(.{});2248 var tmp = testing.tmpDir(.{});