Skip to content

Commit 9a39394

Browse files
Implement the simple lookup optimization
1 parent 3556ead commit 9a39394

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

clang-tools-extra/clangd/index/dex/Dex.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,14 @@ void Dex::buildIndex() {
149149
InvertedIndex = std::move(Builder).build();
150150

151151
// Build RevRefs
152-
for (const auto &Pair : Refs)
153-
for (const auto &R : Pair.second)
152+
for (const auto &[ID, RefList] : Refs)
153+
for (const auto &R : RefList)
154154
if ((R.Kind & RefKind::Call) != RefKind::Unknown)
155-
RevRefs[R.Container].emplace_back(R, Pair.first);
155+
RevRefs.emplace_back(R, ID);
156+
// Sort by container ID so we can use binary search for lookup.
157+
llvm::sort(RevRefs, [](const RevRef &A, const RevRef &B) {
158+
return A.ref().Container < B.ref().Container;
159+
});
156160
}
157161

158162
std::unique_ptr<Iterator> Dex::iterator(const Token &Tok) const {
@@ -320,13 +324,28 @@ bool Dex::refs(const RefsRequest &Req,
320324
return false; // We reported all refs.
321325
}
322326

327+
llvm::iterator_range<std::vector<Dex::RevRef>::const_iterator>
328+
Dex::lookupRevRefs(const SymbolID &Container) const {
329+
// equal_range() requires an element of the same type as the elements of the
330+
// range, so construct a dummy RevRef with the container of interest.
331+
Ref QueryRef;
332+
QueryRef.Container = Container;
333+
RevRef Query(QueryRef, SymbolID{});
334+
335+
auto ItPair = std::equal_range(RevRefs.cbegin(), RevRefs.cend(), Query,
336+
[](const RevRef &A, const RevRef &B) {
337+
return A.ref().Container < B.ref().Container;
338+
});
339+
return {ItPair.first, ItPair.second};
340+
}
341+
323342
bool Dex::refersTo(
324343
const RefsRequest &Req,
325344
llvm::function_ref<void(const RefersToResult &)> Callback) const {
326345
trace::Span Tracer("Dex reversed refs");
327346
uint32_t Remaining = Req.Limit.value_or(std::numeric_limits<uint32_t>::max());
328347
for (const auto &ID : Req.IDs)
329-
for (const auto &Rev : RevRefs.lookup(ID)) {
348+
for (const auto &Rev : lookupRevRefs(ID)) {
330349
if (!static_cast<int>(Req.Filter & Rev.ref().Kind))
331350
continue;
332351
if (Remaining == 0)
@@ -373,9 +392,7 @@ size_t Dex::estimateMemoryUsage() const {
373392
for (const auto &TokenToPostingList : InvertedIndex)
374393
Bytes += TokenToPostingList.second.bytes();
375394
Bytes += Refs.getMemorySize();
376-
Bytes += RevRefs.getMemorySize();
377-
for (const auto &Entry : RevRefs)
378-
Bytes += Entry.second.size() * sizeof(Entry.second.front());
395+
Bytes += RevRefs.size() * sizeof(RevRef);
379396
Bytes += Relations.getMemorySize();
380397
return Bytes + BackingDataSize;
381398
}

clang-tools-extra/clangd/index/dex/Dex.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,21 @@ class Dex : public SymbolIndex {
100100

101101
private:
102102
class RevRef {
103-
const Ref &Reference;
103+
const Ref *Reference;
104104
SymbolID Target;
105105

106106
public:
107107
RevRef(const Ref &Reference, SymbolID Target)
108-
: Reference(Reference), Target(Target) {}
109-
const Ref &ref() const { return Reference; }
108+
: Reference(&Reference), Target(Target) {}
109+
const Ref &ref() const { return *Reference; }
110110
RefersToResult refersToResult() const {
111-
return {Reference.Location, Reference.Kind, Target};
111+
return {ref().Location, ref().Kind, Target};
112112
}
113113
};
114114

115115
void buildIndex();
116+
llvm::iterator_range<std::vector<RevRef>::const_iterator>
117+
lookupRevRefs(const SymbolID &Container) const;
116118
std::unique_ptr<Iterator> iterator(const Token &Tok) const;
117119
std::unique_ptr<Iterator>
118120
createFileProximityIterator(llvm::ArrayRef<std::string> ProximityPaths) const;
@@ -133,7 +135,7 @@ class Dex : public SymbolIndex {
133135
llvm::DenseMap<Token, PostingList> InvertedIndex;
134136
dex::Corpus Corpus;
135137
llvm::DenseMap<SymbolID, llvm::ArrayRef<Ref>> Refs;
136-
llvm::DenseMap<SymbolID, std::vector<RevRef>> RevRefs;
138+
std::vector<RevRef> RevRefs; // sorted by container ID
137139
static_assert(sizeof(RelationKind) == sizeof(uint8_t),
138140
"RelationKind should be of same size as a uint8_t");
139141
llvm::DenseMap<std::pair<SymbolID, uint8_t>, std::vector<SymbolID>> Relations;

0 commit comments

Comments
 (0)