122 static_assert(ValBytes.size() ==
sizeof(ID.getOpaqueData()));
132 std::optional<ArrayRef<char>> UpstreamValue;
133 if (
Error E = UpstreamKVDB->get(
Key).moveInto(UpstreamValue))
143 PrimaryGraphDB->getReference(UpstreamGraphDB->getDigest(UpstreamID));
145 return PrimaryID.takeError();
162 DirI.increment(EC)) {
167 FoundDBDirs.
push_back({0, std::string(SubDir)});
175 "unexpected directory " + DirI->path());
176 FoundDBDirs.
push_back({Order, std::string(SubDir)});
182 return LHS.Order <
RHS.Order;
186 for (DBDir &Dir : FoundDBDirs)
194 return DBDirs.takeError();
199 for (
unsigned Keep = 2;
Keep > 0 && !DBDirs->empty(); --
Keep) {
224 unsigned HashByteSize,
bool CheckHash,
226 std::shared_ptr<UnifiedOnDiskCache> UniDB;
231 if (
Error E = UniDB->getGraphDB().validate(CheckHash, HashFn))
233 if (
Error E = UniDB->validateActionCache())
260class LockedValidationFile {
265 static constexpr uint64_t ValidationPending =
266 std::numeric_limits<uint64_t>::max();
268 static Expected<std::unique_ptr<LockedValidationFile>>
269 open(StringRef RootPath) {
273 SmallString<256> PathBuf(RootPath);
280 std::unique_ptr<LockedValidationFile> VF(
281 new LockedValidationFile(PathBuf, FD));
283 if (std::error_code EC =
288 SmallString<8> Bytes;
291 if (!Bytes.
empty()) {
293 if (StringRef(Bytes).trim().getAsInteger(10,
Value))
298 return std::move(VF);
301 ~LockedValidationFile() {
309 uint64_t getLastValidBootTime()
const {
310 return isValidationPending() ? 0 : State.value_or(0);
316 bool isValidAtBoot(
uint64_t BootTime)
const {
321 return BootTime != 0 && !isValidationPending() && State &&
325 bool isValidationPending()
const {
return State == ValidationPending; }
327 Error setValidationPending() {
return write(ValidationPending); }
332 LockedValidationFile(StringRef Path,
int FD)
340 raw_fd_ostream OS(FD,
false);
349 SmallString<256>
Path;
351 sys::fs::file_t
File;
353 std::optional<uint64_t> State;
370 if (EC == std::errc::no_lock_available)
373 "CAS recovery requires exclusive access but CAS was in use");
380 return DBDirs.takeError();
390 int Attempt = 0, MaxAttempts = 100;
392 for (; Attempt < MaxAttempts; ++Attempt) {
399 if (Attempt == MaxAttempts)
402 "rename " + PathBuf +
403 " failed: too many CAS directories awaiting pruning");
406 " failed: " + EC.message());
414 std::unique_ptr<LockedValidationFile> VF;
415 if (
Error E = LockedValidationFile::open(RootPath).moveInto(VF))
418 std::shared_ptr<ondisk::OnDiskCASLogger> Logger;
426 uint64_t ValidationBootTime = VF->getLastValidBootTime();
429 std::string LogValidationError;
434 Logger->logUnifiedOnDiskCacheValidateIfNeeded(
435 RootPath, BootTime, ValidationBootTime, CheckHash, ForceValidation,
439 if (VF->isValidAtBoot(BootTime) && !ForceValidation) {
446 if (
Error E = VF->setValidationPending())
456 if (
Error E = VF->setLastValidBootTime(BootTime))
462 std::unique_ptr<LockedValidationFile> VF;
463 if (
Error E = LockedValidationFile::open(RootPath).moveInto(VF))
466 std::shared_ptr<ondisk::OnDiskCASLogger> Logger;
476 std::string LogRecoveryError;
481 Logger->logUnifiedOnDiskCacheRecover(RootPath, BootTime, LogRecoveryError,
488 if (!VF->isValidationPending()) {
499 if (
Error E = VF->setLastValidBootTime(BootTime))
506 StringRef HashName,
unsigned HashByteSize,
524 if (std::error_code EC =
530 return DBDirs.takeError();
534 std::shared_ptr<ondisk::OnDiskCASLogger> Logger;
545 auto UniDB = std::unique_ptr<UnifiedOnDiskCache>(
new UnifiedOnDiskCache());
546 std::unique_ptr<OnDiskGraphDB> UpstreamGraphDB;
547 std::unique_ptr<OnDiskKeyValueDB> UpstreamKVDB;
548 if (DBDirs->size() > 1) {
549 StringRef UpstreamDir = *(DBDirs->end() - 2);
554 nullptr, Logger, FaultInPolicy)
555 .moveInto(UpstreamGraphDB))
561 .moveInto(UpstreamKVDB))
565 StringRef PrimaryDir = *(DBDirs->end() - 1);
568 std::unique_ptr<OnDiskGraphDB> PrimaryGraphDB;
571 UpstreamGraphDB.get(), Logger, FaultInPolicy)
572 .moveInto(PrimaryGraphDB))
574 std::unique_ptr<OnDiskKeyValueDB> PrimaryKVDB;
581 .moveInto(PrimaryKVDB))
584 UniDB->RootPath = RootPath;
585 UniDB->SizeLimit = SizeLimit.value_or(0);
586 UniDB->LockFD = LockFD;
587 UniDB->NeedsGarbageCollection = DBDirs->size() > 2;
588 UniDB->PrimaryDBDir = PrimaryDir;
589 UniDB->UpstreamGraphDB = std::move(UpstreamGraphDB);
590 UniDB->PrimaryGraphDB = std::move(PrimaryGraphDB);
591 UniDB->UpstreamKVDB = std::move(UpstreamKVDB);
592 UniDB->PrimaryKVDB = std::move(PrimaryKVDB);
593 UniDB->Logger = std::move(Logger);
595 return std::move(UniDB);
599 this->SizeLimit = SizeLimit.value_or(0);
603 uint64_t TotalSize = getPrimaryStorageSize();
605 TotalSize += UpstreamGraphDB->getStorageSize();
607 TotalSize += UpstreamKVDB->getStorageSize();
611uint64_t UnifiedOnDiskCache::getPrimaryStorageSize()
const {
612 return PrimaryGraphDB->getStorageSize() + PrimaryKVDB->getStorageSize();
616 uint64_t CurSizeLimit = SizeLimit;
621 unsigned CurrentPercent =
622 std::max(PrimaryGraphDB->getHardStorageLimitUtilization(),
623 PrimaryKVDB->getHardStorageLimitUtilization());
624 if (CurrentPercent > 85)
637 return (CurSizeLimit / 2) < getPrimaryStorageSize();
653 UpstreamKVDB.reset();
655 UpstreamGraphDB.reset();
656 PrimaryGraphDB.reset();
660 if (!ExceededSizeLimit)
689 NeedsGarbageCollection =
true;
693UnifiedOnDiskCache::UnifiedOnDiskCache() =
default;
701 return DBDirs.takeError();
707 Logger->logUnifiedOnDiskCacheCollectGarbage(PathBuf);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
This file declares interface for OnDiskCASLogger, an interface that can be used to log CAS events to ...
This declares OnDiskGraphDB, an ondisk CAS database with a fixed length hash.
This declares OnDiskKeyValueDB, a key value storage database of fixed size key and value.
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallString class.
This file defines the SmallVector class.
static Error validateInProcess(StringRef RootPath, StringRef HashName, unsigned HashByteSize, bool CheckHash, OnDiskGraphDB::HashingFuncT HashFn)
static constexpr StringLiteral DBDirPrefix
FIXME: When the version of DBDirPrefix is bumped up we need to figure out how to handle the leftover ...
static Expected< SmallVector< std::string, 4 > > getAllGarbageDirs(StringRef Path)
static constexpr StringLiteral ValidationFilename
static constexpr StringLiteral CorruptPrefix
static uint64_t getCachedBootTime()
static void getNextDBDirName(StringRef DBDir, llvm::raw_ostream &OS)
static Error markAllDBDirsCorrupt(StringRef RootPath)
Marks all the database directories in RootPath as corrupt, which makes them eligible for garbage coll...
static Expected< SmallVector< std::string, 4 > > getAllDBDirs(StringRef Path, bool IncludeCorrupt=false)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void assign(StringRef RHS)
Assign from a StringRef.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
static ObjectID fromOpaqueData(uint64_t Opaque)
Interface for logging low-level on-disk cas operations.
static LLVM_ABI Expected< std::unique_ptr< OnDiskCASLogger > > openIfEnabled(const Twine &Path)
Create or append to a log file inside the given CAS directory Path if logging is enabled by the envir...
FaultInPolicy
How to fault-in nodes if an upstream database is used.
static LLVM_ABI Expected< std::unique_ptr< OnDiskGraphDB > > open(StringRef Path, StringRef HashName, unsigned HashByteSize, OnDiskGraphDB *UpstreamDB=nullptr, std::shared_ptr< OnDiskCASLogger > Logger=nullptr, FaultInPolicy Policy=FaultInPolicy::FullTree)
Open the on-disk store from a directory.
function_ref< void( ArrayRef< ArrayRef< uint8_t > >, ArrayRef< char >, SmallVectorImpl< uint8_t > &)> HashingFuncT
Hashing function type for validation.
static LLVM_ABI Expected< std::unique_ptr< OnDiskKeyValueDB > > open(StringRef Path, StringRef HashName, unsigned KeySize, StringRef ValueName, size_t ValueSize, UnifiedOnDiskCache *UnifiedCache=nullptr, std::shared_ptr< OnDiskCASLogger > Logger=nullptr)
Open the on-disk store from a directory.
LLVM_ABI Error validate() const
Validate the storage.
LLVM_ABI uint64_t getStorageSize() const
static LLVM_ABI ValueBytes getValueFromObjectID(ObjectID ID)
static LLVM_ABI Expected< ValidationResult > recover(StringRef Path)
Recover from invalid data in Path after a failed validateIfNeeded, by marking all the data for garbag...
static LLVM_ABI Expected< std::unique_ptr< UnifiedOnDiskCache > > open(StringRef Path, std::optional< uint64_t > SizeLimit, StringRef HashName, unsigned HashByteSize, OnDiskGraphDB::FaultInPolicy FaultInPolicy=OnDiskGraphDB::FaultInPolicy::FullTree)
Open a UnifiedOnDiskCache instance for a directory.
LLVM_ABI Error close(bool CheckSizeLimit=true)
This is called implicitly at destruction time, so it is not required for a client to call this.
LLVM_ABI Error validateActionCache() const
Validate the action cache only.
static LLVM_ABI ObjectID getObjectIDFromValue(ArrayRef< char > Value)
Helper function to convert the value stored in KeyValueDB and ObjectID.
static LLVM_ABI Expected< ValidationResult > validateIfNeeded(StringRef Path, StringRef HashName, unsigned HashByteSize, bool CheckHash, OnDiskGraphDB::HashingFuncT HashFn, bool ForceValidation)
Validate the data in Path in-process, if it has not been validated since the last system boot.
LLVM_ABI bool hasExceededSizeLimit() const
LLVM_ABI ~UnifiedOnDiskCache()
OnDiskKeyValueDB & getKeyValueDB()
The OnDiskGraphDB instance for the open directory.
std::array< char, sizeof(uint64_t)> ValueBytes
LLVM_ABI Error collectGarbage()
Remove unused data from the current UnifiedOnDiskCache.
LLVM_ABI void setSizeLimit(std::optional< uint64_t > SizeLimit)
Set the size for limiting growth.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
directory_iterator - Iterates through the entries in path.
std::error_code lockFileThreadSafe(int FD, llvm::sys::fs::LockKind Kind)
Thread-safe alternative to sys::fs::lockFile.
std::error_code unlockFileThreadSafe(int FD)
Thread-safe alternative to sys::fs::unlockFile.
std::error_code tryLockFileThreadSafe(int FD, std::chrono::milliseconds Timeout=std::chrono::milliseconds(0), llvm::sys::fs::LockKind Kind=llvm::sys::fs::LockKind::Exclusive)
Thread-safe alternative to sys::fs::tryLockFile.
LLVM_ABI_FOR_TEST Expected< uint64_t > getBootTime()
Get boot time for the OS.
@ Valid
The data is already valid.
@ Recovered
The data was invalid, but was recovered.
@ Skipped
Validation or recovery was skipped, as it was not needed.
uint64_t read64le(const void *P)
void write64le(void *P, uint64_t V)
LLVM_ABI std::error_code closeFile(file_t &F)
Close the file object.
std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp, OpenFlags Flags, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
LLVM_ABI std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
LLVM_ABI Error readNativeFileToEOF(file_t FileHandle, SmallVectorImpl< char > &Buffer, ssize_t ChunkSize=DefaultReadChunkSize)
Reads from FileHandle until EOF, appending to Buffer in chunks of size ChunkSize.
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
@ CD_OpenAlways
CD_OpenAlways - When opening a file:
LLVM_ABI std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
LLVM_ABI std::error_code resize_file(int FD, uint64_t Size)
Resize path to size.
LLVM_ABI file_t convertFDToNativeFile(int FD)
Converts from a Posix file descriptor number to a native file handle.
LLVM_ABI std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
LLVM_ABI std::error_code remove_directories(const Twine &path, bool IgnoreErrors=true)
Recursively delete a directory.
LLVM_ABI StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
LLVM_ABI void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
ScopedSetting scopedDisable()
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
testing::Matcher< const detail::ErrorHolder & > Failed()
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
std::optional< T > expectedToOptional(Expected< T > &&E)
Convert an Expected to an std::optional without doing anything.
LLVM_ABI std::string toStringWithoutConsuming(const Error &E)
Like toString(), but does not consume the error.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
void consumeError(Error Err)
Consume a Error without doing anything.
LLVM_ABI Error write(DWPWriter &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue, raw_pwrite_stream *OS=nullptr)
@ Keep
No function return thunk.
This class wraps the platform specific file handle/descriptor type to provide an unified representati...