mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
Optimize Loc Lookups (#21088)
This commit is contained in:
parent
13b0745e33
commit
ce91ddca22
1 changed files with 107 additions and 2 deletions
|
@ -366,6 +366,11 @@ struct BaseLoc
|
|||
uint[] lines; /// For each line, the file offset at which it starts. At index 0 there's always a 0 entry.
|
||||
BaseLoc[] substitutions; /// Substitutions from #line / #file directives
|
||||
|
||||
/// Cache for the last line lookup
|
||||
private size_t lastLineIndex = 0;
|
||||
/// Cache for the last substitution lookup
|
||||
private size_t lastSubstIndex = 0;
|
||||
|
||||
/// Register that a new line starts at `offset` bytes from the start of the source file
|
||||
void newLine(uint offset)
|
||||
{
|
||||
|
@ -421,8 +426,61 @@ struct BaseLoc
|
|||
|
||||
private size_t getSubstitutionIndex(uint offset) @nogc
|
||||
{
|
||||
if (substitutions.length <= 1)
|
||||
return 0;
|
||||
|
||||
// Check if the offset falls within the current cached substitution or the next one
|
||||
if (lastSubstIndex < substitutions.length - 1)
|
||||
{
|
||||
// For the current substitution's range
|
||||
if (substitutions[lastSubstIndex].startIndex <= offset &&
|
||||
(lastSubstIndex == substitutions.length - 1 ||
|
||||
substitutions[lastSubstIndex + 1].startIndex > offset))
|
||||
return lastSubstIndex;
|
||||
|
||||
// For the next substitution's range
|
||||
if (lastSubstIndex + 1 < substitutions.length - 1 &&
|
||||
substitutions[lastSubstIndex + 1].startIndex <= offset &&
|
||||
substitutions[lastSubstIndex + 2].startIndex > offset)
|
||||
{
|
||||
lastSubstIndex++;
|
||||
return lastSubstIndex;
|
||||
}
|
||||
|
||||
// For the previous substitution's range
|
||||
if (lastSubstIndex > 0 &&
|
||||
substitutions[lastSubstIndex - 1].startIndex <= offset &&
|
||||
substitutions[lastSubstIndex].startIndex > offset)
|
||||
{
|
||||
lastSubstIndex--;
|
||||
return lastSubstIndex;
|
||||
}
|
||||
}
|
||||
else if (lastSubstIndex == substitutions.length - 1 &&
|
||||
substitutions[lastSubstIndex].startIndex <= offset)
|
||||
{
|
||||
// Last substitution case
|
||||
return lastSubstIndex;
|
||||
}
|
||||
|
||||
// Fall back to binary search, but start near
|
||||
size_t lo = 0;
|
||||
size_t hi = substitutions.length + -1;
|
||||
size_t hi = substitutions.length - 1;
|
||||
|
||||
// Adjust the range based on the offset relative to lastSubstIndex
|
||||
if (offset < substitutions[lastSubstIndex].startIndex)
|
||||
{
|
||||
// Search backward
|
||||
lo = 0;
|
||||
hi = lastSubstIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search forward
|
||||
lo = lastSubstIndex;
|
||||
hi = substitutions.length - 1;
|
||||
}
|
||||
|
||||
size_t mid = 0;
|
||||
while (lo <= hi)
|
||||
{
|
||||
|
@ -430,7 +488,10 @@ struct BaseLoc
|
|||
if (substitutions[mid].startIndex <= offset)
|
||||
{
|
||||
if (mid == substitutions.length - 1 || substitutions[mid + 1].startIndex > offset)
|
||||
{
|
||||
lastSubstIndex = mid; // Update cache
|
||||
return mid;
|
||||
}
|
||||
|
||||
lo = mid + 1;
|
||||
}
|
||||
|
@ -443,10 +504,51 @@ struct BaseLoc
|
|||
}
|
||||
|
||||
/// Binary search the index in `this.lines` corresponding to `offset`
|
||||
/// lastLineIndex cache to avoid full binary search when possible
|
||||
private size_t getLineIndex(uint offset) @nogc
|
||||
{
|
||||
if (lines.length <= 1)
|
||||
return 0;
|
||||
|
||||
if (lastLineIndex < lines.length - 1)
|
||||
{
|
||||
if (lines[lastLineIndex] <= offset && offset < lines[lastLineIndex + 1])
|
||||
return lastLineIndex;
|
||||
|
||||
if (lastLineIndex + 1 < lines.length - 1 &&
|
||||
lines[lastLineIndex + 1] <= offset && offset < lines[lastLineIndex + 2])
|
||||
{
|
||||
lastLineIndex++;
|
||||
return lastLineIndex;
|
||||
}
|
||||
|
||||
if (lastLineIndex > 0 &&
|
||||
lines[lastLineIndex - 1] <= offset && offset < lines[lastLineIndex])
|
||||
{
|
||||
lastLineIndex--;
|
||||
return lastLineIndex;
|
||||
}
|
||||
}
|
||||
else if (lastLineIndex == lines.length - 1 && lines[lastLineIndex] <= offset)
|
||||
{
|
||||
return lastLineIndex;
|
||||
}
|
||||
|
||||
// Fall back to binary search
|
||||
size_t lo = 0;
|
||||
size_t hi = lines.length + -1;
|
||||
size_t hi = lines.length - 1;
|
||||
|
||||
if (offset < lines[lastLineIndex])
|
||||
{
|
||||
lo = 0;
|
||||
hi = lastLineIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
lo = lastLineIndex;
|
||||
hi = lines.length - 1;
|
||||
}
|
||||
|
||||
size_t mid = 0;
|
||||
while (lo <= hi)
|
||||
{
|
||||
|
@ -454,7 +556,10 @@ struct BaseLoc
|
|||
if (lines[mid] <= offset)
|
||||
{
|
||||
if (mid == lines.length - 1 || lines[mid + 1] > offset)
|
||||
{
|
||||
lastLineIndex = mid; // Update cache
|
||||
return mid;
|
||||
}
|
||||
|
||||
lo = mid + 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue