LLVM 23.0.0git
OnDiskKeyValueDB.cpp
Go to the documentation of this file.
1//===- OnDiskKeyValueDB.cpp -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// This file implements OnDiskKeyValueDB, an ondisk key value database.
11///
12/// The KeyValue database file is named `actions.<version>` inside the CAS
13/// directory. The database stores a mapping between a fixed-sized key and a
14/// fixed-sized value, where the size of key and value can be configured when
15/// opening the database.
16///
17//
18//===----------------------------------------------------------------------===//
19
21#include "OnDiskCommon.h"
27#include "llvm/Support/Errc.h"
28#include "llvm/Support/Path.h"
29
30using namespace llvm;
31using namespace llvm::cas;
32using namespace llvm::cas::ondisk;
33
34static constexpr StringLiteral ActionCacheFile = "actions.";
35
38 if (LLVM_UNLIKELY(Value.size() != ValueSize))
40 "expected value size of " + itostr(ValueSize) +
41 ", got: " + itostr(Value.size()));
42 assert(Value.size() == ValueSize);
43 auto ActionP = Cache.insertLazy(
44 Key, [&](FileOffset TentativeOffset,
45 OnDiskTrieRawHashMap::ValueProxy TentativeValue) {
46 assert(TentativeValue.Data.size() == ValueSize);
47 llvm::copy(Value, TentativeValue.Data.data());
48 });
49 if (LLVM_UNLIKELY(!ActionP))
50 return ActionP.takeError();
51 return (*ActionP)->Data;
52}
53
56 // Check the result cache.
57 OnDiskTrieRawHashMap::ConstOnDiskPtr ActionP = Cache.find(Key);
58 if (ActionP) {
59 assert(isAddrAligned(Align(8), ActionP->Data.data()));
60 return ActionP->Data;
61 }
62 if (!UnifiedCache || !UnifiedCache->UpstreamKVDB)
63 return std::nullopt;
64
65 // Try to fault in from upstream.
66 return UnifiedCache->faultInFromUpstreamKV(Key);
67}
68
70OnDiskKeyValueDB::open(StringRef Path, StringRef HashName, unsigned KeySize,
71 StringRef ValueName, size_t ValueSize,
72 UnifiedOnDiskCache *Cache,
73 std::shared_ptr<OnDiskCASLogger> Logger) {
74 if (std::error_code EC = sys::fs::create_directories(Path))
75 return createFileError(Path, EC);
76
77 SmallString<256> CachePath(Path);
79 constexpr uint64_t MB = 1024ull * 1024ull;
80 constexpr uint64_t GB = 1024ull * 1024ull * 1024ull;
81
82 uint64_t MaxFileSize = GB;
83 auto CustomSize = getOverriddenMaxMappingSize();
84 if (!CustomSize)
85 return CustomSize.takeError();
86 if (*CustomSize)
87 MaxFileSize = **CustomSize;
88
89 std::optional<OnDiskTrieRawHashMap> ActionCache;
91 CachePath,
92 "llvm.actioncache[" + HashName + "->" + ValueName + "]",
93 KeySize * 8,
94 /*DataSize=*/ValueSize, MaxFileSize, /*MinFileSize=*/MB,
95 std::move(Logger))
96 .moveInto(ActionCache))
97 return std::move(E);
98
99 return std::unique_ptr<OnDiskKeyValueDB>(
100 new OnDiskKeyValueDB(ValueSize, std::move(*ActionCache), Cache));
101}
102
104 size_t ValueSize, OnDiskGraphDB *CAS) {
105 return Cache.validate(
106 [&](FileOffset Offset,
108 auto formatError = [&](Twine Msg) {
109 return createStringError(
111 "bad cache value at 0x" +
112 utohexstr((unsigned)Offset.get(), /*LowerCase=*/true) + ": " +
113 Msg.str());
114 };
115
116 if (Record.Data.size() != ValueSize)
117 return formatError("wrong cache value size");
118 if (!isAddrAligned(Align(8), Record.Data.data()))
119 return formatError("wrong cache value alignment");
120 if (CAS) {
121 auto ID =
123 if (Error E = CAS->validateObjectID(ID))
124 return formatError(llvm::toString(std::move(E)));
125 }
126 return Error::success();
127 });
128}
129
131 if (UnifiedCache && UnifiedCache->UpstreamKVDB) {
132 assert(UnifiedCache->UpstreamGraphDB &&
133 "upstream cache and cas must be paired");
134 if (auto E = validateOnDiskKeyValueDB(UnifiedCache->UpstreamKVDB->Cache,
135 UnifiedCache->UpstreamKVDB->ValueSize,
136 UnifiedCache->UpstreamGraphDB.get()))
137 return E;
138 }
140 Cache, ValueSize,
141 UnifiedCache ? UnifiedCache->PrimaryGraphDB.get() : nullptr);
142}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:336
static constexpr StringLiteral ActionCacheFile
static Error validateOnDiskKeyValueDB(const OnDiskTrieRawHashMap &Cache, size_t ValueSize, OnDiskGraphDB *CAS)
This declares OnDiskKeyValueDB, a key value storage database of fixed size key and value.
This file declares interface for OnDiskTrieRawHashMap, a thread-safe and (mostly) lock-free hash map ...
This file contains some functions that are useful when dealing with strings.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Logging utility - given an ordered specification of features, and assuming a scalar reward,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:882
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
A cache from a key (that describes an action) to the result of performing that action.
Definition ActionCache.h:49
FileOffset is a wrapper around uint64_t to represent the offset of data from the beginning of the fil...
Definition FileOffset.h:24
OnDiskTrieRawHashMap is a persistent trie data structure used as hash maps.
static LLVM_ABI_FOR_TEST Expected< OnDiskTrieRawHashMap > create(const Twine &Path, const Twine &TrieName, size_t NumHashBits, uint64_t DataSize, uint64_t MaxFileSize, std::optional< uint64_t > NewFileInitialSize, std::shared_ptr< ondisk::OnDiskCASLogger > Logger=nullptr, std::optional< size_t > NewTableNumRootBits=std::nullopt, std::optional< size_t > NewTableNumSubtrieBits=std::nullopt)
Gets or creates a file at Path with a hash-mapped trie named TrieName.
On-disk CAS nodes database, independent of a particular hashing algorithm.
LLVM_ABI_FOR_TEST Error validateObjectID(ObjectID ID) const
Checks that ID exists in the index.
static LLVM_ABI_FOR_TEST 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_FOR_TEST Expected< ArrayRef< char > > put(ArrayRef< uint8_t > Key, ArrayRef< char > Value)
Associate a value with a key.
LLVM_ABI_FOR_TEST Expected< std::optional< ArrayRef< char > > > get(ArrayRef< uint8_t > Key)
LLVM_ABI_FOR_TEST Error validate() const
Validate the storage.
A unified CAS nodes and key-value database, using on-disk storage for both.
static LLVM_ABI_FOR_TEST ObjectID getObjectIDFromValue(ArrayRef< char > Value)
Helper function to convert the value stored in KeyValueDB and ObjectID.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
constexpr StringLiteral CASFormatVersion
The version for all the ondisk database files.
Expected< std::optional< uint64_t > > getOverriddenMaxMappingSize()
Retrieves an overridden maximum mapping size for CAS files, if any, speicified by LLVM_CAS_MAX_MAPPIN...
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.
Definition Path.cpp:974
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:457
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
StringMapEntry< Value * > ValueName
Definition Value.h:56
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition Error.h:1399
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1305
@ illegal_byte_sequence
Definition Errc.h:52
@ invalid_argument
Definition Errc.h:56
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1885
std::string itostr(int64_t X)
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
Definition Alignment.h:139
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Const value proxy to access the records stored in TrieRawHashMap.
Value proxy to access the records stored in TrieRawHashMap.