[llvm] r297927 - Support: Add a cache pruning policy parser.
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 15 20:42:00 PDT 2017
Author: pcc
Date: Wed Mar 15 22:42:00 2017
New Revision: 297927
URL: http://llvm.org/viewvc/llvm-project?rev=297927&view=rev
Log:
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
Added:
llvm/trunk/unittests/Support/CachePruningTest.cpp
Modified:
llvm/trunk/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
llvm/trunk/include/llvm/Support/CachePruning.h
llvm/trunk/lib/Support/CachePruning.cpp
llvm/trunk/unittests/Support/CMakeLists.txt
Modified: llvm/trunk/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h?rev=297927&r1=297926&r2=297927&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h (original)
+++ llvm/trunk/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h Wed Mar 15 22:42:00 2017
@@ -142,12 +142,6 @@ public:
struct CachingOptions {
std::string Path; // Path to the cache, empty to disable.
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
Modified: llvm/trunk/include/llvm/Support/CachePruning.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CachePruning.h?rev=297927&r1=297926&r2=297927&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/CachePruning.h (original)
+++ llvm/trunk/include/llvm/Support/CachePruning.h Wed Mar 15 22:42:00 2017
@@ -20,25 +20,36 @@
namespace llvm {
+template <typename T> class Expected;
+
+/// Policy for the pruneCache() function. A default constructed
+/// CachePruningPolicy provides a reasonable default policy.
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();
+ std::chrono::seconds Interval = std::chrono::seconds(1200);
/// 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 Expiration = std::chrono::hours(7 * 24); // 1w
/// 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;
+ unsigned PercentageOfAvailableSpace = 75;
};
+/// Parse the given string as a cache pruning policy. Defaults are taken from a
+/// default constructed CachePruningPolicy object.
+/// For example: "prune_interval=30s:prune_after=24h:cache_size=50%"
+/// which means a pruning interval of 30 seconds, expiration time of 24 hours
+/// and maximum cache size of 50% of available disk space.
+Expected<CachePruningPolicy> parseCachePruningPolicy(StringRef PolicyStr);
+
/// Peform pruning using the supplied policy, returns true if pruning
/// occured, i.e. if Policy.Interval was expired.
bool pruneCache(StringRef Path, CachePruningPolicy Policy);
Modified: llvm/trunk/lib/Support/CachePruning.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CachePruning.cpp?rev=297927&r1=297926&r2=297927&view=diff
==============================================================================
--- llvm/trunk/lib/Support/CachePruning.cpp (original)
+++ llvm/trunk/lib/Support/CachePruning.cpp Wed Mar 15 22:42:00 2017
@@ -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
raw_fd_ostream Out(TimestampFile.str(), EC, sys::fs::F_None);
}
+static Expected<std::chrono::seconds> parseDuration(StringRef Duration) {
+ if (Duration.empty())
+ return make_error<StringError>("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<StringError>("'" + 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<StringError>("'" + Duration +
+ "' must end with one of 's', 'm' or 'h'",
+ inconvertibleErrorCode());
+ }
+}
+
+Expected<CachePruningPolicy>
+llvm::parseCachePruningPolicy(StringRef PolicyStr) {
+ CachePruningPolicy Policy;
+ std::pair<StringRef, StringRef> 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<StringError>("'" + 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<StringError>("'" + SizeStr + "' not an integer",
+ inconvertibleErrorCode());
+ if (Size > 100)
+ return make_error<StringError>("'" + SizeStr +
+ "' must be between 0 and 100",
+ inconvertibleErrorCode());
+ Policy.PercentageOfAvailableSpace = Size;
+ } else {
+ return make_error<StringError>("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;
Modified: llvm/trunk/unittests/Support/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=297927&r1=297926&r2=297927&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/CMakeLists.txt (original)
+++ llvm/trunk/unittests/Support/CMakeLists.txt Wed Mar 15 22:42:00 2017
@@ -10,6 +10,7 @@ add_llvm_unittest(SupportTests
BinaryStreamTest.cpp
BlockFrequencyTest.cpp
BranchProbabilityTest.cpp
+ CachePruningTest.cpp
Casting.cpp
Chrono.cpp
CommandLineTest.cpp
Added: llvm/trunk/unittests/Support/CachePruningTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CachePruningTest.cpp?rev=297927&view=auto
==============================================================================
--- llvm/trunk/unittests/Support/CachePruningTest.cpp (added)
+++ llvm/trunk/unittests/Support/CachePruningTest.cpp Wed Mar 15 22:42:00 2017
@@ -0,0 +1,71 @@
+//===- CachePruningTest.cpp -----------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CachePruning.h"
+#include "llvm/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(CachePruningPolicyParser, Empty) {
+ auto P = parseCachePruningPolicy("");
+ ASSERT_TRUE(bool(P));
+ EXPECT_EQ(std::chrono::seconds(1200), P->Interval);
+ EXPECT_EQ(std::chrono::hours(7 * 24), P->Expiration);
+ EXPECT_EQ(75u, P->PercentageOfAvailableSpace);
+}
+
+TEST(CachePruningPolicyParser, Interval) {
+ auto P = parseCachePruningPolicy("prune_interval=1s");
+ ASSERT_TRUE(bool(P));
+ EXPECT_EQ(std::chrono::seconds(1), P->Interval);
+ P = parseCachePruningPolicy("prune_interval=2m");
+ ASSERT_TRUE(bool(P));
+ EXPECT_EQ(std::chrono::minutes(2), P->Interval);
+ P = parseCachePruningPolicy("prune_interval=3h");
+ ASSERT_TRUE(bool(P));
+ EXPECT_EQ(std::chrono::hours(3), P->Interval);
+}
+
+TEST(CachePruningPolicyParser, Expiration) {
+ auto P = parseCachePruningPolicy("prune_after=1s");
+ ASSERT_TRUE(bool(P));
+ EXPECT_EQ(std::chrono::seconds(1), P->Expiration);
+}
+
+TEST(CachePruningPolicyParser, PercentageOfAvailableSpace) {
+ auto P = parseCachePruningPolicy("cache_size=100%");
+ ASSERT_TRUE(bool(P));
+ EXPECT_EQ(100u, P->PercentageOfAvailableSpace);
+}
+
+TEST(CachePruningPolicyParser, Multiple) {
+ auto P = parseCachePruningPolicy("prune_after=1s:cache_size=50%");
+ ASSERT_TRUE(bool(P));
+ EXPECT_EQ(std::chrono::seconds(1200), P->Interval);
+ EXPECT_EQ(std::chrono::seconds(1), P->Expiration);
+ EXPECT_EQ(50u, P->PercentageOfAvailableSpace);
+}
+
+TEST(CachePruningPolicyParser, Errors) {
+ EXPECT_EQ("Duration must not be empty",
+ toString(parseCachePruningPolicy("prune_interval=").takeError()));
+ EXPECT_EQ("'foo' not an integer",
+ toString(parseCachePruningPolicy("prune_interval=foos").takeError()));
+ EXPECT_EQ("'24x' must end with one of 's', 'm' or 'h'",
+ toString(parseCachePruningPolicy("prune_interval=24x").takeError()));
+ EXPECT_EQ("'foo' must be a percentage",
+ toString(parseCachePruningPolicy("cache_size=foo").takeError()));
+ EXPECT_EQ("'foo' not an integer",
+ toString(parseCachePruningPolicy("cache_size=foo%").takeError()));
+ EXPECT_EQ("'101' must be between 0 and 100",
+ toString(parseCachePruningPolicy("cache_size=101%").takeError()));
+ EXPECT_EQ("Unknown key: 'foo'",
+ toString(parseCachePruningPolicy("foo=bar").takeError()));
+}
More information about the llvm-commits
mailing list