diff options
author | Joel Rosdahl <joel@rosdahl.net> | 2022-11-10 10:07:33 +0100 |
---|---|---|
committer | Joel Rosdahl <joel@rosdahl.net> | 2022-11-27 21:33:51 +0100 |
commit | 5d2f3c702710acd9fc9f71b2a0c3545b3ad5f841 (patch) | |
tree | 99954f0491f17dfbcb0f935b879e9a7d49e51ece /src/core | |
parent | e186724c2e8e6cf6b831f9735915b0cc753eb995 (diff) | |
download | ccache-5d2f3c702710acd9fc9f71b2a0c3545b3ad5f841.tar.gz |
refactor: Improve FileRecompressor to take a stat
This avoids extra stats in some scenarios.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/FileRecompressor.cpp | 26 | ||||
-rw-r--r-- | src/core/FileRecompressor.hpp | 10 | ||||
-rw-r--r-- | src/core/mainoptions.cpp | 28 |
3 files changed, 30 insertions, 34 deletions
diff --git a/src/core/FileRecompressor.cpp b/src/core/FileRecompressor.cpp index 131a85f9..636d6761 100644 --- a/src/core/FileRecompressor.cpp +++ b/src/core/FileRecompressor.cpp @@ -27,23 +27,23 @@ namespace core { -int64_t -FileRecompressor::recompress(const std::string& cache_file, +Stat +FileRecompressor::recompress(const Stat& stat, std::optional<int8_t> level, KeepAtime keep_atime) { - core::CacheEntry::Header header(cache_file); + core::CacheEntry::Header header(stat.path()); const int8_t wanted_level = level ? (*level == 0 ? core::CacheEntry::default_compression_level : *level) : 0; - const auto old_stat = Stat::lstat(cache_file, Stat::OnError::log); - Stat new_stat(old_stat); + + std::optional<Stat> new_stat; if (header.compression_level != wanted_level) { const auto cache_file_data = util::value_or_throw<core::Error>( - util::read_file<util::Bytes>(cache_file), - FMT("Failed to read {}: ", cache_file)); + util::read_file<util::Bytes>(stat.path()), + FMT("Failed to read {}: ", stat.path())); core::CacheEntry cache_entry(cache_file_data); cache_entry.verify_checksum(); @@ -52,23 +52,23 @@ FileRecompressor::recompress(const std::string& cache_file, level ? core::CompressionType::zstd : core::CompressionType::none; header.compression_level = wanted_level; - AtomicFile new_cache_file(cache_file, AtomicFile::Mode::binary); + AtomicFile new_cache_file(stat.path(), AtomicFile::Mode::binary); new_cache_file.write( core::CacheEntry::serialize(header, cache_entry.payload())); new_cache_file.commit(); - new_stat = Stat::lstat(cache_file, Stat::OnError::log); + new_stat = Stat::lstat(stat.path(), Stat::OnError::log); } // Restore mtime/atime to keep cache LRU cleanup working as expected: if (keep_atime == KeepAtime::yes || new_stat) { - util::set_timestamps(cache_file, old_stat.mtime(), old_stat.atime()); + util::set_timestamps(stat.path(), stat.mtime(), stat.atime()); } m_content_size += header.entry_size; - m_old_size += old_stat.size_on_disk(); - m_new_size += new_stat.size_on_disk(); + m_old_size += stat.size_on_disk(); + m_new_size += (new_stat ? *new_stat : stat).size_on_disk(); - return Util::size_change_kibibyte(old_stat, new_stat); + return new_stat ? *new_stat : stat; } uint64_t diff --git a/src/core/FileRecompressor.hpp b/src/core/FileRecompressor.hpp index b2fdb131..84ce2824 100644 --- a/src/core/FileRecompressor.hpp +++ b/src/core/FileRecompressor.hpp @@ -18,6 +18,8 @@ #pragma once +#include <Stat.hpp> + #include <atomic> #include <cstdint> #include <mutex> @@ -33,10 +35,10 @@ public: FileRecompressor() = default; - // Returns on-disk size change in KiB. - int64_t recompress(const std::string& cache_file, - const std::optional<int8_t> level, - KeepAtime keep_atime); + // Returns stat after recompression. + Stat recompress(const Stat& stat, + std::optional<int8_t> level, + KeepAtime keep_atime); uint64_t content_size() const; uint64_t old_size() const; diff --git a/src/core/mainoptions.cpp b/src/core/mainoptions.cpp index 7b3e639a..9ebe5cee 100644 --- a/src/core/mainoptions.cpp +++ b/src/core/mainoptions.cpp @@ -273,19 +273,14 @@ trim_dir(const std::string& dir, std::optional<std::optional<int8_t>> recompress_level, uint32_t recompress_threads) { - struct File - { - std::string path; - Stat stat; - }; - std::vector<File> files; + std::vector<Stat> files; uint64_t initial_size = 0; Util::traverse(dir, [&](const std::string& path, const bool is_dir) { if (is_dir || TemporaryFile::is_tmp_file(path)) { return; } - const auto stat = Stat::lstat(path); + auto stat = Stat::lstat(path); if (!stat) { // Probably some race, ignore. return; @@ -296,12 +291,11 @@ trim_dir(const std::string& dir, throw Fatal( FMT("this looks like a local cache directory (found {})", path)); } - files.push_back({path, stat}); + files.emplace_back(std::move(stat)); }); std::sort(files.begin(), files.end(), [&](const auto& f1, const auto& f2) { - return trim_lru_mtime ? f1.stat.mtime() < f2.stat.mtime() - : f1.stat.atime() < f2.stat.atime(); + return trim_lru_mtime ? f1.mtime() < f2.mtime() : f1.atime() < f2.atime(); }); int64_t recompression_diff = 0; @@ -313,15 +307,15 @@ trim_dir(const std::string& dir, core::FileRecompressor recompressor; std::atomic<uint64_t> incompressible_size = 0; - for (const auto& file : files) { + for (auto& file : files) { thread_pool.enqueue([&] { try { - recompressor.recompress(file.path, - *recompress_level, - core::FileRecompressor::KeepAtime::yes); + auto new_stat = recompressor.recompress( + file, *recompress_level, core::FileRecompressor::KeepAtime::yes); + file = std::move(new_stat); // Remember new size, if any. } catch (core::Error&) { // Ignore for now. - incompressible_size += file.stat.size_on_disk(); + incompressible_size += file.size_on_disk(); } }); } @@ -345,9 +339,9 @@ trim_dir(const std::string& dir, if (final_size <= trim_max_size) { break; } - if (Util::unlink_tmp(file.path)) { + if (Util::unlink_tmp(file.path())) { ++removed_files; - final_size -= file.stat.size_on_disk(); + final_size -= file.size_on_disk(); } } |