| ... | ... | @@ -363,9 +363,9 @@ pub const Manifest = struct { |
| 363 | 363 | pub const File = extern struct { |
| 364 | 364 | size: u64, |
| 365 | 365 | inode: u64, |
| 366 | | digest: BinDigest, |
| 367 | 366 | /// Nanoseconds. |
| 368 | 367 | mtime: i64, |
| 368 | digest: BinDigest, |
| 369 | 369 | /// Starting with this field and continuing into the path, excluding the null byte, |
| 370 | 370 | /// is the string that is hashed for the manifest digest. |
| 371 | 371 | flags: Flags, |
| ... | ... | @@ -546,35 +546,29 @@ pub const Manifest = struct { |
| 546 | 546 | pub fn addInputPath(m: *Manifest, path: Path, options: AddInputPathOptions) Allocator.Error!InputPath.Index { |
| 547 | 547 | const cache = m.cache; |
| 548 | 548 | const gpa = cache.gpa; |
| 549 | const is_directory = options.handle.isDirectory(); |
| 550 | |
| 549 | 551 | try m.files.ensureUnusedCapacityContext(gpa, 1, .{ .contents = m.contents.items }); |
| 550 | 552 | try m.input_paths.ensureUnusedCapacity(gpa, 1); |
| 551 | 553 | |
| 552 | | const prev_contents_len = m.contents.items.len; |
| 553 | | const header: *File = @ptrCast(@alignCast(try m.contents.addManyAsSlice(gpa, @sizeOf(File)))); |
| 554 | | errdefer m.contents.shrinkRetainingCapacity(prev_contents_len); |
| 554 | const new_file_offset: File.Offset = @fromBackingInt(@intCast(m.contents.items.len)); |
| 555 | try m.contents.appendNTimes(gpa, 0, @offsetOf(File, "path_start")); |
| 556 | errdefer m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset)); |
| 555 | 557 | |
| 556 | | header.* = .{ |
| 557 | | .flags = .{ |
| 558 | | .prefix = try cache.resolveAppendPath(&m.contents, path), |
| 559 | | .is_directory = options.handle.isDirectory(), |
| 560 | | .metadata_only = options.metadata_only, |
| 561 | | }, |
| 562 | | .size = undefined, |
| 563 | | .inode = undefined, |
| 564 | | .mtime = undefined, |
| 565 | | .digest = undefined, |
| 566 | | .path_start = .{}, |
| 567 | | }; |
| 558 | const new_prefix = try cache.resolveAppendPath(&m.contents, path); |
| 568 | 559 | assert(mem.isAligned(m.contents.items.len, @alignOf(File))); |
| 560 | new_file_offset.get(m.contents.items).flags = .{ |
| 561 | .prefix = new_prefix, |
| 562 | .is_directory = is_directory, |
| 563 | .metadata_only = options.metadata_only, |
| 564 | }; |
| 569 | 565 | |
| 570 | | const gop = m.files.getOrPutAssumeCapacityContext(@fromBackingInt(@intCast(prev_contents_len)), .{ |
| 571 | | .contents = m.contents.items, |
| 572 | | }); |
| 566 | const gop = m.files.getOrPutAssumeCapacityContext(new_file_offset, .{ .contents = m.contents.items }); |
| 573 | 567 | m.files.lockPointers(); |
| 574 | 568 | defer m.files.unlockPointers(); |
| 575 | 569 | |
| 576 | 570 | if (gop.found_existing) { |
| 577 | | m.contents.shrinkRetainingCapacity(prev_contents_len); |
| 571 | m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset)); |
| 578 | 572 | const existing_input_file = &m.input_paths.items[gop.index]; |
| 579 | 573 | switch (options.handle) { |
| 580 | 574 | .file => |opt_file| if (opt_file) |file| { |
| ... | ... | @@ -600,7 +594,7 @@ pub const Manifest = struct { |
| 600 | 594 | // If it trips, the same file path has been added to the cache |
| 601 | 595 | // manifest both as a directory and as a normal file, making the |
| 602 | 596 | // intended caching behavior ambiguous. |
| 603 | | assert(existing_header.flags.is_directory == options.handle.isDirectory()); |
| 597 | assert(existing_header.flags.is_directory == is_directory); |
| 604 | 598 | if (!options.metadata_only) |
| 605 | 599 | existing_header.flags.metadata_only = false; |
| 606 | 600 | } else { |
| ... | ... | @@ -617,6 +611,7 @@ pub const Manifest = struct { |
| 617 | 611 | }); |
| 618 | 612 | assert(m.input_paths.items.len - 1 == gop.index); |
| 619 | 613 | if (options.stat) |stat| { |
| 614 | const header = new_file_offset.get(m.contents.items); |
| 620 | 615 | header.size = stat.size; |
| 621 | 616 | header.inode = stat.inode; |
| 622 | 617 | header.mtime = @intCast(stat.mtime.toNanoseconds()); |
| ... | ... | @@ -1134,33 +1129,25 @@ pub const Manifest = struct { |
| 1134 | 1129 | try m.files.ensureUnusedCapacityContext(gpa, 1, .{ .contents = m.contents.items }); |
| 1135 | 1130 | |
| 1136 | 1131 | const new_file_offset: File.Offset = @fromBackingInt(@intCast(m.contents.items.len)); |
| 1137 | | const new_header: *File = @ptrCast(@alignCast(try m.contents.addManyAsSlice(gpa, @sizeOf(File)))); |
| 1132 | try m.contents.appendNTimes(gpa, 0, @offsetOf(File, "path_start")); |
| 1138 | 1133 | errdefer m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset)); |
| 1139 | 1134 | |
| 1140 | | new_header.* = .{ |
| 1141 | | .flags = .{ |
| 1142 | | .prefix = switch (options.path) { |
| 1143 | | .unresolved => |unresolved| try cache.resolveAppendPath(&m.contents, unresolved), |
| 1144 | | .prefixed => |prefixed| try cache.appendPrefixedPath(&m.contents, prefixed), |
| 1145 | | }, |
| 1146 | | .is_directory = is_directory, |
| 1147 | | .metadata_only = options.metadata_only, |
| 1148 | | }, |
| 1149 | | .size = undefined, |
| 1150 | | .inode = undefined, |
| 1151 | | .mtime = undefined, |
| 1152 | | .digest = @splat(0), |
| 1153 | | .path_start = .{}, |
| 1135 | const new_prefix = switch (options.path) { |
| 1136 | .unresolved => |unresolved| try cache.resolveAppendPath(&m.contents, unresolved), |
| 1137 | .prefixed => |prefixed| try cache.appendPrefixedPath(&m.contents, prefixed), |
| 1154 | 1138 | }; |
| 1155 | 1139 | assert(mem.isAligned(m.contents.items.len, @alignOf(File))); |
| 1140 | new_file_offset.get(m.contents.items).flags = .{ |
| 1141 | .prefix = new_prefix, |
| 1142 | .is_directory = is_directory, |
| 1143 | .metadata_only = options.metadata_only, |
| 1144 | }; |
| 1156 | 1145 | |
| 1157 | | const gop = m.files.getOrPutAssumeCapacityContext(new_file_offset, .{ |
| 1158 | | .contents = m.contents.items, |
| 1159 | | }); |
| 1146 | const gop = m.files.getOrPutAssumeCapacityContext(new_file_offset, .{ .contents = m.contents.items }); |
| 1160 | 1147 | m.files.lockPointers(); |
| 1161 | 1148 | defer m.files.unlockPointers(); |
| 1162 | 1149 | |
| 1163 | | const header, const file_offset = if (gop.found_existing) h: { |
| 1150 | const file_offset = if (gop.found_existing) h: { |
| 1164 | 1151 | m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset)); |
| 1165 | 1152 | const existing_off = gop.key_ptr.*; |
| 1166 | 1153 | const header = existing_off.get(m.contents.items); |
| ... | ... | @@ -1170,8 +1157,10 @@ pub const Manifest = struct { |
| 1170 | 1157 | assert(header.flags.is_directory == is_directory); |
| 1171 | 1158 | if (!options.metadata_only) |
| 1172 | 1159 | header.flags.metadata_only = false; |
| 1173 | | break :h .{ header, existing_off }; |
| 1174 | | } else .{ new_header, new_file_offset }; |
| 1160 | break :h existing_off; |
| 1161 | } else new_file_offset; |
| 1162 | |
| 1163 | const header = file_offset.get(m.contents.items); |
| 1175 | 1164 | |
| 1176 | 1165 | if (options.stat) |stat| { |
| 1177 | 1166 | try header.setStat(m, stat); |