summaryrefslogtreecommitdiff
path: root/lib/Support/CachePruning.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support/CachePruning.cpp')
-rw-r--r--lib/Support/CachePruning.cpp70
1 files changed, 37 insertions, 33 deletions
diff --git a/lib/Support/CachePruning.cpp b/lib/Support/CachePruning.cpp
index 60d0964f2764..3e97c991f504 100644
--- a/lib/Support/CachePruning.cpp
+++ b/lib/Support/CachePruning.cpp
@@ -113,6 +113,10 @@ llvm::parseCachePruningPolicy(StringRef PolicyStr) {
return make_error<StringError>("'" + Value + "' not an integer",
inconvertibleErrorCode());
Policy.MaxSizeBytes = Size * Mult;
+ } else if (Key == "cache_size_files") {
+ if (Value.getAsInteger(0, Policy.MaxSizeFiles))
+ return make_error<StringError>("'" + Value + "' not an integer",
+ inconvertibleErrorCode());
} else {
return make_error<StringError>("Unknown key: '" + Key + "'",
inconvertibleErrorCode());
@@ -141,7 +145,7 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) {
if (Policy.Expiration == seconds(0) &&
Policy.MaxSizePercentageOfAvailableSpace == 0 &&
- Policy.MaxSizeBytes == 0) {
+ Policy.MaxSizeBytes == 0 && Policy.MaxSizeFiles == 0) {
DEBUG(dbgs() << "No pruning settings set, exit early\n");
// Nothing will be pruned, early exit
return false;
@@ -161,7 +165,7 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) {
return false;
}
} else {
- if (Policy.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();
@@ -179,22 +183,9 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) {
writeTimestampFile(TimestampFile);
}
- bool ShouldComputeSize =
- (Policy.MaxSizePercentageOfAvailableSpace > 0 || Policy.MaxSizeBytes > 0);
-
- // Keep track of space
+ // Keep track of space. Needs to be kept ordered by size for determinism.
std::set<std::pair<uint64_t, std::string>> FileSizes;
uint64_t TotalSize = 0;
- // Helper to add a path to the set of files to consider for size-based
- // pruning, sorted by size.
- auto AddToFileListForSizePruning =
- [&](StringRef Path) {
- if (!ShouldComputeSize)
- return;
- TotalSize += FileStatus.getSize();
- FileSizes.insert(
- std::make_pair(FileStatus.getSize(), std::string(Path)));
- };
// Walk the entire directory cache, looking for unused files.
std::error_code EC;
@@ -212,15 +203,16 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) {
// Look at this file. If we can't stat it, there's nothing interesting
// there.
- if (sys::fs::status(File->path(), FileStatus)) {
+ ErrorOr<sys::fs::basic_file_status> StatusOrErr = File->status();
+ if (!StatusOrErr) {
DEBUG(dbgs() << "Ignore " << File->path() << " (can't stat)\n");
continue;
}
// If the file hasn't been used recently enough, delete it
- const auto FileAccessTime = FileStatus.getLastAccessedTime();
+ const auto FileAccessTime = StatusOrErr->getLastAccessedTime();
auto FileAge = CurrentTime - FileAccessTime;
- if (FileAge > Policy.Expiration) {
+ if (Policy.Expiration != seconds(0) && FileAge > Policy.Expiration) {
DEBUG(dbgs() << "Remove " << File->path() << " ("
<< duration_cast<seconds>(FileAge).count() << "s old)\n");
sys::fs::remove(File->path());
@@ -228,11 +220,32 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) {
}
// Leave it here for now, but add it to the list of size-based pruning.
- AddToFileListForSizePruning(File->path());
+ TotalSize += StatusOrErr->getSize();
+ FileSizes.insert({StatusOrErr->getSize(), std::string(File->path())});
}
+ auto FileAndSize = FileSizes.rbegin();
+ size_t NumFiles = FileSizes.size();
+
+ auto RemoveCacheFile = [&]() {
+ // Remove the file.
+ sys::fs::remove(FileAndSize->second);
+ // Update size
+ TotalSize -= FileAndSize->first;
+ NumFiles--;
+ DEBUG(dbgs() << " - Remove " << FileAndSize->second << " (size "
+ << FileAndSize->first << "), new occupancy is " << TotalSize
+ << "%\n");
+ ++FileAndSize;
+ };
+
+ // Prune for number of files.
+ if (Policy.MaxSizeFiles)
+ while (NumFiles > Policy.MaxSizeFiles)
+ RemoveCacheFile();
+
// Prune for size now if needed
- if (ShouldComputeSize) {
+ if (Policy.MaxSizePercentageOfAvailableSpace > 0 || Policy.MaxSizeBytes > 0) {
auto ErrOrSpaceInfo = sys::fs::disk_space(Path);
if (!ErrOrSpaceInfo) {
report_fatal_error("Can't get available size");
@@ -252,18 +265,9 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) {
<< "% target is: " << Policy.MaxSizePercentageOfAvailableSpace
<< "%, " << Policy.MaxSizeBytes << " bytes\n");
- auto FileAndSize = FileSizes.rbegin();
- // Remove the oldest accessed files first, till we get below the threshold
- while (TotalSize > TotalSizeTarget && FileAndSize != FileSizes.rend()) {
- // Remove the file.
- sys::fs::remove(FileAndSize->second);
- // Update size
- TotalSize -= FileAndSize->first;
- DEBUG(dbgs() << " - Remove " << FileAndSize->second << " (size "
- << FileAndSize->first << "), new occupancy is " << TotalSize
- << "%\n");
- ++FileAndSize;
- }
+ // Remove the oldest accessed files first, till we get below the threshold.
+ while (TotalSize > TotalSizeTarget && FileAndSize != FileSizes.rend())
+ RemoveCacheFile();
}
return true;
}