@@ -149,10 +149,14 @@ void Dex::buildIndex() {
149
149
InvertedIndex = std::move (Builder).build ();
150
150
151
151
// 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 )
154
154
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
+ });
156
160
}
157
161
158
162
std::unique_ptr<Iterator> Dex::iterator (const Token &Tok) const {
@@ -320,13 +324,28 @@ bool Dex::refs(const RefsRequest &Req,
320
324
return false ; // We reported all refs.
321
325
}
322
326
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
+
323
342
bool Dex::refersTo (
324
343
const RefsRequest &Req,
325
344
llvm::function_ref<void (const RefersToResult &)> Callback) const {
326
345
trace::Span Tracer (" Dex reversed refs" );
327
346
uint32_t Remaining = Req.Limit .value_or (std::numeric_limits<uint32_t >::max ());
328
347
for (const auto &ID : Req.IDs )
329
- for (const auto &Rev : RevRefs. lookup (ID)) {
348
+ for (const auto &Rev : lookupRevRefs (ID)) {
330
349
if (!static_cast <int >(Req.Filter & Rev.ref ().Kind ))
331
350
continue ;
332
351
if (Remaining == 0 )
@@ -373,9 +392,7 @@ size_t Dex::estimateMemoryUsage() const {
373
392
for (const auto &TokenToPostingList : InvertedIndex)
374
393
Bytes += TokenToPostingList.second .bytes ();
375
394
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);
379
396
Bytes += Relations.getMemorySize ();
380
397
return Bytes + BackingDataSize;
381
398
}
0 commit comments