From d1eac7bc36e2396903244eb4ef6d081f22c97933 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 16 Mar 2017 03:42:00 +0000 Subject: Support: Add a cache pruning policy parser. The idea is that the policy string fully specifies the policy and is portable between clients. Differential Revision: https://reviews.llvm.org/D31020 llvm-svn: 297927 --- llvm/lib/Support/CachePruning.cpp | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'llvm/lib/Support/CachePruning.cpp') diff --git a/llvm/lib/Support/CachePruning.cpp b/llvm/lib/Support/CachePruning.cpp index 27cffb7721a..73e55f24b21 100644 --- a/llvm/lib/Support/CachePruning.cpp +++ b/llvm/lib/Support/CachePruning.cpp @@ -15,6 +15,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -33,6 +34,73 @@ static void writeTimestampFile(StringRef TimestampFile) { raw_fd_ostream Out(TimestampFile.str(), EC, sys::fs::F_None); } +static Expected parseDuration(StringRef Duration) { + if (Duration.empty()) + return make_error("Duration must not be empty", + inconvertibleErrorCode()); + + StringRef NumStr = Duration.slice(0, Duration.size()-1); + uint64_t Num; + if (NumStr.getAsInteger(0, Num)) + return make_error("'" + NumStr + "' not an integer", + inconvertibleErrorCode()); + + switch (Duration.back()) { + case 's': + return std::chrono::seconds(Num); + case 'm': + return std::chrono::minutes(Num); + case 'h': + return std::chrono::hours(Num); + default: + return make_error("'" + Duration + + "' must end with one of 's', 'm' or 'h'", + inconvertibleErrorCode()); + } +} + +Expected +llvm::parseCachePruningPolicy(StringRef PolicyStr) { + CachePruningPolicy Policy; + std::pair P = {"", PolicyStr}; + while (!P.second.empty()) { + P = P.second.split(':'); + + StringRef Key, Value; + std::tie(Key, Value) = P.first.split('='); + if (Key == "prune_interval") { + auto DurationOrErr = parseDuration(Value); + if (!DurationOrErr) + return std::move(DurationOrErr.takeError()); + Policy.Interval = *DurationOrErr; + } else if (Key == "prune_after") { + auto DurationOrErr = parseDuration(Value); + if (!DurationOrErr) + return std::move(DurationOrErr.takeError()); + Policy.Expiration = *DurationOrErr; + } else if (Key == "cache_size") { + if (Value.back() != '%') + return make_error("'" + Value + "' must be a percentage", + inconvertibleErrorCode()); + StringRef SizeStr = Value.slice(0, Value.size() - 1); + uint64_t Size; + if (SizeStr.getAsInteger(0, Size)) + return make_error("'" + SizeStr + "' not an integer", + inconvertibleErrorCode()); + if (Size > 100) + return make_error("'" + SizeStr + + "' must be between 0 and 100", + inconvertibleErrorCode()); + Policy.PercentageOfAvailableSpace = Size; + } else { + return make_error("Unknown key: '" + Key + "'", + inconvertibleErrorCode()); + } + } + + return Policy; +} + /// Prune the cache of files that haven't been accessed in a long time. bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) { using namespace std::chrono; -- cgit v1.2.3