| ... | ... | @@ -36,8 +36,7 @@ pub const File = struct { |
| 36 | 36 | pub const CacheHash = struct { |
| 37 | 37 | alloc: *Allocator, |
| 38 | 38 | blake3: Blake3, |
| 39 | | manifest_dir: []const u8, |
| 40 | | manifest_file_path: ?[]const u8, |
| 39 | manifest_dir: fs.Dir, |
| 41 | 40 | manifest_file: ?fs.File, |
| 42 | 41 | manifest_dirty: bool, |
| 43 | 42 | force_check_manifest: bool, |
| ... | ... | @@ -45,11 +44,13 @@ pub const CacheHash = struct { |
| 45 | 44 | b64_digest: ArrayList(u8), |
| 46 | 45 | |
| 47 | 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 | 50 | return CacheHash{ |
| 49 | 51 | .alloc = alloc, |
| 50 | 52 | .blake3 = Blake3.init(), |
| 51 | | .manifest_dir = manifest_dir_path, |
| 52 | | .manifest_file_path = null, |
| 53 | .manifest_dir = manifest_dir, |
| 53 | 54 | .manifest_file = null, |
| 54 | 55 | .manifest_dirty = false, |
| 55 | 56 | .force_check_manifest = false, |
| ... | ... | @@ -59,14 +60,14 @@ pub const CacheHash = struct { |
| 59 | 60 | } |
| 60 | 61 | |
| 61 | 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 | 65 | self.blake3.update(val); |
| 65 | 66 | self.blake3.update(&[_]u8{0}); |
| 66 | 67 | } |
| 67 | 68 | |
| 68 | 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 | 72 | const val_type = @TypeOf(val); |
| 72 | 73 | switch (@typeInfo(val_type)) { |
| ... | ... | @@ -88,7 +89,7 @@ pub const CacheHash = struct { |
| 88 | 89 | } |
| 89 | 90 | |
| 90 | 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 | 94 | var cache_hash_file = try self.files.addOne(); |
| 94 | 95 | cache_hash_file.path = try fs.path.resolve(self.alloc, &[_][]const u8{file_path}); |
| ... | ... | @@ -97,7 +98,7 @@ pub const CacheHash = struct { |
| 97 | 98 | } |
| 98 | 99 | |
| 99 | 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 | 103 | var bin_digest: [BIN_DIGEST_LEN]u8 = undefined; |
| 103 | 104 | self.blake3.final(&bin_digest); |
| ... | ... | @@ -116,21 +117,12 @@ pub const CacheHash = struct { |
| 116 | 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 | | var path_buf = ArrayList(u8).fromOwnedSlice(self.alloc, manifest_file_path_slice); |
| 121 | | defer path_buf.deinit(); |
| 122 | | try path_buf.appendSlice(".txt"); |
| 120 | const manifest_file_path = try fmt.allocPrint(self.alloc, "{}.txt", .{self.b64_digest.toSlice()}); |
| 121 | defer self.alloc.free(manifest_file_path); |
| 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 | 126 | // create a buffer instead of using readAllAlloc |
| 135 | 127 | // See: https://github.com/ziglang/zig/issues/4656 |
| 136 | 128 | var file_buffer = try Buffer.initCapacity(self.alloc, 16 * 1024); |
| ... | ... | @@ -172,7 +164,7 @@ pub const CacheHash = struct { |
| 172 | 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 | 168 | self.manifest_file.?.close(); |
| 177 | 169 | self.manifest_file = null; |
| 178 | 170 | return error.CacheUnavailable; |
| ... | ... | @@ -245,7 +237,7 @@ pub const CacheHash = struct { |
| 245 | 237 | } |
| 246 | 238 | |
| 247 | 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 | 242 | var bin_digest: [BIN_DIGEST_LEN]u8 = undefined; |
| 251 | 243 | self.blake3.final(&bin_digest); |
| ... | ... | @@ -256,7 +248,7 @@ pub const CacheHash = struct { |
| 256 | 248 | } |
| 257 | 249 | |
| 258 | 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 | 253 | const OUT_DIGEST_LEN = base64.Base64Encoder.calcSize(BIN_DIGEST_LEN); |
| 262 | 254 | var encoded_digest = try Buffer.initSize(self.alloc, OUT_DIGEST_LEN); |
| ... | ... | @@ -274,23 +266,21 @@ pub const CacheHash = struct { |
| 274 | 266 | } |
| 275 | 267 | |
| 276 | 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 | 271 | if (self.manifest_dirty) { |
| 280 | 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 | 277 | self.manifest_file.?.close(); |
| 286 | | if (self.manifest_file_path) |owned_slice| { |
| 287 | | self.alloc.free(owned_slice); |
| 288 | | } |
| 289 | 278 | for (self.files.toSlice()) |*file| { |
| 290 | 279 | file.deinit(self.alloc); |
| 291 | 280 | } |
| 292 | 281 | self.files.deinit(); |
| 293 | 282 | self.b64_digest.deinit(); |
| 283 | self.manifest_dir.close(); |
| 294 | 284 | } |
| 295 | 285 | }; |
| 296 | 286 | |