mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +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.
|
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
|
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
|
/// Register that a new line starts at `offset` bytes from the start of the source file
|
||||||
void newLine(uint offset)
|
void newLine(uint offset)
|
||||||
{
|
{
|
||||||
|
@ -421,8 +426,61 @@ struct BaseLoc
|
||||||
|
|
||||||
private size_t getSubstitutionIndex(uint offset) @nogc
|
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 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;
|
size_t mid = 0;
|
||||||
while (lo <= hi)
|
while (lo <= hi)
|
||||||
{
|
{
|
||||||
|
@ -430,7 +488,10 @@ struct BaseLoc
|
||||||
if (substitutions[mid].startIndex <= offset)
|
if (substitutions[mid].startIndex <= offset)
|
||||||
{
|
{
|
||||||
if (mid == substitutions.length - 1 || substitutions[mid + 1].startIndex > offset)
|
if (mid == substitutions.length - 1 || substitutions[mid + 1].startIndex > offset)
|
||||||
|
{
|
||||||
|
lastSubstIndex = mid; // Update cache
|
||||||
return mid;
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
lo = mid + 1;
|
lo = mid + 1;
|
||||||
}
|
}
|
||||||
|
@ -443,10 +504,51 @@ struct BaseLoc
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Binary search the index in `this.lines` corresponding to `offset`
|
/// 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
|
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 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;
|
size_t mid = 0;
|
||||||
while (lo <= hi)
|
while (lo <= hi)
|
||||||
{
|
{
|
||||||
|
@ -454,7 +556,10 @@ struct BaseLoc
|
||||||
if (lines[mid] <= offset)
|
if (lines[mid] <= offset)
|
||||||
{
|
{
|
||||||
if (mid == lines.length - 1 || lines[mid + 1] > offset)
|
if (mid == lines.length - 1 || lines[mid + 1] > offset)
|
||||||
|
{
|
||||||
|
lastLineIndex = mid; // Update cache
|
||||||
return mid;
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
lo = mid + 1;
|
lo = mid + 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue