CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
143 lines
5.4 KiB
C++
143 lines
5.4 KiB
C++
//===- OnDiskKeyValueDB.cpp -------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// \file
|
|
/// This file implements OnDiskKeyValueDB, an ondisk key value database.
|
|
///
|
|
/// The KeyValue database file is named `actions.<version>` inside the CAS
|
|
/// directory. The database stores a mapping between a fixed-sized key and a
|
|
/// fixed-sized value, where the size of key and value can be configured when
|
|
/// opening the database.
|
|
///
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CAS/OnDiskKeyValueDB.h"
|
|
#include "OnDiskCommon.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/CAS/OnDiskTrieRawHashMap.h"
|
|
#include "llvm/CAS/UnifiedOnDiskCache.h"
|
|
#include "llvm/Support/Alignment.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/Errc.h"
|
|
#include "llvm/Support/Path.h"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::cas;
|
|
using namespace llvm::cas::ondisk;
|
|
|
|
static constexpr StringLiteral ActionCacheFile = "actions.";
|
|
|
|
Expected<ArrayRef<char>> OnDiskKeyValueDB::put(ArrayRef<uint8_t> Key,
|
|
ArrayRef<char> Value) {
|
|
if (LLVM_UNLIKELY(Value.size() != ValueSize))
|
|
return createStringError(errc::invalid_argument,
|
|
"expected value size of " + itostr(ValueSize) +
|
|
", got: " + itostr(Value.size()));
|
|
assert(Value.size() == ValueSize);
|
|
auto ActionP = Cache.insertLazy(
|
|
Key, [&](FileOffset TentativeOffset,
|
|
OnDiskTrieRawHashMap::ValueProxy TentativeValue) {
|
|
assert(TentativeValue.Data.size() == ValueSize);
|
|
llvm::copy(Value, TentativeValue.Data.data());
|
|
});
|
|
if (LLVM_UNLIKELY(!ActionP))
|
|
return ActionP.takeError();
|
|
return (*ActionP)->Data;
|
|
}
|
|
|
|
Expected<std::optional<ArrayRef<char>>>
|
|
OnDiskKeyValueDB::get(ArrayRef<uint8_t> Key) {
|
|
// Check the result cache.
|
|
OnDiskTrieRawHashMap::ConstOnDiskPtr ActionP = Cache.find(Key);
|
|
if (ActionP) {
|
|
assert(isAddrAligned(Align(8), ActionP->Data.data()));
|
|
return ActionP->Data;
|
|
}
|
|
if (!UnifiedCache || !UnifiedCache->UpstreamKVDB)
|
|
return std::nullopt;
|
|
|
|
// Try to fault in from upstream.
|
|
return UnifiedCache->faultInFromUpstreamKV(Key);
|
|
}
|
|
|
|
Expected<std::unique_ptr<OnDiskKeyValueDB>>
|
|
OnDiskKeyValueDB::open(StringRef Path, StringRef HashName, unsigned KeySize,
|
|
StringRef ValueName, size_t ValueSize,
|
|
UnifiedOnDiskCache *Cache,
|
|
std::shared_ptr<OnDiskCASLogger> Logger) {
|
|
if (std::error_code EC = sys::fs::create_directories(Path))
|
|
return createFileError(Path, EC);
|
|
|
|
SmallString<256> CachePath(Path);
|
|
sys::path::append(CachePath, ActionCacheFile + CASFormatVersion);
|
|
constexpr uint64_t MB = 1024ull * 1024ull;
|
|
constexpr uint64_t GB = 1024ull * 1024ull * 1024ull;
|
|
|
|
uint64_t MaxFileSize = GB;
|
|
auto CustomSize = getOverriddenMaxMappingSize();
|
|
if (!CustomSize)
|
|
return CustomSize.takeError();
|
|
if (*CustomSize)
|
|
MaxFileSize = **CustomSize;
|
|
|
|
std::optional<OnDiskTrieRawHashMap> ActionCache;
|
|
if (Error E = OnDiskTrieRawHashMap::create(
|
|
CachePath,
|
|
"llvm.actioncache[" + HashName + "->" + ValueName + "]",
|
|
KeySize * 8,
|
|
/*DataSize=*/ValueSize, MaxFileSize, /*MinFileSize=*/MB,
|
|
std::move(Logger))
|
|
.moveInto(ActionCache))
|
|
return std::move(E);
|
|
|
|
return std::unique_ptr<OnDiskKeyValueDB>(
|
|
new OnDiskKeyValueDB(ValueSize, std::move(*ActionCache), Cache));
|
|
}
|
|
|
|
static Error validateOnDiskKeyValueDB(const OnDiskTrieRawHashMap &Cache,
|
|
size_t ValueSize, OnDiskGraphDB *CAS) {
|
|
return Cache.validate(
|
|
[&](FileOffset Offset,
|
|
OnDiskTrieRawHashMap::ConstValueProxy Record) -> Error {
|
|
auto formatError = [&](Twine Msg) {
|
|
return createStringError(
|
|
llvm::errc::illegal_byte_sequence,
|
|
"bad cache value at 0x" +
|
|
utohexstr((unsigned)Offset.get(), /*LowerCase=*/true) + ": " +
|
|
Msg.str());
|
|
};
|
|
|
|
if (Record.Data.size() != ValueSize)
|
|
return formatError("wrong cache value size");
|
|
if (!isAddrAligned(Align(8), Record.Data.data()))
|
|
return formatError("wrong cache value alignment");
|
|
if (CAS) {
|
|
auto ID =
|
|
ondisk::UnifiedOnDiskCache::getObjectIDFromValue(Record.Data);
|
|
if (Error E = CAS->validateObjectID(ID))
|
|
return formatError(llvm::toString(std::move(E)));
|
|
}
|
|
return Error::success();
|
|
});
|
|
}
|
|
|
|
Error OnDiskKeyValueDB::validate() const {
|
|
if (UnifiedCache && UnifiedCache->UpstreamKVDB) {
|
|
assert(UnifiedCache->UpstreamGraphDB &&
|
|
"upstream cache and cas must be paired");
|
|
if (auto E = validateOnDiskKeyValueDB(UnifiedCache->UpstreamKVDB->Cache,
|
|
UnifiedCache->UpstreamKVDB->ValueSize,
|
|
UnifiedCache->UpstreamGraphDB.get()))
|
|
return E;
|
|
}
|
|
return validateOnDiskKeyValueDB(
|
|
Cache, ValueSize,
|
|
UnifiedCache ? UnifiedCache->PrimaryGraphDB.get() : nullptr);
|
|
}
|