]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Use subsecond resolution timestamps in manifest files
authorJoel Rosdahl <joel@rosdahl.net>
Tue, 20 Sep 2022 17:02:18 +0000 (19:02 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 21 Sep 2022 15:06:33 +0000 (17:06 +0200)
This improves accuracy in with "file_stat_matches" sloppiness.

src/core/Manifest.cpp

index cf4f4fccd4775ce44c0545912ec66b7104cd21bc..19093c0290e40ec559a2f0b897ac348139b9f2cd 100644 (file)
@@ -46,8 +46,8 @@
 // <path_index>    ::= uint32_t
 // <digest>        ::= Digest::size() bytes
 // <fsize>         ::= uint64_t ; file size
-// <mtime>         ::= int64_t ; modification time
-// <ctime>         ::= int64_t ; status change time
+// <mtime>         ::= int64_t ; modification time (ns), 0 = not recorded
+// <ctime>         ::= int64_t ; status change time (ns), 0 = not recorded
 // <results>       ::= <n_results> <result>*
 // <n_results>     ::= uint32_t
 // <result>        ::= <n_indexes> <include_index>* <key>
@@ -76,6 +76,12 @@ template<> struct hash<core::Manifest::FileInfo>
 
 namespace core {
 
+// Format version history:
+//
+// Version 0:
+//   - First version.
+// Version 1:
+//   - mtime and ctime are now stored with nanoseconds resolution.
 const uint8_t Manifest::k_format_version = 1;
 
 void
@@ -107,8 +113,8 @@ Manifest::read(nonstd::span<const uint8_t> data)
     reader.read_int(entry.index);
     reader.read_and_copy_bytes({entry.digest.bytes(), Digest::size()});
     reader.read_int(entry.fsize);
-    entry.mtime.set_sec(reader.read_int<int64_t>());
-    entry.ctime.set_sec(reader.read_int<int64_t>());
+    entry.mtime.set_nsec(reader.read_int<int64_t>());
+    entry.ctime.set_nsec(reader.read_int<int64_t>());
   }
 
   const auto result_count = reader.read_int<uint32_t>();
@@ -264,8 +270,8 @@ Manifest::serialize(util::Bytes& output)
     writer.write_int<uint32_t>(file_info.index);
     writer.write_bytes({file_info.digest.bytes(), Digest::size()});
     writer.write_int(file_info.fsize);
-    writer.write_int(file_info.mtime.sec());
-    writer.write_int(file_info.ctime.sec());
+    writer.write_int(file_info.mtime.nsec());
+    writer.write_int(file_info.ctime.nsec());
   }
 
   writer.write_int<uint32_t>(m_results.size());
@@ -430,15 +436,21 @@ Manifest::inspect(FILE* const stream) const
     PRINT(stream, "    Path index: {}\n", m_file_infos[i].index);
     PRINT(stream, "    Hash: {}\n", m_file_infos[i].digest.to_string());
     PRINT(stream, "    File size: {}\n", m_file_infos[i].fsize);
-    if (m_file_infos[i].mtime == util::TimePoint(-1)) {
+    if (m_file_infos[i].mtime == util::TimePoint()) {
       PRINT_RAW(stream, "    Mtime: -\n");
     } else {
-      PRINT(stream, "    Mtime: {}\n", m_file_infos[i].mtime.sec());
+      PRINT(stream,
+            "    Mtime: {}.{:09}\n",
+            m_file_infos[i].mtime.sec(),
+            m_file_infos[i].mtime.nsec_decimal_part());
     }
-    if (m_file_infos[i].ctime == util::TimePoint(-1)) {
+    if (m_file_infos[i].ctime == util::TimePoint()) {
       PRINT_RAW(stream, "    Ctime: -\n");
     } else {
-      PRINT(stream, "    Ctime: {}\n", m_file_infos[i].ctime.sec());
+      PRINT(stream,
+            "    Ctime: {}.{:09}\n",
+            m_file_infos[i].ctime.sec(),
+            m_file_infos[i].ctime.nsec_decimal_part());
     }
   }