authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-21 19:53:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-21 19:56:30-07:00
log2f4bbd6c637782eb985860255cf70011bbadd452
tree8baa0a2c003b66c3e449af9d73bc33985d13d0f3
parentebec7336e23404ab091d34303055cd3b8a0088a5

std.Build.Cache: use an array hash map for files

Rather than an ArrayList. Provides deduplication.

4 files changed, 152 insertions(+), 72 deletions(-)

lib/std/Build/Cache.zig+148-68
...@@ -55,7 +55,15 @@ pub fn prefixes(cache: *const Cache) []const Directory {...@@ -55,7 +55,15 @@ pub fn prefixes(cache: *const Cache) []const Directory {
5555
56const PrefixedPath = struct {56const PrefixedPath = struct {
57 prefix: u8,57 prefix: u8,
58 sub_path: []u8,58 sub_path: []const u8,
59
60 fn eql(a: PrefixedPath, b: PrefixedPath) bool {
61 return a.prefix == b.prefix and std.mem.eql(u8, a.sub_path, b.sub_path);
62 }
63
64 fn hash(pp: PrefixedPath) u32 {
65 return @truncate(std.hash.Wyhash.hash(pp.prefix, pp.sub_path));
66 }
59};67};
6068
61fn findPrefix(cache: *const Cache, file_path: []const u8) !PrefixedPath {69fn findPrefix(cache: *const Cache, file_path: []const u8) !PrefixedPath {
...@@ -132,7 +140,7 @@ pub const hasher_init: Hasher = Hasher.init(&[_]u8{...@@ -132,7 +140,7 @@ pub const hasher_init: Hasher = Hasher.init(&[_]u8{
132});140});
133141
134pub const File = struct {142pub const File = struct {
135 prefixed_path: ?PrefixedPath,143 prefixed_path: PrefixedPath,
136 max_file_size: ?usize,144 max_file_size: ?usize,
137 stat: Stat,145 stat: Stat,
138 bin_digest: BinDigest,146 bin_digest: BinDigest,
...@@ -145,16 +153,18 @@ pub const File = struct {...@@ -145,16 +153,18 @@ pub const File = struct {
145 };153 };
146154
147 pub fn deinit(self: *File, gpa: Allocator) void {155 pub fn deinit(self: *File, gpa: Allocator) void {
148 if (self.prefixed_path) |pp| {156 gpa.free(self.prefixed_path.sub_path);
149 gpa.free(pp.sub_path);
150 self.prefixed_path = null;
151 }
152 if (self.contents) |contents| {157 if (self.contents) |contents| {
153 gpa.free(contents);158 gpa.free(contents);
154 self.contents = null;159 self.contents = null;
155 }160 }
156 self.* = undefined;161 self.* = undefined;
157 }162 }
163
164 pub fn updateMaxSize(file: *File, new_max_size: ?usize) void {
165 const new = new_max_size orelse return;
166 file.max_file_size = if (file.max_file_size) |old| @max(old, new) else new;
167 }
158};168};
159169
160pub const HashHelper = struct {170pub const HashHelper = struct {
...@@ -296,7 +306,7 @@ pub const Manifest = struct {...@@ -296,7 +306,7 @@ pub const Manifest = struct {
296 // order to obtain a problematic timestamp for the next call. Calls after that306 // order to obtain a problematic timestamp for the next call. Calls after that
297 // will then use the same timestamp, to avoid unnecessary filesystem writes.307 // will then use the same timestamp, to avoid unnecessary filesystem writes.
298 want_refresh_timestamp: bool = true,308 want_refresh_timestamp: bool = true,
299 files: std.ArrayListUnmanaged(File) = .{},309 files: Files = .{},
300 hex_digest: HexDigest,310 hex_digest: HexDigest,
301 /// Populated when hit() returns an error because of one311 /// Populated when hit() returns an error because of one
302 /// of the files listed in the manifest.312 /// of the files listed in the manifest.
...@@ -305,6 +315,34 @@ pub const Manifest = struct {...@@ -305,6 +315,34 @@ pub const Manifest = struct {
305 /// what time the file system thinks it is, according to its own granularity.315 /// what time the file system thinks it is, according to its own granularity.
306 recent_problematic_timestamp: i128 = 0,316 recent_problematic_timestamp: i128 = 0,
307317
318 pub const Files = std.ArrayHashMapUnmanaged(File, void, FilesContext, false);
319
320 pub const FilesContext = struct {
321 pub fn hash(fc: FilesContext, file: File) u32 {
322 _ = fc;
323 return file.prefixed_path.hash();
324 }
325
326 pub fn eql(fc: FilesContext, a: File, b: File, b_index: usize) bool {
327 _ = fc;
328 _ = b_index;
329 return a.prefixed_path.eql(b.prefixed_path);
330 }
331 };
332
333 const FilesAdapter = struct {
334 pub fn eql(context: @This(), a: PrefixedPath, b: File, b_index: usize) bool {
335 _ = context;
336 _ = b_index;
337 return a.eql(b.prefixed_path);
338 }
339
340 pub fn hash(context: @This(), key: PrefixedPath) u32 {
341 _ = context;
342 return key.hash();
343 }
344 };
345
308 /// Add a file as a dependency of process being cached. When `hit` is346 /// Add a file as a dependency of process being cached. When `hit` is
309 /// called, the file's contents will be checked to ensure that it matches347 /// called, the file's contents will be checked to ensure that it matches
310 /// the contents from previous times.348 /// the contents from previous times.
...@@ -317,7 +355,7 @@ pub const Manifest = struct {...@@ -317,7 +355,7 @@ pub const Manifest = struct {
317 /// to access the contents of the file after calling `hit()` like so:355 /// to access the contents of the file after calling `hit()` like so:
318 ///356 ///
319 /// ```357 /// ```
320 /// var file_contents = cache_hash.files.items[file_index].contents.?;358 /// var file_contents = cache_hash.files.keys()[file_index].contents.?;
321 /// ```359 /// ```
322 pub fn addFile(self: *Manifest, file_path: []const u8, max_file_size: ?usize) !usize {360 pub fn addFile(self: *Manifest, file_path: []const u8, max_file_size: ?usize) !usize {
323 assert(self.manifest_file == null);361 assert(self.manifest_file == null);
...@@ -327,7 +365,12 @@ pub const Manifest = struct {...@@ -327,7 +365,12 @@ pub const Manifest = struct {
327 const prefixed_path = try self.cache.findPrefix(file_path);365 const prefixed_path = try self.cache.findPrefix(file_path);
328 errdefer gpa.free(prefixed_path.sub_path);366 errdefer gpa.free(prefixed_path.sub_path);
329367
330 self.files.addOneAssumeCapacity().* = .{368 const gop = self.files.getOrPutAssumeCapacityAdapted(prefixed_path, FilesAdapter{});
369 if (gop.found_existing) {
370 gop.key_ptr.updateMaxSize(max_file_size);
371 return gop.index;
372 }
373 gop.key_ptr.* = .{
331 .prefixed_path = prefixed_path,374 .prefixed_path = prefixed_path,
332 .contents = null,375 .contents = null,
333 .max_file_size = max_file_size,376 .max_file_size = max_file_size,
...@@ -338,7 +381,7 @@ pub const Manifest = struct {...@@ -338,7 +381,7 @@ pub const Manifest = struct {
338 self.hash.add(prefixed_path.prefix);381 self.hash.add(prefixed_path.prefix);
339 self.hash.addBytes(prefixed_path.sub_path);382 self.hash.addBytes(prefixed_path.sub_path);
340383
341 return self.files.items.len - 1;384 return gop.index;
342 }385 }
343386
344 pub fn addOptionalFile(self: *Manifest, optional_file_path: ?[]const u8) !void {387 pub fn addOptionalFile(self: *Manifest, optional_file_path: ?[]const u8) !void {
...@@ -418,7 +461,7 @@ pub const Manifest = struct {...@@ -418,7 +461,7 @@ pub const Manifest = struct {
418461
419 self.want_refresh_timestamp = true;462 self.want_refresh_timestamp = true;
420463
421 const input_file_count = self.files.items.len;464 const input_file_count = self.files.entries.len;
422 while (true) : (self.unhit(bin_digest, input_file_count)) {465 while (true) : (self.unhit(bin_digest, input_file_count)) {
423 const file_contents = try self.manifest_file.?.reader().readAllAlloc(gpa, manifest_file_size_max);466 const file_contents = try self.manifest_file.?.reader().readAllAlloc(gpa, manifest_file_size_max);
424 defer gpa.free(file_contents);467 defer gpa.free(file_contents);
...@@ -430,7 +473,7 @@ pub const Manifest = struct {...@@ -430,7 +473,7 @@ pub const Manifest = struct {
430 if (try self.upgradeToExclusiveLock()) continue;473 if (try self.upgradeToExclusiveLock()) continue;
431 self.manifest_dirty = true;474 self.manifest_dirty = true;
432 while (idx < input_file_count) : (idx += 1) {475 while (idx < input_file_count) : (idx += 1) {
433 const ch_file = &self.files.items[idx];476 const ch_file = &self.files.keys()[idx];
434 self.populateFileHash(ch_file) catch |err| {477 self.populateFileHash(ch_file) catch |err| {
435 self.failed_file_index = idx;478 self.failed_file_index = idx;
436 return err;479 return err;
...@@ -441,18 +484,6 @@ pub const Manifest = struct {...@@ -441,18 +484,6 @@ pub const Manifest = struct {
441 while (line_iter.next()) |line| {484 while (line_iter.next()) |line| {
442 defer idx += 1;485 defer idx += 1;
443486
444 const cache_hash_file = if (idx < input_file_count) &self.files.items[idx] else blk: {
445 const new = try self.files.addOne(gpa);
446 new.* = .{
447 .prefixed_path = null,
448 .contents = null,
449 .max_file_size = null,
450 .stat = undefined,
451 .bin_digest = undefined,
452 };
453 break :blk new;
454 };
455
456 var iter = mem.tokenizeScalar(u8, line, ' ');487 var iter = mem.tokenizeScalar(u8, line, ' ');
457 const size = iter.next() orelse return error.InvalidFormat;488 const size = iter.next() orelse return error.InvalidFormat;
458 const inode = iter.next() orelse return error.InvalidFormat;489 const inode = iter.next() orelse return error.InvalidFormat;
...@@ -461,30 +492,61 @@ pub const Manifest = struct {...@@ -461,30 +492,61 @@ pub const Manifest = struct {
461 const prefix_str = iter.next() orelse return error.InvalidFormat;492 const prefix_str = iter.next() orelse return error.InvalidFormat;
462 const file_path = iter.rest();493 const file_path = iter.rest();
463494
464 cache_hash_file.stat.size = fmt.parseInt(u64, size, 10) catch return error.InvalidFormat;495 const stat_size = fmt.parseInt(u64, size, 10) catch return error.InvalidFormat;
465 cache_hash_file.stat.inode = fmt.parseInt(fs.File.INode, inode, 10) catch return error.InvalidFormat;496 const stat_inode = fmt.parseInt(fs.File.INode, inode, 10) catch return error.InvalidFormat;
466 cache_hash_file.stat.mtime = fmt.parseInt(i64, mtime_nsec_str, 10) catch return error.InvalidFormat;497 const stat_mtime = fmt.parseInt(i64, mtime_nsec_str, 10) catch return error.InvalidFormat;
467 _ = fmt.hexToBytes(&cache_hash_file.bin_digest, digest_str) catch return error.InvalidFormat;498 const file_bin_digest = b: {
499 if (digest_str.len != hex_digest_len) return error.InvalidFormat;
500 var bd: BinDigest = undefined;
501 _ = fmt.hexToBytes(&bd, digest_str) catch return error.InvalidFormat;
502 break :b bd;
503 };
504
468 const prefix = fmt.parseInt(u8, prefix_str, 10) catch return error.InvalidFormat;505 const prefix = fmt.parseInt(u8, prefix_str, 10) catch return error.InvalidFormat;
469 if (prefix >= self.cache.prefixes_len) return error.InvalidFormat;506 if (prefix >= self.cache.prefixes_len) return error.InvalidFormat;
470507
471 if (file_path.len == 0) {508 if (file_path.len == 0) return error.InvalidFormat;
472 return error.InvalidFormat;
473 }
474 if (cache_hash_file.prefixed_path) |pp| {
475 if (pp.prefix != prefix or !mem.eql(u8, file_path, pp.sub_path)) {
476 return error.InvalidFormat;
477 }
478 }
479509
480 if (cache_hash_file.prefixed_path == null) {510 const cache_hash_file = f: {
481 cache_hash_file.prefixed_path = .{511 const prefixed_path: PrefixedPath = .{
482 .prefix = prefix,512 .prefix = prefix,
483 .sub_path = try gpa.dupe(u8, file_path),513 .sub_path = file_path, // expires with file_contents
484 };514 };
485 }515 if (idx < input_file_count) {
516 const file = &self.files.keys()[idx];
517 if (!file.prefixed_path.eql(prefixed_path))
518 return error.InvalidFormat;
519
520 file.stat = .{
521 .size = stat_size,
522 .inode = stat_inode,
523 .mtime = stat_mtime,
524 };
525 file.bin_digest = file_bin_digest;
526 break :f file;
527 }
528 const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{});
529 errdefer assert(self.files.popOrNull() != null);
530 if (!gop.found_existing) {
531 gop.key_ptr.* = .{
532 .prefixed_path = .{
533 .prefix = prefix,
534 .sub_path = try gpa.dupe(u8, file_path),
535 },
536 .contents = null,
537 .max_file_size = null,
538 .stat = .{
539 .size = stat_size,
540 .inode = stat_inode,
541 .mtime = stat_mtime,
542 },
543 .bin_digest = file_bin_digest,
544 };
545 }
546 break :f gop.key_ptr;
547 };
486548
487 const pp = cache_hash_file.prefixed_path.?;549 const pp = cache_hash_file.prefixed_path;
488 const dir = self.cache.prefixes()[pp.prefix].handle;550 const dir = self.cache.prefixes()[pp.prefix].handle;
489 const this_file = dir.openFile(pp.sub_path, .{ .mode = .read_only }) catch |err| switch (err) {551 const this_file = dir.openFile(pp.sub_path, .{ .mode = .read_only }) catch |err| switch (err) {
490 error.FileNotFound => {552 error.FileNotFound => {
...@@ -548,7 +610,7 @@ pub const Manifest = struct {...@@ -548,7 +610,7 @@ pub const Manifest = struct {
548 if (try self.upgradeToExclusiveLock()) continue;610 if (try self.upgradeToExclusiveLock()) continue;
549 self.manifest_dirty = true;611 self.manifest_dirty = true;
550 while (idx < input_file_count) : (idx += 1) {612 while (idx < input_file_count) : (idx += 1) {
551 const ch_file = &self.files.items[idx];613 const ch_file = &self.files.keys()[idx];
552 self.populateFileHash(ch_file) catch |err| {614 self.populateFileHash(ch_file) catch |err| {
553 self.failed_file_index = idx;615 self.failed_file_index = idx;
554 return err;616 return err;
...@@ -571,12 +633,12 @@ pub const Manifest = struct {...@@ -571,12 +633,12 @@ pub const Manifest = struct {
571 self.hash.hasher.update(&bin_digest);633 self.hash.hasher.update(&bin_digest);
572634
573 // Remove files not in the initial hash.635 // Remove files not in the initial hash.
574 for (self.files.items[input_file_count..]) |*file| {636 for (self.files.keys()[input_file_count..]) |*file| {
575 file.deinit(self.cache.gpa);637 file.deinit(self.cache.gpa);
576 }638 }
577 self.files.shrinkRetainingCapacity(input_file_count);639 self.files.shrinkRetainingCapacity(input_file_count);
578640
579 for (self.files.items) |file| {641 for (self.files.keys()) |file| {
580 self.hash.hasher.update(&file.bin_digest);642 self.hash.hasher.update(&file.bin_digest);
581 }643 }
582 }644 }
...@@ -616,7 +678,7 @@ pub const Manifest = struct {...@@ -616,7 +678,7 @@ pub const Manifest = struct {
616 }678 }
617679
618 fn populateFileHash(self: *Manifest, ch_file: *File) !void {680 fn populateFileHash(self: *Manifest, ch_file: *File) !void {
619 const pp = ch_file.prefixed_path.?;681 const pp = ch_file.prefixed_path;
620 const dir = self.cache.prefixes()[pp.prefix].handle;682 const dir = self.cache.prefixes()[pp.prefix].handle;
621 const file = try dir.openFile(pp.sub_path, .{});683 const file = try dir.openFile(pp.sub_path, .{});
622 defer file.close();684 defer file.close();
...@@ -682,7 +744,7 @@ pub const Manifest = struct {...@@ -682,7 +744,7 @@ pub const Manifest = struct {
682 .bin_digest = undefined,744 .bin_digest = undefined,
683 .contents = null,745 .contents = null,
684 };746 };
685 errdefer self.files.shrinkRetainingCapacity(self.files.items.len - 1);747 errdefer self.files.shrinkRetainingCapacity(self.files.entries.len - 1);
686748
687 try self.populateFileHash(new_ch_file);749 try self.populateFileHash(new_ch_file);
688750
...@@ -690,9 +752,11 @@ pub const Manifest = struct {...@@ -690,9 +752,11 @@ pub const Manifest = struct {
690 }752 }
691753
692 /// Add a file as a dependency of process being cached, after the initial hash has been754 /// Add a file as a dependency of process being cached, after the initial hash has been
693 /// calculated. This is useful for processes that don't know the all the files that755 /// calculated.
694 /// are depended on ahead of time. For example, a source file that can import other files756 ///
695 /// will need to be recompiled if the imported file is changed.757 /// This is useful for processes that don't know the all the files that are
758 /// depended on ahead of time. For example, a source file that can import
759 /// other files will need to be recompiled if the imported file is changed.
696 pub fn addFilePost(self: *Manifest, file_path: []const u8) !void {760 pub fn addFilePost(self: *Manifest, file_path: []const u8) !void {
697 assert(self.manifest_file != null);761 assert(self.manifest_file != null);
698762
...@@ -700,17 +764,26 @@ pub const Manifest = struct {...@@ -700,17 +764,26 @@ pub const Manifest = struct {
700 const prefixed_path = try self.cache.findPrefix(file_path);764 const prefixed_path = try self.cache.findPrefix(file_path);
701 errdefer gpa.free(prefixed_path.sub_path);765 errdefer gpa.free(prefixed_path.sub_path);
702766
703 const new_ch_file = try self.files.addOne(gpa);767 const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{});
704 new_ch_file.* = .{768 errdefer assert(self.files.popOrNull() != null);
769
770 if (gop.found_existing) {
771 gpa.free(prefixed_path.sub_path);
772 return;
773 }
774
775 gop.key_ptr.* = .{
705 .prefixed_path = prefixed_path,776 .prefixed_path = prefixed_path,
706 .max_file_size = null,777 .max_file_size = null,
707 .stat = undefined,778 .stat = undefined,
708 .bin_digest = undefined,779 .bin_digest = undefined,
709 .contents = null,780 .contents = null,
710 };781 };
711 errdefer self.files.shrinkRetainingCapacity(self.files.items.len - 1);
712782
713 try self.populateFileHash(new_ch_file);783 self.files.lockPointers();
784 defer self.files.unlockPointers();
785
786 try self.populateFileHash(gop.key_ptr);
714 }787 }
715788
716 /// Like `addFilePost` but when the file contents have already been loaded from disk.789 /// Like `addFilePost` but when the file contents have already been loaded from disk.
...@@ -724,13 +797,20 @@ pub const Manifest = struct {...@@ -724,13 +797,20 @@ pub const Manifest = struct {
724 assert(self.manifest_file != null);797 assert(self.manifest_file != null);
725 const gpa = self.cache.gpa;798 const gpa = self.cache.gpa;
726799
727 const ch_file = try self.files.addOne(gpa);
728 errdefer self.files.shrinkRetainingCapacity(self.files.items.len - 1);
729
730 const prefixed_path = try self.cache.findPrefixResolved(resolved_path);800 const prefixed_path = try self.cache.findPrefixResolved(resolved_path);
731 errdefer gpa.free(prefixed_path.sub_path);801 errdefer gpa.free(prefixed_path.sub_path);
732802
733 ch_file.* = .{803 const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{});
804 errdefer assert(self.files.popOrNull() != null);
805
806 if (gop.found_existing) {
807 gpa.free(prefixed_path.sub_path);
808 return;
809 }
810
811 const new_file = gop.key_ptr;
812
813 new_file.* = .{
734 .prefixed_path = prefixed_path,814 .prefixed_path = prefixed_path,
735 .max_file_size = null,815 .max_file_size = null,
736 .stat = stat,816 .stat = stat,
...@@ -738,19 +818,19 @@ pub const Manifest = struct {...@@ -738,19 +818,19 @@ pub const Manifest = struct {
738 .contents = null,818 .contents = null,
739 };819 };
740820
741 if (self.isProblematicTimestamp(ch_file.stat.mtime)) {821 if (self.isProblematicTimestamp(new_file.stat.mtime)) {
742 // The actual file has an unreliable timestamp, force it to be hashed822 // The actual file has an unreliable timestamp, force it to be hashed
743 ch_file.stat.mtime = 0;823 new_file.stat.mtime = 0;
744 ch_file.stat.inode = 0;824 new_file.stat.inode = 0;
745 }825 }
746826
747 {827 {
748 var hasher = hasher_init;828 var hasher = hasher_init;
749 hasher.update(bytes);829 hasher.update(bytes);
750 hasher.final(&ch_file.bin_digest);830 hasher.final(&new_file.bin_digest);
751 }831 }
752832
753 self.hash.hasher.update(&ch_file.bin_digest);833 self.hash.hasher.update(&new_file.bin_digest);
754 }834 }
755835
756 pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {836 pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {
...@@ -816,14 +896,14 @@ pub const Manifest = struct {...@@ -816,14 +896,14 @@ pub const Manifest = struct {
816896
817 const writer = contents.writer();897 const writer = contents.writer();
818 try writer.writeAll(manifest_header ++ "\n");898 try writer.writeAll(manifest_header ++ "\n");
819 for (self.files.items) |file| {899 for (self.files.keys()) |file| {
820 try writer.print("{d} {d} {d} {} {d} {s}\n", .{900 try writer.print("{d} {d} {d} {} {d} {s}\n", .{
821 file.stat.size,901 file.stat.size,
822 file.stat.inode,902 file.stat.inode,
823 file.stat.mtime,903 file.stat.mtime,
824 fmt.fmtSliceHexLower(&file.bin_digest),904 fmt.fmtSliceHexLower(&file.bin_digest),
825 file.prefixed_path.?.prefix,905 file.prefixed_path.prefix,
826 file.prefixed_path.?.sub_path,906 file.prefixed_path.sub_path,
827 });907 });
828 }908 }
829909
...@@ -892,7 +972,7 @@ pub const Manifest = struct {...@@ -892,7 +972,7 @@ pub const Manifest = struct {
892972
893 file.close();973 file.close();
894 }974 }
895 for (self.files.items) |*file| {975 for (self.files.keys()) |*file| {
896 file.deinit(self.cache.gpa);976 file.deinit(self.cache.gpa);
897 }977 }
898 self.files.deinit(self.cache.gpa);978 self.files.deinit(self.cache.gpa);
...@@ -1061,7 +1141,7 @@ test "check that changing a file makes cache fail" {...@@ -1061,7 +1141,7 @@ test "check that changing a file makes cache fail" {
1061 // There should be nothing in the cache1141 // There should be nothing in the cache
1062 try testing.expectEqual(false, try ch.hit());1142 try testing.expectEqual(false, try ch.hit());
10631143
1064 try testing.expect(mem.eql(u8, original_temp_file_contents, ch.files.items[temp_file_idx].contents.?));1144 try testing.expect(mem.eql(u8, original_temp_file_contents, ch.files.keys()[temp_file_idx].contents.?));
10651145
1066 digest1 = ch.final();1146 digest1 = ch.final();
10671147
...@@ -1081,7 +1161,7 @@ test "check that changing a file makes cache fail" {...@@ -1081,7 +1161,7 @@ test "check that changing a file makes cache fail" {
1081 try testing.expectEqual(false, try ch.hit());1161 try testing.expectEqual(false, try ch.hit());
10821162
1083 // The cache system does not keep the contents of re-hashed input files.1163 // The cache system does not keep the contents of re-hashed input files.
1084 try testing.expect(ch.files.items[temp_file_idx].contents == null);1164 try testing.expect(ch.files.keys()[temp_file_idx].contents == null);
10851165
1086 digest2 = ch.final();1166 digest2 = ch.final();
10871167
lib/std/Build/Step.zig+1-1
...@@ -544,7 +544,7 @@ pub fn cacheHit(s: *Step, man: *std.Build.Cache.Manifest) !bool {...@@ -544,7 +544,7 @@ pub fn cacheHit(s: *Step, man: *std.Build.Cache.Manifest) !bool {
544544
545fn failWithCacheError(s: *Step, man: *const std.Build.Cache.Manifest, err: anyerror) anyerror {545fn failWithCacheError(s: *Step, man: *const std.Build.Cache.Manifest, err: anyerror) anyerror {
546 const i = man.failed_file_index orelse return err;546 const i = man.failed_file_index orelse return err;
547 const pp = man.files.items[i].prefixed_path orelse return err;547 const pp = man.files.keys()[i].prefixed_path;
548 const prefix = man.cache.prefixes()[pp.prefix].path orelse "";548 const prefix = man.cache.prefixes()[pp.prefix].path orelse "";
549 return s.fail("{s}: {s}/{s}", .{ @errorName(err), prefix, pp.sub_path });549 return s.fail("{s}: {s}/{s}", .{ @errorName(err), prefix, pp.sub_path });
550}550}
src/Compilation.zig+2-2
...@@ -1999,7 +1999,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void...@@ -1999,7 +1999,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
19991999
2000 const is_hit = man.hit() catch |err| {2000 const is_hit = man.hit() catch |err| {
2001 const i = man.failed_file_index orelse return err;2001 const i = man.failed_file_index orelse return err;
2002 const pp = man.files.items[i].prefixed_path orelse return err;2002 const pp = man.files.keys()[i].prefixed_path;
2003 const prefix = man.cache.prefixes()[pp.prefix];2003 const prefix = man.cache.prefixes()[pp.prefix];
2004 return comp.setMiscFailure(2004 return comp.setMiscFailure(
2005 .check_whole_cache,2005 .check_whole_cache,
...@@ -4147,7 +4147,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module...@@ -4147,7 +4147,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module
4147 const prev_hash_state = man.hash.peekBin();4147 const prev_hash_state = man.hash.peekBin();
4148 const actual_hit = hit: {4148 const actual_hit = hit: {
4149 _ = try man.hit();4149 _ = try man.hit();
4150 if (man.files.items.len == 0) {4150 if (man.files.entries.len == 0) {
4151 man.unhit(prev_hash_state, 0);4151 man.unhit(prev_hash_state, 0);
4152 break :hit false;4152 break :hit false;
4153 }4153 }
src/glibc.zig+1-1
...@@ -713,7 +713,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: *std.Progress.Node) !vo...@@ -713,7 +713,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: *std.Progress.Node) !vo
713 };713 };
714 defer o_directory.handle.close();714 defer o_directory.handle.close();
715715
716 const abilists_contents = man.files.items[abilists_index].contents.?;716 const abilists_contents = man.files.keys()[abilists_index].contents.?;
717 const metadata = try loadMetaData(comp.gpa, abilists_contents);717 const metadata = try loadMetaData(comp.gpa, abilists_contents);
718 defer metadata.destroy(comp.gpa);718 defer metadata.destroy(comp.gpa);
719719