]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Add progress bar for -x/--show-compression
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 4 Sep 2019 19:11:04 +0000 (21:11 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 5 Sep 2019 20:04:43 +0000 (22:04 +0200)
dev.mk.in
src/ccache.cpp
src/ccache.hpp
src/compress.cpp
src/compress.hpp [new file with mode: 0644]

index 3e6f3c83218cf5e48d07ba6ad00ef44b9934b7a8..d558ff2281044b888383e3f3712c53ae3b5731e9 100644 (file)
--- a/dev.mk.in
+++ b/dev.mk.in
@@ -44,6 +44,7 @@ non_third_party_headers = \
     src/cleanup.hpp \
     src/common_header.hpp \
     src/compopt.hpp \
+    src/compress.hpp \
     src/compression.hpp \
     src/counters.hpp \
     src/hash.hpp \
index 4b0297485cf4252c85d121fe79cae9490eddb5d3..a9fb738b00a5696afc82291591663d4ebc1693c1 100644 (file)
@@ -33,6 +33,7 @@
 #else
 #  include "third_party/getopt_long.h"
 #endif
+#include "compress.hpp"
 #include "hash.hpp"
 #include "hashutil.hpp"
 #include "language.hpp"
@@ -4071,9 +4072,13 @@ ccache_main_options(int argc, char* argv[])
       x_exit(0);
 
     case 'x': // --show-compression
+    {
       initialize();
-      compress_stats(g_config);
+      ProgressBar progress_bar("Scanning...");
+      compress_stats(g_config,
+                     [&](double progress) { progress_bar.update(progress); });
       break;
+    }
 
     case 'z': // --zero-stats
       initialize();
index 56ed97a04bf26434eebffe0f98a4a88dc2f4e40c..9ff8e01a7cdd86fc173f338ca0f35359bb14b934 100644 (file)
@@ -249,11 +249,6 @@ void exitfn_add(void (*function)(void*), void* context);
 void exitfn_add_last(void (*function)(void*), void* context);
 void exitfn_call(void);
 
-// ----------------------------------------------------------------------------
-// compress.c
-
-void compress_stats(const Config& config);
-
 // ----------------------------------------------------------------------------
 // execute.c
 
index bd066608678f7af5ae04575c92db3879792f63f0..ef2dc0645dfe8c184dff91ec4fd07732eda50cbb 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
+#include "compress.hpp"
+
 #include "ccache.hpp"
 #include "common_header.hpp"
 #include "manifest.hpp"
 #include "result.hpp"
 
+#include <string>
+
 static bool
-get_content_size(const char* path,
+get_content_size(const std::string& path,
                  const char* magic,
                  uint8_t version,
                  size_t* size)
 {
   char* errmsg;
-  FILE* f = fopen(path, "rb");
+  FILE* f = fopen(path.c_str(), "rb");
   if (!f) {
-    cc_log("Failed to open %s for reading: %s", path, strerror(errno));
+    cc_log("Failed to open %s for reading: %s", path.c_str(), strerror(errno));
     return false;
   }
   struct common_header header;
@@ -44,78 +48,54 @@ get_content_size(const char* path,
   return success;
 }
 
-static uint64_t on_disk_size;
-static uint64_t compr_size;
-static uint64_t compr_orig_size;
-static uint64_t incompr_size;
-
-// This measures the size of files in the cache.
-static void
-measure_fn(const char* fname, struct stat* st)
-{
-  if (!S_ISREG(st->st_mode)) {
-    return;
-  }
-
-  char* p = x_basename(fname);
-  if (str_eq(p, "stats")) {
-    free(p);
-    return;
-  }
-
-  if (str_startswith(p, ".nfs")) {
-    // Ignore temporary NFS files that may be left for open but deleted files.
-    free(p);
-    return;
-  }
-
-  if (strstr(p, ".tmp.")) {
-    // Ignore tmp files since they are transient.
-    free(p);
-    return;
-  }
-
-  if (strstr(p, "CACHEDIR.TAG")) {
-    free(p);
-    return;
-  }
-
-  free(p);
-
-  on_disk_size += file_size(st);
-
-  size_t content_size = 0;
-  const char* file_ext = get_extension(p);
-  bool is_compressible = false;
-  if (str_eq(file_ext, ".manifest")) {
-    is_compressible =
-      get_content_size(fname, MANIFEST_MAGIC, MANIFEST_VERSION, &content_size);
-  } else if (str_eq(file_ext, ".result")) {
-    is_compressible =
-      get_content_size(fname, RESULT_MAGIC, RESULT_VERSION, &content_size);
-  }
-
-  if (is_compressible) {
-    compr_size += st->st_size;
-    compr_orig_size += content_size;
-  } else {
-    incompr_size += st->st_size;
-  }
-}
-
-// Process up all cache subdirectories.
 void
-compress_stats(const Config& config)
+compress_stats(const Config& config,
+               const util::ProgressReceiver& progress_receiver)
 {
-  on_disk_size = 0;
-  compr_size = 0;
-  compr_orig_size = 0;
-  incompr_size = 0;
-
-  for (int i = 0; i <= 0xF; i++) {
-    char* dname = format("%s/%1x", config.cache_dir().c_str(), i);
-    traverse(dname, measure_fn);
-    free(dname);
+  uint64_t on_disk_size = 0;
+  uint64_t compr_size = 0;
+  uint64_t compr_orig_size = 0;
+  uint64_t incompr_size = 0;
+
+  util::for_each_level_1_subdir(
+    config.cache_dir(),
+    [&](const std::string& subdir,
+        const util::ProgressReceiver& sub_progress_receiver) {
+      std::vector<std::shared_ptr<CacheFile>> files;
+      util::get_level_1_files(
+        subdir,
+        [&](double progress) { sub_progress_receiver(progress / 2); },
+        files);
+
+      for (size_t i = 0; i < files.size(); ++i) {
+        const auto& file = files[i];
+
+        on_disk_size += file_size(&file->stat());
+
+        size_t content_size = 0;
+        bool is_compressible = false;
+        if (util::ends_with(file->path(), ".manifest")) {
+          is_compressible = get_content_size(
+            file->path(), MANIFEST_MAGIC, MANIFEST_VERSION, &content_size);
+        } else if (util::ends_with(file->path(), ".result")) {
+          is_compressible = get_content_size(
+            file->path(), RESULT_MAGIC, RESULT_VERSION, &content_size);
+        }
+
+        if (is_compressible) {
+          compr_size += file->stat().st_size;
+          compr_orig_size += content_size;
+        } else {
+          incompr_size += file->stat().st_size;
+        }
+
+        sub_progress_receiver(1.0 / 2 + 1.0 * i / files.size() / 2);
+      }
+    },
+    progress_receiver);
+
+  if (isatty(STDOUT_FILENO)) {
+    printf("\n\n");
   }
 
   double ratio = compr_size > 0 ? ((double)compr_orig_size) / compr_size : 0.0;
diff --git a/src/compress.hpp b/src/compress.hpp
new file mode 100644 (file)
index 0000000..459258c
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#pragma once
+
+#include "Config.hpp"
+#include "util.hpp"
+
+void compress_stats(const Config& config,
+                    const util::ProgressReceiver& progress_receiver);