56 template<
typename ReaderInfo,
typename WriterInfo>
61 using HashTable = llvm::OnDiskIterableChainedHashTable<Info>;
66 OnDiskTable(
file_type File,
unsigned NumBuckets,
unsigned NumEntries,
70 Table(NumBuckets, NumEntries, Buckets, Payload,
Base, InfoObj) {}
74 std::vector<file_type> Files;
75 llvm::DenseMap<internal_key_type, data_type>
Data;
78 using Table = llvm::PointerUnion<OnDiskTable *, MergedTable *>;
79 using TableVector = llvm::TinyPtrVector<void *>;
90 llvm::TinyPtrVector<file_type> PendingOverrides;
92 struct AsOnDiskTable {
93 using result_type = OnDiskTable *;
95 result_type operator()(
void *P)
const {
96 return llvm::cast<OnDiskTable *>(Table::getFromOpaqueValue(P));
100 using table_iterator =
101 llvm::mapped_iterator<TableVector::iterator, AsOnDiskTable>;
102 using table_range = llvm::iterator_range<table_iterator>;
105 table_range tables() {
106 unsigned DropBegin = getMergedTable() ? 1 : 0;
107 return llvm::map_range(llvm::drop_begin(Tables, DropBegin),
111 MergedTable *getMergedTable()
const {
113 return Tables.empty() ?
nullptr
114 : llvm::dyn_cast<MergedTable *>(
115 Table::getFromOpaqueValue(*Tables.begin()));
120 for (
auto *
T : tables())
122 if (
auto *M = getMergedTable())
127 void removeOverriddenTables() {
128 llvm::DenseSet<file_type> Files;
129 Files.insert_range(PendingOverrides);
131 auto ShouldRemove = [&Files](
void *
T) ->
bool {
132 auto *ODT = llvm::cast<OnDiskTable *>(Table::getFromOpaqueValue(
T));
133 bool Remove = Files.count(ODT->File);
138 Tables.erase(std::remove_if(tables().begin().getCurrent(), Tables.end(),
141 PendingOverrides.clear();
145 MergedTable *Merged = getMergedTable();
147 Merged =
new MergedTable;
151 for (
auto *ODT : tables()) {
152 auto &HT = ODT->Table;
153 Info &InfoObj = HT.getInfoObj();
155 for (
auto I = HT.data_begin(), E = HT.data_end(); I != E; ++I) {
156 auto *LocalPtr = I.getItem();
159 auto L = InfoObj.ReadKeyDataLength(LocalPtr);
162 InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second,
166 Merged->Files.push_back(ODT->File);
171 Tables.push_back(Table(Merged).getOpaqueValue());
178 : Tables(
std::move(O.Tables)),
179 PendingOverrides(
std::move(O.PendingOverrides)) {
187 Tables = std::move(O.Tables);
189 PendingOverrides = std::move(O.PendingOverrides);
197 using namespace llvm::support;
202 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
206 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
210 OverriddenFiles.reserve(NumFiles);
211 for (; NumFiles != 0; --NumFiles)
212 OverriddenFiles.push_back(InfoObj.ReadFileRef(Ptr));
213 llvm::append_range(PendingOverrides, OverriddenFiles);
217 auto NumBucketsAndEntries =
218 OnDiskTable::HashTable::readNumBucketsAndEntries(Buckets);
221 Table NewTable =
new OnDiskTable(
File, NumBucketsAndEntries.first,
222 NumBucketsAndEntries.second,
223 Buckets, Ptr,
Data, std::move(InfoObj));
224 Tables.push_back(NewTable.getOpaqueValue());
231 if (!PendingOverrides.empty())
232 removeOverriddenTables();
234 if (Tables.size() >
static_cast<unsigned>(Info::MaxTables))
238 auto KeyHash = Info::ComputeHash(Key);
240 if (MergedTable *M = getMergedTable()) {
241 auto It = M->Data.find(Key);
242 if (It != M->Data.end())
248 for (
auto *ODT : tables()) {
249 auto &HT = ODT->Table;
250 auto It = HT.find_hashed(Key, KeyHash);
252 HT.getInfoObj().ReadDataInto(Key, It.getDataPtr(), It.getDataLen(),
265 if (!PendingOverrides.empty())
266 removeOverriddenTables();
268 if (MergedTable *M = getMergedTable()) {
269 for (
auto &KV : M->Data)
270 Info::MergeDataInto(KV.second, ResultBuilder);
273 for (
auto *ODT : tables()) {
274 auto &HT = ODT->Table;
275 Info &InfoObj = HT.getInfoObj();
276 for (
auto I = HT.data_begin(), E = HT.data_end(); I != E; ++I) {
277 auto *LocalPtr = I.getItem();
280 auto L = InfoObj.ReadKeyDataLength(LocalPtr);
282 InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second, ResultBuilder);