| ... | @@ -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; |
| 1064 | | 1065 | |
| 1065 | if (input_path.have_digest) return; | 1066 | if (input_path.have_digest) return; |
| 1066 | | 1067 | |
| ... | @@ -1150,7 +1151,6 @@ pub const Manifest = struct { | ... | @@ -1150,7 +1151,6 @@ pub const Manifest = struct { |
| 1150 | } | 1151 | } |
| 1151 | | 1152 | |
| 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 | } |
| 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 | 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 | } |
| 1322 | | 1334 | |
| 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 | } |
| 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 | 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 | } |
| 1382 | | 1405 | |
| ... | @@ -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 | } |
| 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 | const HashDirError = Io.Dir.Reader.Error || Allocator.Error; | 2079 | const HashDirError = Io.Dir.Reader.Error || Allocator.Error; |
| 2036 | | 2080 | |
| 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 | } |
| 2200 | | 2244 | |
| 2201 | test "check that changing a file makes cache fail" { | 2245 | test "check that changing a file causes cache miss" { |
| 2202 | const io = testing.io; | 2246 | const io = testing.io; |
| 2203 | | 2247 | |
| 2204 | var tmp = testing.tmpDir(.{}); | 2248 | var tmp = testing.tmpDir(.{}); |