]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Add util::for_each_level_1_subdir function
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 28 Aug 2019 20:44:13 +0000 (22:44 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 5 Sep 2019 20:04:43 +0000 (22:04 +0200)
src/util.cpp
src/util.hpp
unittest/test_util.cpp

index f93ba3c1e144076eb02e80256818333e8f85a9fb..34cd7e779dd8cdb6bc8d83286dede9f4a774e015 100644 (file)
@@ -1827,6 +1827,22 @@ get_level_1_files(const std::string& dir,
   get_cache_files_internal(dir, 1, progress_receiver, files);
 }
 
+void
+for_each_level_1_subdir(const std::string& cache_dir,
+                        const SubdirVisitor& subdir_visitor,
+                        const ProgressReceiver& progress_receiver)
+{
+  for (int i = 0; i <= 0xF; i++) {
+    double progress = 1.0 * i / 16;
+    progress_receiver(progress);
+    std::string subdir_path = fmt::format("{}/{:x}", cache_dir, i);
+    subdir_visitor(subdir_path, [&](double inner_progress) {
+      progress_receiver(progress + inner_progress / 16);
+    });
+  }
+  progress_receiver(1.0);
+}
+
 std::string
 read_file(const std::string& path)
 {
index 662db14d918400838a595c70dba70a86c99c147b..597b18fd6ad3fa1c14b324586d9f134befc01dd4 100644 (file)
@@ -31,6 +31,10 @@ namespace util {
 
 typedef std::function<void(double)> ProgressReceiver;
 typedef std::function<void(std::shared_ptr<CacheFile>)> CacheFileVisitor;
+typedef std::function<void(const std::string& /*dir_path*/,
+                           const ProgressReceiver& /*progress_receiver*/)>
+  SubdirVisitor;
+
 // Get base name of path.
 std::string base_name(const std::string& path);
 
@@ -45,6 +49,17 @@ std::string dir_name(const std::string& path);
 // Return true if suffix is a suffix of string.
 bool ends_with(const std::string& string, const std::string& suffix);
 
+// Call a function for each subdir (0-9a-f) in the cache.
+//
+// Parameters:
+// - cache_dir: Path to the cache directory.
+// - visitor: Function to call with directory path and progress_receiver as
+//   arguments.
+// - progress_receiver: Function that will be called for progress updates.
+void for_each_level_1_subdir(const std::string& cache_dir,
+                             const SubdirVisitor& visitor,
+                             const ProgressReceiver& progress_receiver);
+
 // Get a list of files in a level 1 subdirectory of the cache.
 //
 // The function works under the assumption that directory entries with one
index bd4640f4d382c10555384bf1a810399054aa9119..5beec601dd6d174f82b08563307a8c41ea22e9cf 100644 (file)
@@ -71,6 +71,37 @@ TEST_CASE("util::ends_with")
   CHECK_FALSE(util::ends_with("x", "xy"));
 }
 
+TEST_CASE("util::for_each_level_1_subdir")
+{
+  std::vector<std::string> actual;
+  util::for_each_level_1_subdir(
+    "cache_dir",
+    [&](const std::string& subdir, const util::ProgressReceiver&) {
+      actual.push_back(subdir);
+    },
+    [](double) {});
+
+  std::vector<std::string> expected = {
+    "cache_dir/0",
+    "cache_dir/1",
+    "cache_dir/2",
+    "cache_dir/3",
+    "cache_dir/4",
+    "cache_dir/5",
+    "cache_dir/6",
+    "cache_dir/7",
+    "cache_dir/8",
+    "cache_dir/9",
+    "cache_dir/a",
+    "cache_dir/b",
+    "cache_dir/c",
+    "cache_dir/d",
+    "cache_dir/e",
+    "cache_dir/f",
+  };
+  CHECK(actual == expected);
+}
+
 TEST_CASE("util::get_level_1_files")
 {
   util::create_dir("e/m/p/t/y");