Skip to content

Commit cd13077

Browse files
Add indexed include definition navigation
1 parent b01a982 commit cd13077

15 files changed

Lines changed: 519 additions & 5 deletions

File tree

src/index/merged_index.cpp

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,28 @@ struct DenseMapInfo<clice::index::Occurrence> {
3838
}
3939
};
4040

41+
template <>
42+
struct DenseMapInfo<clice::index::IncludeDefinition> {
43+
using R = clice::LocalSourceRange;
44+
using V = clice::index::IncludeDefinition;
45+
46+
inline static V getEmptyKey() {
47+
return V(R(-1, 0), 0);
48+
}
49+
50+
inline static V getTombstoneKey() {
51+
return V(R(-2, 0), 0);
52+
}
53+
54+
static auto getHashValue(const V& v) {
55+
return dense_hash(v.range.begin, v.range.end, v.target_path);
56+
}
57+
58+
static bool isEqual(const V& lhs, const V& rhs) {
59+
return lhs.range == rhs.range && lhs.target_path == rhs.target_path;
60+
}
61+
};
62+
4163
template <>
4264
struct DenseMapInfo<clice::index::Relation> {
4365
using R = clice::index::Relation;
@@ -134,12 +156,18 @@ struct MergedIndex::Impl {
134156
/// All merged symbol occurrences.
135157
llvm::DenseMap<Occurrence, roaring::Roaring> occurrences;
136158

159+
/// All merged include definitions.
160+
llvm::DenseMap<IncludeDefinition, roaring::Roaring> include_definitions;
161+
137162
/// All merged symbol relations.
138163
llvm::DenseMap<SymbolHash, llvm::DenseMap<Relation, roaring::Roaring>> relations;
139164

140165
/// Sorted occurrences cache for fast lookup.
141166
std::vector<Occurrence> occurrences_cache;
142167

168+
/// Sorted include definitions cache for fast lookup.
169+
std::vector<IncludeDefinition> include_definitions_cache;
170+
143171
void merge(this Impl& self, std::uint32_t path_id, FileIndex& index, auto&& add_context) {
144172
auto hash = index.hash();
145173
auto hash_key = llvm::StringRef(reinterpret_cast<char*>(hash.data()), hash.size());
@@ -158,6 +186,10 @@ struct MergedIndex::Impl {
158186
self.occurrences[occurrence].add(canonical_id);
159187
}
160188

189+
for(auto& include: index.include_definitions) {
190+
self.include_definitions[include].add(canonical_id);
191+
}
192+
161193
for(auto& [symbol_id, relations]: index.relations) {
162194
auto& target = self.relations[symbol_id];
163195
for(auto& relation: relations) {
@@ -245,6 +277,14 @@ void MergedIndex::load_in_memory(this Self& self) {
245277
read_bitmap(entry->context()));
246278
}
247279

280+
if(root->include_definitions()) {
281+
for(auto entry: *root->include_definitions()) {
282+
index.include_definitions.try_emplace(
283+
*safe_cast<IncludeDefinition>(entry->include_definition()),
284+
read_bitmap(entry->context()));
285+
}
286+
}
287+
248288
for(auto entry: *root->relations()) {
249289
auto& relations = index.relations[entry->symbol()];
250290
for(auto relation_entry: *entry->relations()) {
@@ -329,6 +369,27 @@ void MergedIndex::serialize(this const Self& self, llvm::raw_ostream& out) {
329369
std::tuple(ro.range.begin, ro.range.end, ro.target);
330370
});
331371

372+
llvm::SmallVector<const IncludeDefinition*> include_definition_keys;
373+
include_definition_keys.reserve(index->include_definitions.size());
374+
auto include_definitions = transform(index->include_definitions, [&](auto&& value) {
375+
auto&& [include, bitmap] = value;
376+
buffer.clear();
377+
buffer.resize_for_overwrite(bitmap.getSizeInBytes(false));
378+
bitmap.write(buffer.data(), false);
379+
include_definition_keys.emplace_back(&include);
380+
return binary::CreateIncludeDefinitionEntry(
381+
builder,
382+
safe_cast<binary::IncludeDefinition>(&include),
383+
CreateVector(builder, buffer));
384+
});
385+
std::ranges::sort(std::views::zip(include_definition_keys, include_definitions),
386+
[](auto lhs, auto rhs) {
387+
const auto& lo = *std::get<0>(lhs);
388+
const auto& ro = *std::get<0>(rhs);
389+
return std::tuple(lo.range.begin, lo.range.end, lo.target_path) <
390+
std::tuple(ro.range.begin, ro.range.end, ro.target_path);
391+
});
392+
332393
llvm::SmallVector<std::uint64_t> relation_keys;
333394
relation_keys.reserve(index->relations.size());
334395
auto relations = transform(index->relations, [&](auto&& value) {
@@ -369,7 +430,8 @@ void MergedIndex::serialize(this const Self& self, llvm::raw_ostream& out) {
369430
CreateVector(builder, occurrences),
370431
CreateVector(builder, relations),
371432
removed,
372-
content_offset);
433+
content_offset,
434+
CreateVector(builder, include_definitions));
373435
builder.Finish(merged_index);
374436

375437
out.write(safe_cast<char>(builder.GetBufferPointer()), builder.GetSize());
@@ -443,6 +505,81 @@ void MergedIndex::lookup(this const Self& self,
443505
}
444506
}
445507

508+
void MergedIndex::lookup_include_definition(
509+
this const Self& self,
510+
std::uint32_t offset,
511+
llvm::function_ref<bool(const IncludeDefinition&)> callback) {
512+
if(self.impl) {
513+
auto& index = *self.impl;
514+
auto& includes = index.include_definitions_cache;
515+
if(includes.empty()) {
516+
for(auto& [include, _]: index.include_definitions) {
517+
includes.emplace_back(include);
518+
}
519+
std::ranges::sort(includes,
520+
[](const IncludeDefinition& lhs, const IncludeDefinition& rhs) {
521+
return std::tuple(lhs.range.begin,
522+
lhs.range.end,
523+
lhs.target_path) < std::tuple(rhs.range.begin,
524+
rhs.range.end,
525+
rhs.target_path);
526+
});
527+
}
528+
529+
auto it = std::ranges::lower_bound(includes, offset, {}, [](const IncludeDefinition& i) {
530+
return i.range.end;
531+
});
532+
533+
while(it != includes.end()) {
534+
if(it->range.contains(offset)) {
535+
if(!index.removed.isEmpty()) {
536+
auto bitmap_it = index.include_definitions.find(*it);
537+
if(bitmap_it != index.include_definitions.end()) {
538+
auto remaining = bitmap_it->second - index.removed;
539+
if(remaining.isEmpty()) {
540+
it++;
541+
continue;
542+
}
543+
}
544+
}
545+
546+
if(!callback(*it)) {
547+
break;
548+
}
549+
550+
it++;
551+
continue;
552+
}
553+
554+
break;
555+
}
556+
} else if(self.buffer) {
557+
auto index = fbs::GetRoot<binary::MergedIndex>(self.buffer->getBufferStart());
558+
auto include_definitions = index->include_definitions();
559+
if(!include_definitions) {
560+
return;
561+
}
562+
563+
auto it = std::ranges::lower_bound(*include_definitions, offset, {}, [](auto i) {
564+
return i->include_definition()->range().end();
565+
});
566+
567+
while(it != include_definitions->end()) {
568+
auto include = safe_cast<IncludeDefinition>((*it)->include_definition());
569+
if(include->range.contains(offset)) {
570+
if(!callback(*include)) {
571+
break;
572+
}
573+
574+
it++;
575+
continue;
576+
}
577+
578+
break;
579+
}
580+
}
581+
}
582+
446583
void MergedIndex::lookup(this const Self& self,
447584
SymbolHash symbol,
448585
RelationKind kind,
@@ -577,6 +714,7 @@ void MergedIndex::remove(this Self& self, std::uint32_t path_id) {
577714

578715
// Invalidate cached occurrences.
579716
index.occurrences_cache.clear();
717+
index.include_definitions_cache.clear();
580718
}
581719

582720
void MergedIndex::merge(this Self& self,
@@ -594,6 +732,7 @@ void MergedIndex::merge(this Self& self,
594732
context.include_locations = std::move(include_locations);
595733
});
596734
self.impl->occurrences_cache.clear();
735+
self.impl->include_definitions_cache.clear();
597736
}
598737

599738
void MergedIndex::merge(this Self& self,
@@ -610,6 +749,7 @@ void MergedIndex::merge(this Self& self,
610749
context.includes.emplace_back(include_id, canonical_id);
611750
});
612751
self.impl->occurrences_cache.clear();
752+
self.impl->include_definitions_cache.clear();
613753
}
614754

615755
llvm::StringRef MergedIndex::content(this const Self& self) {

src/index/merged_index.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ class MergedIndex {
4848
std::uint32_t offset,
4949
llvm::function_ref<bool(const Occurrence&)> callback);
5050

51+
/// Lookup the include definition at the corresponding offset.
52+
void lookup_include_definition(
53+
this const Self& self,
54+
std::uint32_t offset,
55+
llvm::function_ref<bool(const IncludeDefinition&)> callback);
56+
5157
/// Lookup the relations of given symbol.
5258
void lookup(this const Self& self,
5359
SymbolHash symbol,

src/index/schema.fbs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ struct Occurrence {
1010
target : ulong;
1111
}
1212

13+
struct IncludeDefinition {
14+
range : Range;
15+
target_path : uint;
16+
}
17+
1318
struct Relation {
1419
kind : uint;
1520
padding : uint;
@@ -64,6 +69,13 @@ context:
6469
[ubyte];
6570
}
6671

72+
table IncludeDefinitionEntry {
73+
include_definition:
74+
IncludeDefinition;
75+
context:
76+
[ubyte];
77+
}
78+
6779
table RelationEntry {
6880
relation:
6981
Relation;
@@ -118,6 +130,9 @@ removed:
118130

119131
content:
120132
string;
133+
134+
include_definitions:
135+
[IncludeDefinitionEntry];
121136
}
122137

123138
table TUFileRelationsEntry {
@@ -134,6 +149,8 @@ occurrences:
134149
[Occurrence];
135150
relations:
136151
[TUFileRelationsEntry];
152+
include_definitions:
153+
[IncludeDefinition];
137154
}
138155

139156
table TUIndex {

0 commit comments

Comments
 (0)