Skip to content

Commit da6d4c2

Browse files
OpenDocumentGenerator: Use HashSet<DocumentKey> for unique items
Update OpenDocumentGenerator to use a dedicated HashSet instance to compute the most recent unique items. In addition, make the following changes: - Add a DocumentSnapshot.Key property that produces a DocumentKey. - Update OpenDocumentGenerator's async batching work queue to track DocumentKeys rather than DocumentSnapshots. - Prefer faster boolean tests first, but checking _options.UpdateBuffersForCLosedDocuments before _projectManager.IsDocumentOpen(...)
1 parent 63e910b commit da6d4c2

File tree

3 files changed

+25
-58
lines changed

3 files changed

+25
-58
lines changed

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/OpenDocumentGenerator.Comparer.cs

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/OpenDocumentGenerator.cs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Collections.Immutable;
77
using System.Threading;
88
using System.Threading.Tasks;
9+
using Microsoft.AspNetCore.Razor.ProjectSystem;
910
using Microsoft.AspNetCore.Razor.Utilities;
1011
using Microsoft.CodeAnalysis.Razor.Logging;
1112
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
@@ -32,21 +33,23 @@ internal partial class OpenDocumentGenerator : IRazorStartupService, IDisposable
3233
private readonly LanguageServerFeatureOptions _options;
3334
private readonly ILogger _logger;
3435

35-
private readonly AsyncBatchingWorkQueue<DocumentSnapshot> _workQueue;
36+
private readonly AsyncBatchingWorkQueue<DocumentKey> _workQueue;
3637
private readonly CancellationTokenSource _disposeTokenSource;
38+
private readonly HashSet<DocumentKey> _workerSet;
3739

3840
public OpenDocumentGenerator(
3941
IEnumerable<IDocumentProcessedListener> listeners,
4042
ProjectSnapshotManager projectManager,
4143
LanguageServerFeatureOptions options,
4244
ILoggerFactory loggerFactory)
4345
{
44-
_listeners = listeners.ToImmutableArray();
46+
_listeners = [.. listeners];
4547
_projectManager = projectManager;
4648
_options = options;
4749

50+
_workerSet = [];
4851
_disposeTokenSource = new();
49-
_workQueue = new AsyncBatchingWorkQueue<DocumentSnapshot>(
52+
_workQueue = new AsyncBatchingWorkQueue<DocumentKey>(
5053
s_delay,
5154
ProcessBatchAsync,
5255
_disposeTokenSource.Token);
@@ -66,15 +69,22 @@ public void Dispose()
6669
_disposeTokenSource.Dispose();
6770
}
6871

69-
private async ValueTask ProcessBatchAsync(ImmutableArray<DocumentSnapshot> items, CancellationToken token)
72+
private async ValueTask ProcessBatchAsync(ImmutableArray<DocumentKey> items, CancellationToken token)
7073
{
71-
foreach (var document in items.GetMostRecentUniqueItems(Comparer.Instance))
74+
_workerSet.Clear();
75+
76+
foreach (var key in items.GetMostRecentUniqueItems(_workerSet))
7277
{
7378
if (token.IsCancellationRequested)
7479
{
7580
return;
7681
}
7782

83+
if (!_projectManager.TryGetDocument(key, out var document))
84+
{
85+
continue;
86+
}
87+
7888
var codeDocument = await document.GetGeneratedOutputAsync(token).ConfigureAwait(false);
7989

8090
foreach (var listener in _listeners)
@@ -109,7 +119,7 @@ private void ProjectManager_Changed(object? sender, ProjectChangeEventArgs args)
109119
{
110120
if (newProject.TryGetDocument(documentFilePath, out var document))
111121
{
112-
EnqueueIfNecessary(document);
122+
EnqueueIfNecessary(document.Key, document.Version);
113123
}
114124
}
115125

@@ -127,11 +137,11 @@ private void ProjectManager_Changed(object? sender, ProjectChangeEventArgs args)
127137

128138
if (newProject.TryGetDocument(documentFilePath, out var document))
129139
{
130-
EnqueueIfNecessary(document);
140+
EnqueueIfNecessary(document.Key, document.Version);
131141

132142
foreach (var relatedDocument in newProject.GetRelatedDocuments(document))
133143
{
134-
EnqueueIfNecessary(relatedDocument);
144+
EnqueueIfNecessary(relatedDocument.Key, relatedDocument.Version);
135145
}
136146
}
137147

@@ -152,7 +162,7 @@ private void ProjectManager_Changed(object? sender, ProjectChangeEventArgs args)
152162

153163
if (newProject.TryGetDocument(relatedDocumentFilePath, out var newRelatedDocument))
154164
{
155-
EnqueueIfNecessary(newRelatedDocument);
165+
EnqueueIfNecessary(newRelatedDocument.Key, newRelatedDocument.Version);
156166
}
157167
}
158168
}
@@ -167,17 +177,17 @@ private void ProjectManager_Changed(object? sender, ProjectChangeEventArgs args)
167177
}
168178
}
169179

170-
void EnqueueIfNecessary(DocumentSnapshot document)
180+
void EnqueueIfNecessary(DocumentKey documentKey, int documentVersion)
171181
{
172-
if (!_projectManager.IsDocumentOpen(document.FilePath) &&
173-
!_options.UpdateBuffersForClosedDocuments)
182+
if (!_options.UpdateBuffersForClosedDocuments &&
183+
!_projectManager.IsDocumentOpen(documentKey.FilePath))
174184
{
175185
return;
176186
}
177187

178-
_logger.LogDebug($"Enqueuing generation of {document.FilePath} in {document.Project.Key.Id} at version {document.Version}");
188+
_logger.LogDebug($"Enqueuing generation of {documentKey.FilePath} in {documentKey.ProjectKey.Id} at version {documentVersion}");
179189

180-
_workQueue.AddWork(document);
190+
_workQueue.AddWork(documentKey);
181191
}
182192
}
183193
}

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/DocumentSnapshot.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ internal sealed class DocumentSnapshot(ProjectSnapshot project, DocumentState st
1919

2020
public HostDocument HostDocument => _state.HostDocument;
2121

22+
public DocumentKey Key => new(Project.Key, FilePath);
2223
public string FileKind => _state.HostDocument.FileKind;
2324
public string FilePath => _state.HostDocument.FilePath;
2425
public string TargetPath => _state.HostDocument.TargetPath;

0 commit comments

Comments
 (0)