| ... | @@ -2,6 +2,18 @@ | ... | @@ -2,6 +2,18 @@ |
| 2 | //! This is not a general-purpose cache. It is designed to be fast and simple, | 2 | //! This is not a general-purpose cache. It is designed to be fast and simple, |
| 3 | //! not to withstand attacks using specially-crafted input. | 3 | //! not to withstand attacks using specially-crafted input. |
| 4 | | 4 | |
| | 5 | const Cache = @This(); |
| | 6 | const std = @import("std"); |
| | 7 | const builtin = @import("builtin"); |
| | 8 | const crypto = std.crypto; |
| | 9 | const fs = std.fs; |
| | 10 | const assert = std.debug.assert; |
| | 11 | const testing = std.testing; |
| | 12 | const mem = std.mem; |
| | 13 | const fmt = std.fmt; |
| | 14 | const Allocator = std.mem.Allocator; |
| | 15 | const log = std.log.scoped(.cache); |
| | 16 | |
| 5 | gpa: Allocator, | 17 | gpa: Allocator, |
| 6 | manifest_dir: fs.Dir, | 18 | manifest_dir: fs.Dir, |
| 7 | hash: HashHelper = .{}, | 19 | hash: HashHelper = .{}, |
| ... | @@ -21,18 +33,6 @@ pub const Path = @import("Cache/Path.zig"); | ... | @@ -21,18 +33,6 @@ pub const Path = @import("Cache/Path.zig"); |
| 21 | pub const Directory = @import("Cache/Directory.zig"); | 33 | pub const Directory = @import("Cache/Directory.zig"); |
| 22 | pub const DepTokenizer = @import("Cache/DepTokenizer.zig"); | 34 | pub const DepTokenizer = @import("Cache/DepTokenizer.zig"); |
| 23 | | 35 | |
| 24 | const Cache = @This(); | | |
| 25 | const std = @import("std"); | | |
| 26 | const builtin = @import("builtin"); | | |
| 27 | const crypto = std.crypto; | | |
| 28 | const fs = std.fs; | | |
| 29 | const assert = std.debug.assert; | | |
| 30 | const testing = std.testing; | | |
| 31 | const mem = std.mem; | | |
| 32 | const fmt = std.fmt; | | |
| 33 | const Allocator = std.mem.Allocator; | | |
| 34 | const log = std.log.scoped(.cache); | | |
| 35 | | | |
| 36 | pub fn addPrefix(cache: *Cache, directory: Directory) void { | 36 | pub fn addPrefix(cache: *Cache, directory: Directory) void { |
| 37 | cache.prefixes_buffer[cache.prefixes_len] = directory; | 37 | cache.prefixes_buffer[cache.prefixes_len] = directory; |
| 38 | cache.prefixes_len += 1; | 38 | cache.prefixes_len += 1; |
| ... | @@ -1118,25 +1118,12 @@ pub const Manifest = struct { | ... | @@ -1118,25 +1118,12 @@ pub const Manifest = struct { |
| 1118 | if (self.manifest_dirty) { | 1118 | if (self.manifest_dirty) { |
| 1119 | self.manifest_dirty = false; | 1119 | self.manifest_dirty = false; |
| 1120 | | 1120 | |
| 1121 | const gpa = self.cache.gpa; | 1121 | var buffer: [4000]u8 = undefined; |
| 1122 | var contents: std.ArrayListUnmanaged(u8) = .empty; | 1122 | var fw = manifest_file.writer(&buffer); |
| 1123 | defer contents.deinit(gpa); | 1123 | writeDirtyManifestToStream(self, &fw) catch |err| switch (err) { |
| 1124 | | 1124 | error.WriteFailed => return fw.err.?, |
| 1125 | try contents.appendSlice(gpa, manifest_header ++ "\n"); | 1125 | else => |e| return e, |
| 1126 | for (self.files.keys()) |file| { | 1126 | }; |
| 1127 | try contents.print(gpa, "{d} {d} {d} {x} {d} {s}\n", .{ | | |
| 1128 | file.stat.size, | | |
| 1129 | file.stat.inode, | | |
| 1130 | file.stat.mtime, | | |
| 1131 | &file.bin_digest, | | |
| 1132 | file.prefixed_path.prefix, | | |
| 1133 | file.prefixed_path.sub_path, | | |
| 1134 | }); | | |
| 1135 | } | | |
| 1136 | | | |
| 1137 | try manifest_file.setEndPos(contents.items.len); | | |
| 1138 | var pos: usize = 0; | | |
| 1139 | while (pos < contents.items.len) pos += try manifest_file.pwrite(contents.items[pos..], pos); | | |
| 1140 | } | 1127 | } |
| 1141 | | 1128 | |
| 1142 | if (self.want_shared_lock) { | 1129 | if (self.want_shared_lock) { |
| ... | @@ -1144,6 +1131,21 @@ pub const Manifest = struct { | ... | @@ -1144,6 +1131,21 @@ pub const Manifest = struct { |
| 1144 | } | 1131 | } |
| 1145 | } | 1132 | } |
| 1146 | | 1133 | |
| | 1134 | fn writeDirtyManifestToStream(self: *Manifest, fw: *fs.File.Writer) !void { |
| | 1135 | try fw.interface.writeAll(manifest_header ++ "\n"); |
| | 1136 | for (self.files.keys()) |file| { |
| | 1137 | try fw.interface.print("{d} {d} {d} {x} {d} {s}\n", .{ |
| | 1138 | file.stat.size, |
| | 1139 | file.stat.inode, |
| | 1140 | file.stat.mtime, |
| | 1141 | &file.bin_digest, |
| | 1142 | file.prefixed_path.prefix, |
| | 1143 | file.prefixed_path.sub_path, |
| | 1144 | }); |
| | 1145 | } |
| | 1146 | try fw.end(); |
| | 1147 | } |
| | 1148 | |
| 1147 | fn downgradeToSharedLock(self: *Manifest) !void { | 1149 | fn downgradeToSharedLock(self: *Manifest) !void { |
| 1148 | if (!self.have_exclusive_lock) return; | 1150 | if (!self.have_exclusive_lock) return; |
| 1149 | | 1151 | |