Skip to content

Commit 0207896

Browse files
committed
Use a dictionary for the cache, and doc the usage better
1 parent e6b5593 commit 0207896

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/IProjectCapabilityResolver.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ internal interface IProjectCapabilityResolver
1313
/// <summary>
1414
/// Tries to return a cached value for the capability check, if a previous call to <see cref="ResolveCapability(string, string)" /> has been made for the same project and capability.
1515
/// </summary>
16+
/// <remarks>
17+
/// This method is intended purely for performance optimization. It should not be used to determine if a capability is supported, as it may return false negatives in many circumstances.
18+
/// </remarks>
1619
bool TryGetCachedCapabilityMatch(string projectFilePath, string capability, out bool isMatch);
1720
}

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectCapabilityResolver.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5-
using System.Collections.Immutable;
5+
using System.Collections.Generic;
66
using System.ComponentModel.Composition;
77
using System.Diagnostics;
88
using System.Threading;
@@ -27,7 +27,8 @@ internal sealed class ProjectCapabilityResolver : IProjectCapabilityResolver, ID
2727
private readonly JoinableTaskFactory _jtf;
2828
private readonly CancellationTokenSource _disposeTokenSource;
2929

30-
private ImmutableDictionary<(string, string), bool> _cachedCapabilities = ImmutableDictionary<(string, string), bool>.Empty;
30+
private readonly Dictionary<(string ProjectFilePath, string Capability), bool> _cachedCapabilities = [];
31+
private readonly object _gate = new();
3132

3233
[ImportingConstructor]
3334
public ProjectCapabilityResolver(
@@ -130,7 +131,10 @@ private bool ContainingProjectHasCapability(string capability, string documentFi
130131

131132
if (vsHierarchy.GetProjectFilePath(_jtf) is { } projectFilePath)
132133
{
133-
_cachedCapabilities = _cachedCapabilities.SetItem((projectFilePath, capability), isMatch);
134+
lock (_gate)
135+
{
136+
_cachedCapabilities[(projectFilePath, capability)] = isMatch;
137+
}
134138
}
135139
}
136140
catch (NotSupportedException)
@@ -148,6 +152,9 @@ private bool ContainingProjectHasCapability(string capability, string documentFi
148152

149153
public bool TryGetCachedCapabilityMatch(string projectFilePath, string capability, out bool isMatch)
150154
{
151-
return _cachedCapabilities.TryGetValue((projectFilePath, capability), out isMatch);
155+
lock (_gate)
156+
{
157+
return _cachedCapabilities.TryGetValue((projectFilePath, capability), out isMatch);
158+
}
152159
}
153160
}

0 commit comments

Comments
 (0)