diff options
Diffstat (limited to 'lib/Support/CachePruning.cpp')
-rw-r--r-- | lib/Support/CachePruning.cpp | 70 |
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; } |