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