From: Joel Rosdahl Date: Wed, 28 Aug 2019 20:44:13 +0000 (+0200) Subject: Add util::for_each_level_1_subdir function X-Git-Tag: v4.0~803 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=80d0810879c83e9d44f69bef0c164e13eeb9c903;p=thirdparty%2Fccache.git Add util::for_each_level_1_subdir function --- diff --git a/src/util.cpp b/src/util.cpp index f93ba3c1e..34cd7e779 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -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) { diff --git a/src/util.hpp b/src/util.hpp index 662db14d9..597b18fd6 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -31,6 +31,10 @@ namespace util { typedef std::function ProgressReceiver; typedef std::function)> CacheFileVisitor; +typedef std::function + 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 diff --git a/unittest/test_util.cpp b/unittest/test_util.cpp index bd4640f4d..5beec601d 100644 --- a/unittest/test_util.cpp +++ b/unittest/test_util.cpp @@ -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 actual; + util::for_each_level_1_subdir( + "cache_dir", + [&](const std::string& subdir, const util::ProgressReceiver&) { + actual.push_back(subdir); + }, + [](double) {}); + + std::vector 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");