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 : Table::getFromOpaqueValue(*Tables.begin())
114 .template dyn_cast<MergedTable*>();
119 for (
auto *
T : tables())
121 if (
auto *M = getMergedTable())
126 void removeOverriddenTables() {
127 llvm::DenseSet<file_type> Files;
128 Files.insert_range(PendingOverrides);
130 auto ShouldRemove = [&Files](
void *
T) ->
bool {
131 auto *ODT = llvm::cast<OnDiskTable *>(Table::getFromOpaqueValue(
T));
132 bool Remove = Files.count(ODT->File);
137 Tables.erase(std::remove_if(tables().begin().getCurrent(), Tables.end(),
140 PendingOverrides.clear();
144 MergedTable *Merged = getMergedTable();
146 Merged =
new MergedTable;
150 for (
auto *ODT : tables()) {
151 auto &HT = ODT->Table;
152 Info &InfoObj = HT.getInfoObj();
154 for (
auto I = HT.data_begin(), E = HT.data_end(); I != E; ++I) {
155 auto *LocalPtr = I.getItem();
158 auto L = InfoObj.ReadKeyDataLength(LocalPtr);
161 InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second,
165 Merged->Files.push_back(ODT->File);
170 Tables.push_back(Table(Merged).getOpaqueValue());
177 : Tables(
std::move(O.Tables)),
178 PendingOverrides(
std::move(O.PendingOverrides)) {
186 Tables = std::move(O.Tables);
188 PendingOverrides = std::move(O.PendingOverrides);
196 using namespace llvm::support;
200 uint32_t BucketOffset =
201 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
205 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
209 OverriddenFiles.reserve(NumFiles);
210 for (; NumFiles != 0; --NumFiles)
211 OverriddenFiles.push_back(InfoObj.ReadFileRef(Ptr));
212 llvm::append_range(PendingOverrides, OverriddenFiles);
216 auto NumBucketsAndEntries =
217 OnDiskTable::HashTable::readNumBucketsAndEntries(Buckets);
220 Table NewTable =
new OnDiskTable(
File, NumBucketsAndEntries.first,
221 NumBucketsAndEntries.second,
222 Buckets, Ptr,
Data, std::move(InfoObj));
223 Tables.push_back(NewTable.getOpaqueValue());
230 if (!PendingOverrides.empty())
231 removeOverriddenTables();
233 if (Tables.size() >
static_cast<unsigned>(Info::MaxTables))
237 auto KeyHash = Info::ComputeHash(Key);
239 if (MergedTable *M = getMergedTable()) {
240 auto It = M->Data.find(Key);
241 if (It != M->Data.end())
247 for (
auto *ODT : tables()) {
248 auto &HT = ODT->Table;
249 auto It = HT.find_hashed(Key, KeyHash);
251 HT.getInfoObj().ReadDataInto(Key, It.getDataPtr(), It.getDataLen(),
264 if (!PendingOverrides.empty())
265 removeOverriddenTables();
267 if (MergedTable *M = getMergedTable()) {
268 for (
auto &KV : M->Data)
269 Info::MergeDataInto(KV.second, ResultBuilder);
272 for (
auto *ODT : tables()) {
273 auto &HT = ODT->Table;
274 Info &InfoObj = HT.getInfoObj();
275 for (
auto I = HT.data_begin(), E = HT.data_end(); I != E; ++I) {
276 auto *LocalPtr = I.getItem();
279 auto L = InfoObj.ReadKeyDataLength(LocalPtr);
281 InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second, ResultBuilder);