| ... | @@ -36,8 +36,7 @@ pub const File = struct { | ... | @@ -36,8 +36,7 @@ pub const File = struct { |
| 36 | pub const CacheHash = struct { | 36 | pub const CacheHash = struct { |
| 37 | alloc: *Allocator, | 37 | alloc: *Allocator, |
| 38 | blake3: Blake3, | 38 | blake3: Blake3, |
| 39 | manifest_dir: []const u8, | 39 | manifest_dir: fs.Dir, |
| 40 | manifest_file_path: ?[]const u8, | | |
| 41 | manifest_file: ?fs.File, | 40 | manifest_file: ?fs.File, |
| 42 | manifest_dirty: bool, | 41 | manifest_dirty: bool, |
| 43 | force_check_manifest: bool, | 42 | force_check_manifest: bool, |
| ... | @@ -45,11 +44,13 @@ pub const CacheHash = struct { | ... | @@ -45,11 +44,13 @@ pub const CacheHash = struct { |
| 45 | b64_digest: ArrayList(u8), | 44 | b64_digest: ArrayList(u8), |
| 46 | | 45 | |
| 47 | pub fn init(alloc: *Allocator, manifest_dir_path: []const u8) !@This() { | 46 | pub fn init(alloc: *Allocator, manifest_dir_path: []const u8) !@This() { |
| | 47 | try fs.cwd().makePath(manifest_dir_path); |
| | 48 | const manifest_dir = try fs.cwd().openDirTraverse(manifest_dir_path); |
| | 49 | |
| 48 | return CacheHash{ | 50 | return CacheHash{ |
| 49 | .alloc = alloc, | 51 | .alloc = alloc, |
| 50 | .blake3 = Blake3.init(), | 52 | .blake3 = Blake3.init(), |
| 51 | .manifest_dir = manifest_dir_path, | 53 | .manifest_dir = manifest_dir, |
| 52 | .manifest_file_path = null, | | |
| 53 | .manifest_file = null, | 54 | .manifest_file = null, |
| 54 | .manifest_dirty = false, | 55 | .manifest_dirty = false, |
| 55 | .force_check_manifest = false, | 56 | .force_check_manifest = false, |
| ... | @@ -59,14 +60,14 @@ pub const CacheHash = struct { | ... | @@ -59,14 +60,14 @@ pub const CacheHash = struct { |
| 59 | } | 60 | } |
| 60 | | 61 | |
| 61 | pub fn cache_buf(self: *@This(), val: []const u8) void { | 62 | pub fn cache_buf(self: *@This(), val: []const u8) void { |
| 62 | debug.assert(self.manifest_file_path == null); | 63 | debug.assert(self.manifest_file == null); |
| 63 | | 64 | |
| 64 | self.blake3.update(val); | 65 | self.blake3.update(val); |
| 65 | self.blake3.update(&[_]u8{0}); | 66 | self.blake3.update(&[_]u8{0}); |
| 66 | } | 67 | } |
| 67 | | 68 | |
| 68 | pub fn cache(self: *@This(), val: var) void { | 69 | pub fn cache(self: *@This(), val: var) void { |
| 69 | debug.assert(self.manifest_file_path == null); | 70 | debug.assert(self.manifest_file == null); |
| 70 | | 71 | |
| 71 | const val_type = @TypeOf(val); | 72 | const val_type = @TypeOf(val); |
| 72 | switch (@typeInfo(val_type)) { | 73 | switch (@typeInfo(val_type)) { |
| ... | @@ -88,7 +89,7 @@ pub const CacheHash = struct { | ... | @@ -88,7 +89,7 @@ pub const CacheHash = struct { |
| 88 | } | 89 | } |
| 89 | | 90 | |
| 90 | pub fn cache_file(self: *@This(), file_path: []const u8) !void { | 91 | pub fn cache_file(self: *@This(), file_path: []const u8) !void { |
| 91 | debug.assert(self.manifest_file_path == null); | 92 | debug.assert(self.manifest_file == null); |
| 92 | | 93 | |
| 93 | var cache_hash_file = try self.files.addOne(); | 94 | var cache_hash_file = try self.files.addOne(); |
| 94 | cache_hash_file.path = try fs.path.resolve(self.alloc, &[_][]const u8{file_path}); | 95 | cache_hash_file.path = try fs.path.resolve(self.alloc, &[_][]const u8{file_path}); |
| ... | @@ -97,7 +98,7 @@ pub const CacheHash = struct { | ... | @@ -97,7 +98,7 @@ pub const CacheHash = struct { |
| 97 | } | 98 | } |
| 98 | | 99 | |
| 99 | pub fn hit(self: *@This(), out_digest: *ArrayList(u8)) !bool { | 100 | pub fn hit(self: *@This(), out_digest: *ArrayList(u8)) !bool { |
| 100 | debug.assert(self.manifest_file_path == null); | 101 | debug.assert(self.manifest_file == null); |
| 101 | | 102 | |
| 102 | var bin_digest: [BIN_DIGEST_LEN]u8 = undefined; | 103 | var bin_digest: [BIN_DIGEST_LEN]u8 = undefined; |
| 103 | self.blake3.final(&bin_digest); | 104 | self.blake3.final(&bin_digest); |
| ... | @@ -116,21 +117,12 @@ pub const CacheHash = struct { | ... | @@ -116,21 +117,12 @@ pub const CacheHash = struct { |
| 116 | self.blake3.update(&bin_digest); | 117 | self.blake3.update(&bin_digest); |
| 117 | | 118 | |
| 118 | { | 119 | { |
| 119 | const manifest_file_path_slice = try fs.path.join(self.alloc, &[_][]const u8{ self.manifest_dir, self.b64_digest.toSlice() }); | 120 | const manifest_file_path = try fmt.allocPrint(self.alloc, "{}.txt", .{self.b64_digest.toSlice()}); |
| 120 | var path_buf = ArrayList(u8).fromOwnedSlice(self.alloc, manifest_file_path_slice); | 121 | defer self.alloc.free(manifest_file_path); |
| 121 | defer path_buf.deinit(); | | |
| 122 | try path_buf.appendSlice(".txt"); | | |
| 123 | | 122 | |
| 124 | self.manifest_file_path = path_buf.toOwnedSlice(); | 123 | self.manifest_file = try self.manifest_dir.createFile(manifest_file_path, .{ .read = true, .truncate = false }); |
| 125 | } | 124 | } |
| 126 | | 125 | |
| 127 | const cwd = fs.cwd(); | | |
| 128 | | | |
| 129 | try cwd.makePath(self.manifest_dir); | | |
| 130 | | | |
| 131 | // TODO: Open file with a file lock | | |
| 132 | self.manifest_file = try cwd.createFile(self.manifest_file_path.?, .{ .read = true, .truncate = false }); | | |
| 133 | | | |
| 134 | // create a buffer instead of using readAllAlloc | 126 | // create a buffer instead of using readAllAlloc |
| 135 | // See: https://github.com/ziglang/zig/issues/4656 | 127 | // See: https://github.com/ziglang/zig/issues/4656 |
| 136 | var file_buffer = try Buffer.initCapacity(self.alloc, 16 * 1024); | 128 | var file_buffer = try Buffer.initCapacity(self.alloc, 16 * 1024); |
| ... | @@ -172,7 +164,7 @@ pub const CacheHash = struct { | ... | @@ -172,7 +164,7 @@ pub const CacheHash = struct { |
| 172 | return error.InvalidFormat; | 164 | return error.InvalidFormat; |
| 173 | } | 165 | } |
| 174 | | 166 | |
| 175 | const this_file = cwd.openFile(cache_hash_file.path.?, .{ .read = true }) catch { | 167 | const this_file = fs.cwd().openFile(cache_hash_file.path.?, .{ .read = true }) catch { |
| 176 | self.manifest_file.?.close(); | 168 | self.manifest_file.?.close(); |
| 177 | self.manifest_file = null; | 169 | self.manifest_file = null; |
| 178 | return error.CacheUnavailable; | 170 | return error.CacheUnavailable; |
| ... | @@ -245,7 +237,7 @@ pub const CacheHash = struct { | ... | @@ -245,7 +237,7 @@ pub const CacheHash = struct { |
| 245 | } | 237 | } |
| 246 | | 238 | |
| 247 | pub fn final(self: *@This(), out_digest: *ArrayList(u8)) !void { | 239 | pub fn final(self: *@This(), out_digest: *ArrayList(u8)) !void { |
| 248 | debug.assert(self.manifest_file_path != null); | 240 | debug.assert(self.manifest_file != null); |
| 249 | | 241 | |
| 250 | var bin_digest: [BIN_DIGEST_LEN]u8 = undefined; | 242 | var bin_digest: [BIN_DIGEST_LEN]u8 = undefined; |
| 251 | self.blake3.final(&bin_digest); | 243 | self.blake3.final(&bin_digest); |
| ... | @@ -256,7 +248,7 @@ pub const CacheHash = struct { | ... | @@ -256,7 +248,7 @@ pub const CacheHash = struct { |
| 256 | } | 248 | } |
| 257 | | 249 | |
| 258 | pub fn write_manifest(self: *@This()) !void { | 250 | pub fn write_manifest(self: *@This()) !void { |
| 259 | debug.assert(self.manifest_file_path != null); | 251 | debug.assert(self.manifest_file != null); |
| 260 | | 252 | |
| 261 | const OUT_DIGEST_LEN = base64.Base64Encoder.calcSize(BIN_DIGEST_LEN); | 253 | const OUT_DIGEST_LEN = base64.Base64Encoder.calcSize(BIN_DIGEST_LEN); |
| 262 | var encoded_digest = try Buffer.initSize(self.alloc, OUT_DIGEST_LEN); | 254 | var encoded_digest = try Buffer.initSize(self.alloc, OUT_DIGEST_LEN); |
| ... | @@ -274,23 +266,21 @@ pub const CacheHash = struct { | ... | @@ -274,23 +266,21 @@ pub const CacheHash = struct { |
| 274 | } | 266 | } |
| 275 | | 267 | |
| 276 | pub fn release(self: *@This()) void { | 268 | pub fn release(self: *@This()) void { |
| 277 | debug.assert(self.manifest_file_path != null); | 269 | debug.assert(self.manifest_file != null); |
| 278 | | 270 | |
| 279 | if (self.manifest_dirty) { | 271 | if (self.manifest_dirty) { |
| 280 | self.write_manifest() catch |err| { | 272 | self.write_manifest() catch |err| { |
| 281 | debug.warn("Unable to write cache file '{}': {}\n", .{ self.manifest_file_path, err }); | 273 | debug.warn("Unable to write cache file '{}': {}\n", .{ self.b64_digest, err }); |
| 282 | }; | 274 | }; |
| 283 | } | 275 | } |
| 284 | | 276 | |
| 285 | self.manifest_file.?.close(); | 277 | self.manifest_file.?.close(); |
| 286 | if (self.manifest_file_path) |owned_slice| { | | |
| 287 | self.alloc.free(owned_slice); | | |
| 288 | } | | |
| 289 | for (self.files.toSlice()) |*file| { | 278 | for (self.files.toSlice()) |*file| { |
| 290 | file.deinit(self.alloc); | 279 | file.deinit(self.alloc); |
| 291 | } | 280 | } |
| 292 | self.files.deinit(); | 281 | self.files.deinit(); |
| 293 | self.b64_digest.deinit(); | 282 | self.b64_digest.deinit(); |
| | 283 | self.manifest_dir.close(); |
| 294 | } | 284 | } |
| 295 | }; | 285 | }; |
| 296 | | 286 | |