Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use small dic
  • Loading branch information
CyrusNajmabadi committed Aug 20, 2025
commit 948a505c0a868b61f77837bb9d9fd8b0c0e095f2
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,18 @@ public int GetHashCode((Checksum checksum, ImmutableArray<DiagnosticAnalyzer> an
/// we've created for it. Note: the CompilationWithAnalyzersPair instance is dependent on the set of <see
/// cref="DiagnosticAnalyzer"/>s passed along with the project.
/// <para/>
/// The value of the table is a <see cref="ConcurrentDictionary{TKey, TValue}"/> that maps from the
/// The value of the table is a <see cref="Dictionary{TKey, TValue}"/> that maps from the
/// <see cref="Project"/> checksum the set of <see cref="DiagnosticAnalyzer"/>s being requested.
/// Note: this dictionary must be locked with <see cref="s_gate"/> before accessing it.
/// </summary>
private static readonly ConditionalWeakTable<
ProjectState,
ConcurrentDictionary<
SmallDictionary<
(Checksum checksum, ImmutableArray<DiagnosticAnalyzer> analyzers),
AsyncLazy<CompilationWithAnalyzersPair?>>> s_projectToCompilationWithAnalyzers = new();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOte: i designed it this way so that we dont' toss out a very good 'full compilation with analyzers' and replace it with a 'compilation with analyzers with a single analyzer in it'.


private static readonly SemaphoreSlim s_gate = new(initialCount: 1);

private static async Task<CompilationWithAnalyzersPair?> GetOrCreateCompilationWithAnalyzersAsync(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: i dont' like this design at all. it means on the client side we end up makign the compilatino, then create the compilationWithAnalyzersPair only to eventually call over to oop with the set of analyzers we want, where it does the same thing over ther eas well.

we should make the call to oop much higher in stack.

Project project,
ImmutableArray<DiagnosticAnalyzer> analyzers,
Expand All @@ -75,16 +78,24 @@ private static readonly ConditionalWeakTable<
// recompute and cache with the new state sets.
var map = s_projectToCompilationWithAnalyzers.GetValue(
projectState,
// We will almost always have one item in this dict
static _ => new(ChecksumAndAnalyzersEqualityComparer.Instance));

var lazy = map.GetOrAdd(
(checksum, analyzers),
checksumAndAnalyzers => AsyncLazy.Create(async cancellationToken =>
AsyncLazy<CompilationWithAnalyzersPair?>? lazy;
using (await s_gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false))
{
var checksumAndAnalyzers = (checksum, analyzers);
if (!map.TryGetValue(checksumAndAnalyzers, out lazy))
{
var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
var compilationWithAnalyzersPair = CreateCompilationWithAnalyzers(projectState, compilation);
return compilationWithAnalyzersPair;
}));
lazy = AsyncLazy.Create(async cancellationToken =>
{
var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
var compilationWithAnalyzersPair = CreateCompilationWithAnalyzers(projectState, compilation);
return compilationWithAnalyzersPair;
});
map.Add(checksumAndAnalyzers, lazy);
}
}

return await lazy.GetValueAsync(cancellationToken).ConfigureAwait(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<Compile Include="$(MSBuildThisFileDirectory)..\..\..\..\Compilers\Core\Portable\InternalUtilities\SharedStopwatch.cs" Link="InternalUtilities\SharedStopwatch.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\..\..\..\Compilers\Core\Portable\Syntax\SyntaxTreeExtensions.cs" Link="Syntax\SyntaxTreeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\..\..\..\Compilers\Core\Portable\Collections\BitVector.cs" Link="Collections\BitVector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\..\..\..\Compilers\Core\Portable\Collections\SmallDictionary.cs" Link="Collections\SmallDictionary.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\..\..\..\Compilers\Core\Portable\Collections\IOrderedReadOnlySet.cs" Link="Collections\IOrderedReadOnlySet.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\..\..\..\Compilers\Core\Portable\SourceGeneration\GeneratedCodeUtilities.cs" Link="SourceGeneration\GeneratedCodeUtilities.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\..\..\..\Compilers\Core\Portable\SourceCodeKindExtensions.cs" Link="Utilities\Compiler\SourceCodeKindExtensions.cs" />
Expand Down
Loading