From 2edabdec2aa5ab8d31866941886b50dc704aa774 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 15 Mar 2017 22:54:18 +0000 Subject: [PATCH] Support: Simplify the CachePruning API. NFCI. Change the function that implements the pruning into a free function that takes the policy as a struct argument. Differential Revision: https://reviews.llvm.org/D31009 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297907 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/LTO/legacy/ThinLTOCodeGenerator.h | 17 ++++-- include/llvm/Support/CachePruning.h | 60 ++++++------------- lib/LTO/ThinLTOCodeGenerator.cpp | 6 +- lib/Support/CachePruning.cpp | 22 ++++--- 4 files changed, 45 insertions(+), 60 deletions(-) diff --git a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h index 0cc3b26e965..8fdfd3dd714 100644 --- a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringSet.h" #include "llvm/ADT/Triple.h" #include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/Support/CachePruning.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Target/TargetOptions.h" @@ -140,9 +141,13 @@ public: struct CachingOptions { std::string Path; // Path to the cache, empty to disable. - int PruningInterval = 1200; // seconds, -1 to disable pruning. - unsigned int Expiration = 7 * 24 * 3600; // seconds (1w default). - unsigned MaxPercentageOfAvailableSpace = 75; // percentage. + CachePruningPolicy Policy; + + CachingOptions() { + Policy.Interval = std::chrono::seconds(1200); + Policy.Expiration = std::chrono::hours(7 * 24); // 1w + Policy.PercentageOfAvailableSpace = 75; + }; }; /// Provide a path to a directory where to store the cached files for @@ -153,14 +158,14 @@ public: /// negative value (default) to disable pruning. A value of 0 will be ignored. void setCachePruningInterval(int Interval) { if (Interval) - CacheOptions.PruningInterval = Interval; + CacheOptions.Policy.Interval = std::chrono::seconds(Interval); } /// Cache policy: expiration (in seconds) for an entry. /// A value of 0 will be ignored. void setCacheEntryExpiration(unsigned Expiration) { if (Expiration) - CacheOptions.Expiration = Expiration; + CacheOptions.Policy.Expiration = std::chrono::seconds(Expiration); } /** @@ -178,7 +183,7 @@ public: */ void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) { if (Percentage) - CacheOptions.MaxPercentageOfAvailableSpace = Percentage; + CacheOptions.Policy.PercentageOfAvailableSpace = Percentage; } /**@}*/ diff --git a/include/llvm/Support/CachePruning.h b/include/llvm/Support/CachePruning.h index 954fd8ae7ff..282ecd0aacd 100644 --- a/include/llvm/Support/CachePruning.h +++ b/include/llvm/Support/CachePruning.h @@ -20,51 +20,29 @@ namespace llvm { -/// Handle pruning a directory provided a path and some options to control what -/// to prune. -class CachePruning { -public: - /// Prepare to prune \p Path. - CachePruning(StringRef Path) : Path(Path) {} - - /// Define the pruning interval. This is intended to be used to avoid scanning - /// the directory too often. It does not impact the decision of which file to - /// prune. A value of 0 forces the scan to occurs. - CachePruning &setPruningInterval(std::chrono::seconds PruningInterval) { - Interval = PruningInterval; - return *this; - } - - /// Define the expiration for a file. When a file hasn't been accessed for - /// \p ExpireAfter seconds, it is removed from the cache. A value of 0 disable - /// the expiration-based pruning. - CachePruning &setEntryExpiration(std::chrono::seconds ExpireAfter) { - Expiration = ExpireAfter; - return *this; - } - - /// Define the maximum size for the cache directory, in terms of percentage of - /// the available space on the the disk. Set to 100 to indicate no limit, 50 - /// to indicate that the cache size will not be left over half the - /// available disk space. A value over 100 will be reduced to 100. A value of - /// 0 disable the size-based pruning. - CachePruning &setMaxSize(unsigned Percentage) { - PercentageOfAvailableSpace = std::min(100u, Percentage); - return *this; - } - - /// Peform pruning using the supplied options, returns true if pruning - /// occured, i.e. if PruningInterval was expired. - bool prune(); - -private: - // Options that matches the setters above. - std::string Path; - std::chrono::seconds Expiration = std::chrono::seconds::zero(); +struct CachePruningPolicy { + /// The pruning interval. This is intended to be used to avoid scanning the + /// directory too often. It does not impact the decision of which file to + /// prune. A value of 0 forces the scan to occur. std::chrono::seconds Interval = std::chrono::seconds::zero(); + + /// The expiration for a file. When a file hasn't been accessed for Expiration + /// seconds, it is removed from the cache. A value of 0 disables the + /// expiration-based pruning. + std::chrono::seconds Expiration = std::chrono::seconds::zero(); + + /// The maximum size for the cache directory, in terms of percentage of the + /// available space on the the disk. Set to 100 to indicate no limit, 50 to + /// indicate that the cache size will not be left over half the available disk + /// space. A value over 100 will be reduced to 100. A value of 0 disables the + /// size-based pruning. unsigned PercentageOfAvailableSpace = 0; }; +/// Peform pruning using the supplied policy, returns true if pruning +/// occured, i.e. if Policy.Interval was expired. +bool pruneCache(StringRef Path, CachePruningPolicy Policy); + } // namespace llvm #endif diff --git a/lib/LTO/ThinLTOCodeGenerator.cpp b/lib/LTO/ThinLTOCodeGenerator.cpp index 9e3b89bc17c..b793d0c9e3e 100644 --- a/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/lib/LTO/ThinLTOCodeGenerator.cpp @@ -1023,11 +1023,7 @@ void ThinLTOCodeGenerator::run() { } } - CachePruning(CacheOptions.Path) - .setPruningInterval(std::chrono::seconds(CacheOptions.PruningInterval)) - .setEntryExpiration(std::chrono::seconds(CacheOptions.Expiration)) - .setMaxSize(CacheOptions.MaxPercentageOfAvailableSpace) - .prune(); + pruneCache(CacheOptions.Path, CacheOptions.Policy); // If statistics were requested, print them out now. if (llvm::AreStatisticsEnabled()) diff --git a/lib/Support/CachePruning.cpp b/lib/Support/CachePruning.cpp index 3831625962c..27cffb7721a 100644 --- a/lib/Support/CachePruning.cpp +++ b/lib/Support/CachePruning.cpp @@ -34,7 +34,7 @@ static void writeTimestampFile(StringRef TimestampFile) { } /// Prune the cache of files that haven't been accessed in a long time. -bool CachePruning::prune() { +bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) { using namespace std::chrono; if (Path.empty()) @@ -47,7 +47,11 @@ bool CachePruning::prune() { if (!isPathDir) return false; - if (Expiration == seconds(0) && PercentageOfAvailableSpace == 0) { + Policy.PercentageOfAvailableSpace = + std::min(Policy.PercentageOfAvailableSpace, 100u); + + if (Policy.Expiration == seconds(0) && + Policy.PercentageOfAvailableSpace == 0) { DEBUG(dbgs() << "No pruning settings set, exit early\n"); // Nothing will be pruned, early exit return false; @@ -67,12 +71,12 @@ bool CachePruning::prune() { return false; } } else { - if (Interval == seconds(0)) { + if (Policy.Interval == seconds(0)) { // Check whether the time stamp is older than our pruning interval. // If not, do nothing. const auto TimeStampModTime = FileStatus.getLastModificationTime(); auto TimeStampAge = CurrentTime - TimeStampModTime; - if (TimeStampAge <= Interval) { + if (TimeStampAge <= Policy.Interval) { DEBUG(dbgs() << "Timestamp file too recent (" << duration_cast(TimeStampAge).count() << "s old), do not prune.\n"); @@ -85,7 +89,7 @@ bool CachePruning::prune() { writeTimestampFile(TimestampFile); } - bool ShouldComputeSize = (PercentageOfAvailableSpace > 0); + bool ShouldComputeSize = (Policy.PercentageOfAvailableSpace > 0); // Keep track of space std::set> FileSizes; @@ -122,7 +126,7 @@ bool CachePruning::prune() { // If the file hasn't been used recently enough, delete it const auto FileAccessTime = FileStatus.getLastAccessedTime(); auto FileAge = CurrentTime - FileAccessTime; - if (FileAge > Expiration) { + if (FileAge > Policy.Expiration) { DEBUG(dbgs() << "Remove " << File->path() << " (" << duration_cast(FileAge).count() << "s old)\n"); sys::fs::remove(File->path()); @@ -143,9 +147,11 @@ bool CachePruning::prune() { auto AvailableSpace = TotalSize + SpaceInfo.free; auto FileAndSize = FileSizes.rbegin(); DEBUG(dbgs() << "Occupancy: " << ((100 * TotalSize) / AvailableSpace) - << "% target is: " << PercentageOfAvailableSpace << "\n"); + << "% target is: " << Policy.PercentageOfAvailableSpace + << "\n"); // Remove the oldest accessed files first, till we get below the threshold - while (((100 * TotalSize) / AvailableSpace) > PercentageOfAvailableSpace && + while (((100 * TotalSize) / AvailableSpace) > + Policy.PercentageOfAvailableSpace && FileAndSize != FileSizes.rend()) { // Remove the file. sys::fs::remove(FileAndSize->second);