#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"
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
/// 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);
}
/**
*/
void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) {
if (Percentage)
- CacheOptions.MaxPercentageOfAvailableSpace = Percentage;
+ CacheOptions.Policy.PercentageOfAvailableSpace = Percentage;
}
/**@}*/
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();
+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();
-private:
- // Options that matches the setters above.
- std::string Path;
+ /// 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();
- std::chrono::seconds Interval = 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
}
}
- 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())
}
/// 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())
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;
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<seconds>(TimeStampAge).count()
<< "s old), do not prune.\n");
writeTimestampFile(TimestampFile);
}
- bool ShouldComputeSize = (PercentageOfAvailableSpace > 0);
+ bool ShouldComputeSize = (Policy.PercentageOfAvailableSpace > 0);
// Keep track of space
std::set<std::pair<uint64_t, std::string>> FileSizes;
// 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<seconds>(FileAge).count() << "s old)\n");
sys::fs::remove(File->path());
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);