authorgravatar for leroycepearson@geemili.xyzLeRoyce Pearson <leroycepearson@geemili.xyz> 2020-04-11 16:01:17-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-25 13:48:43-04:00
log67d6432d10a081338f719eff4a9dfc9a5eb5b457
treef614987753e6059aaf123f46f78a1ee3ee705bf6
parent73d2747084e92b2907ecf71f180a955ec411975e

Check for problematic timestamps


1 files changed, 29 insertions(+), 2 deletions(-)

lib/std/cache_hash.zig+29-2
...@@ -8,6 +8,7 @@ const mem = @import("mem.zig");...@@ -8,6 +8,7 @@ const mem = @import("mem.zig");
8const fmt = @import("fmt.zig");8const fmt = @import("fmt.zig");
9const Allocator = mem.Allocator;9const Allocator = mem.Allocator;
10const os = @import("os.zig");10const os = @import("os.zig");
11const time = @import("time.zig");
1112
12const base64_encoder = fs.base64_encoder;13const base64_encoder = fs.base64_encoder;
13const base64_decoder = fs.base64_decoder;14const base64_decoder = fs.base64_decoder;
...@@ -198,7 +199,10 @@ pub const CacheHash = struct {...@@ -198,7 +199,10 @@ pub const CacheHash = struct {
198199
199 cache_hash_file.stat = actual_stat;200 cache_hash_file.stat = actual_stat;
200201
201 // TODO: check for problematic timestamp202 if (is_problematic_timestamp(cache_hash_file.stat.mtime)) {
203 cache_hash_file.stat.mtime = 0;
204 cache_hash_file.stat.inode = 0;
205 }
202206
203 var actual_digest: [BIN_DIGEST_LEN]u8 = undefined;207 var actual_digest: [BIN_DIGEST_LEN]u8 = undefined;
204 try hash_file(self.alloc, &actual_digest, &this_file);208 try hash_file(self.alloc, &actual_digest, &this_file);
...@@ -252,7 +256,10 @@ pub const CacheHash = struct {...@@ -252,7 +256,10 @@ pub const CacheHash = struct {
252256
253 cache_hash_file.stat = try this_file.stat();257 cache_hash_file.stat = try this_file.stat();
254258
255 // TODO: check for problematic timestamp259 if (is_problematic_timestamp(cache_hash_file.stat.mtime)) {
260 cache_hash_file.stat.mtime = 0;
261 cache_hash_file.stat.inode = 0;
262 }
256263
257 try hash_file(self.alloc, &cache_hash_file.bin_digest, &this_file);264 try hash_file(self.alloc, &cache_hash_file.bin_digest, &this_file);
258 self.blake3.update(&cache_hash_file.bin_digest);265 self.blake3.update(&cache_hash_file.bin_digest);
...@@ -317,6 +324,16 @@ fn hash_file(alloc: *Allocator, bin_digest: []u8, handle: *const fs.File) !void...@@ -317,6 +324,16 @@ fn hash_file(alloc: *Allocator, bin_digest: []u8, handle: *const fs.File) !void
317 blake3.final(bin_digest);324 blake3.final(bin_digest);
318}325}
319326
327/// If the wall clock time, rounded to the same precision as the
328/// mtime, is equal to the mtime, then we cannot rely on this mtime
329/// yet. We will instead save an mtime value that indicates the hash
330/// must be unconditionally computed.
331fn is_problematic_timestamp(file_mtime_ns: i64) bool {
332 const now_ms = time.milliTimestamp();
333 const file_mtime_ms = @divFloor(file_mtime_ns, time.millisecond);
334 return now_ms == file_mtime_ms;
335}
336
320test "cache file and then recall it" {337test "cache file and then recall it" {
321 const cwd = fs.cwd();338 const cwd = fs.cwd();
322339
...@@ -360,3 +377,13 @@ test "cache file and then recall it" {...@@ -360,3 +377,13 @@ test "cache file and then recall it" {
360 try cwd.deleteTree(temp_manifest_dir);377 try cwd.deleteTree(temp_manifest_dir);
361 try cwd.deleteFile(temp_file);378 try cwd.deleteFile(temp_file);
362}379}
380
381test "give problematic timestamp" {
382 const now_ns = @intCast(i64, time.milliTimestamp() * time.millisecond);
383 debug.assert(is_problematic_timestamp(now_ns));
384}
385
386test "give nonproblematic timestamp" {
387 const now_ns = @intCast(i64, time.milliTimestamp() * time.millisecond) - 1000;
388 debug.assert(!is_problematic_timestamp(now_ns));
389}