LLVM 22.0.0git
DatabaseFile.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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 This file implements the common abstractions for CAS database file.
10///
11//===----------------------------------------------------------------------===//
12
13#include "DatabaseFile.h"
14
15using namespace llvm;
16using namespace llvm::cas;
17using namespace llvm::cas::ondisk;
18
20 StringRef TableName, const Twine &Msg) {
22 Path + "[" + TableName + "]: " + Msg);
23}
24
25Error ondisk::checkTable(StringRef Label, size_t Expected, size_t Observed,
26 StringRef Path, StringRef TrieName) {
27 if (Expected == Observed)
28 return Error::success();
29 return createTableConfigError(std::errc::invalid_argument, Path, TrieName,
30 "mismatched " + Label +
31 " (expected: " + Twine(Expected) +
32 ", observed: " + Twine(Observed) + ")");
33}
34
36DatabaseFile::create(const Twine &Path, uint64_t Capacity,
37 function_ref<Error(DatabaseFile &)> NewDBConstructor) {
38 // Constructor for if the file doesn't exist.
39 auto NewFileConstructor = [&](MappedFileRegionArena &Alloc) -> Error {
40 if (Alloc.capacity() <
41 sizeof(Header) + sizeof(MappedFileRegionArena::Header))
42 return createTableConfigError(std::errc::argument_out_of_domain,
43 Path.str(), "datafile",
44 "Allocator too small for header");
45 (void)new (Alloc.data()) Header{getMagic(), getVersion(), {0}};
46 DatabaseFile DB(Alloc);
47 return NewDBConstructor(DB);
48 };
49
50 // Get or create the file.
52 if (Error E = MappedFileRegionArena::create(Path, Capacity, sizeof(Header),
53 NewFileConstructor)
54 .moveInto(Alloc))
55 return std::move(E);
56
57 return DatabaseFile::get(
58 std::make_unique<MappedFileRegionArena>(std::move(Alloc)));
59}
60
62 assert(Table);
63 assert(&Table.getRegion() == &getRegion());
64 int64_t ExistingRootOffset = 0;
65 const int64_t NewOffset =
66 reinterpret_cast<const char *>(&Table.getHeader()) - getRegion().data();
67 if (H->RootTableOffset.compare_exchange_strong(ExistingRootOffset, NewOffset))
68 return Error::success();
69
70 // Silently ignore attempts to set the root to itself.
71 if (ExistingRootOffset == NewOffset)
72 return Error::success();
73
74 // Return an proper error message.
75 TableHandle Root(getRegion(), ExistingRootOffset);
76 if (Root.getName() == Table.getName())
77 return createStringError(
78 make_error_code(std::errc::not_supported),
79 "collision with existing table of the same name '" + Table.getName() +
80 "'");
81
82 return createStringError(make_error_code(std::errc::not_supported),
83 "cannot add new table '" + Table.getName() +
84 "'"
85 " to existing root '" +
86 Root.getName() + "'");
87}
88
89std::optional<TableHandle> DatabaseFile::findTable(StringRef Name) {
90 int64_t RootTableOffset = H->RootTableOffset.load();
91 if (!RootTableOffset)
92 return std::nullopt;
93
94 TableHandle Root(getRegion(), RootTableOffset);
95 if (Root.getName() == Name)
96 return Root;
97
98 return std::nullopt;
99}
100
101Error DatabaseFile::validate(MappedFileRegion &Region) {
102 if (Region.size() < sizeof(Header))
103 return createStringError(std::errc::invalid_argument,
104 "database: missing header");
105
106 // Check the magic and version.
107 auto *H = reinterpret_cast<Header *>(Region.data());
108 if (H->Magic != getMagic())
109 return createStringError(std::errc::invalid_argument,
110 "database: bad magic");
111 if (H->Version != getVersion())
112 return createStringError(std::errc::invalid_argument,
113 "database: wrong version");
114
115 auto *MFH = reinterpret_cast<MappedFileRegionArena::Header *>(Region.data() +
116 sizeof(Header));
117 // Check the bump-ptr, which should point past the header.
118 if (MFH->BumpPtr.load() < (int64_t)sizeof(Header))
119 return createStringError(std::errc::invalid_argument,
120 "database: corrupt bump-ptr");
121
122 return Error::success();
123}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares the common interface for a DatabaseFile that is used to implement OnDiskCAS.
#define H(x, y, z)
Definition MD5.cpp:57
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
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
Allocator for an owned mapped file region that supports thread-safe and process-safe bump pointer all...
static Expected< MappedFileRegionArena > create(const Twine &Path, uint64_t Capacity, uint64_t HeaderOffset, function_ref< Error(MappedFileRegionArena &)> NewFileConstructor)
Create a MappedFileRegionArena.
static Expected< DatabaseFile > create(const Twine &Path, uint64_t Capacity, function_ref< Error(DatabaseFile &)> NewDBConstructor)
Create the DatabaseFile at Path with Capacity.
std::optional< TableHandle > findTable(StringRef Name)
Find a table. May return null.
static constexpr uint32_t getVersion()
static constexpr uint32_t getMagic()
MappedFileRegion & getRegion()
Error addTable(TableHandle Table)
Add a table.
Generic handle for a table.
const Header & getHeader() const
MappedFileRegion & getRegion() const
An efficient, type-erasing, non-owning reference to a callable.
LLVM_ABI char * data() const
Definition Path.cpp:1164
Error createTableConfigError(std::errc ErrC, StringRef Path, StringRef TableName, const Twine &Msg)
MappedFileRegionArena::RegionT MappedFileRegion
Error checkTable(StringRef Label, size_t Expected, size_t Observed, StringRef Path, StringRef TrieName)
This is an optimization pass for GlobalISel generic memory operations.
std::error_code make_error_code(BitcodeError E)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1305
Header for MappedFileRegionArena.