From 13db77db0ebb1c8fa64cb9957dc92e6d3695b522 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 9 Oct 2023 13:47:52 -0700 Subject: [PATCH 01/12] Don't add/sync these checksums --- .../Workspace/Solution/ChecksumCollection.cs | 1 - .../Workspace/Solution/StateChecksums.cs | 74 +++++++++---------- 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/ChecksumCollection.cs b/src/Workspaces/Core/Portable/Workspace/Solution/ChecksumCollection.cs index 6a9f618673160..e556e26603a73 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/ChecksumCollection.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/ChecksumCollection.cs @@ -39,7 +39,6 @@ IEnumerator IEnumerable.GetEnumerator() public void AddAllTo(HashSet checksums) { - checksums.AddIfNotNullChecksum(this.Checksum); foreach (var checksum in this) checksums.AddIfNotNullChecksum(checksum); } diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs b/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs index a94175f485250..08297be164dbd 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs @@ -98,15 +98,15 @@ public async Task FindAsync( result[FrozenSourceGeneratedDocumentText] = await SerializableSourceText.FromTextDocumentStateAsync(state.FrozenSourceGeneratedDocumentState, cancellationToken).ConfigureAwait(false); } - if (searchingChecksumsLeft.Remove(Projects.Checksum)) - { - result[Projects.Checksum] = Projects; - } + //if (searchingChecksumsLeft.Remove(Projects.Checksum)) + //{ + // result[Projects.Checksum] = Projects; + //} - if (searchingChecksumsLeft.Remove(AnalyzerReferences.Checksum)) - { - result[AnalyzerReferences.Checksum] = AnalyzerReferences; - } + //if (searchingChecksumsLeft.Remove(AnalyzerReferences.Checksum)) + //{ + // result[AnalyzerReferences.Checksum] = AnalyzerReferences; + //} foreach (var (_, projectState) in state.ProjectStates) { @@ -242,35 +242,35 @@ public async Task FindAsync( result[ParseOptions] = state.ParseOptions; } - if (searchingChecksumsLeft.Remove(Documents.Checksum)) - { - result[Documents.Checksum] = Documents; - } - - if (searchingChecksumsLeft.Remove(ProjectReferences.Checksum)) - { - result[ProjectReferences.Checksum] = ProjectReferences; - } - - if (searchingChecksumsLeft.Remove(MetadataReferences.Checksum)) - { - result[MetadataReferences.Checksum] = MetadataReferences; - } - - if (searchingChecksumsLeft.Remove(AnalyzerReferences.Checksum)) - { - result[AnalyzerReferences.Checksum] = AnalyzerReferences; - } - - if (searchingChecksumsLeft.Remove(AdditionalDocuments.Checksum)) - { - result[AdditionalDocuments.Checksum] = AdditionalDocuments; - } - - if (searchingChecksumsLeft.Remove(AnalyzerConfigDocuments.Checksum)) - { - result[AnalyzerConfigDocuments.Checksum] = AnalyzerConfigDocuments; - } + //if (searchingChecksumsLeft.Remove(Documents.Checksum)) + //{ + // result[Documents.Checksum] = Documents; + //} + + //if (searchingChecksumsLeft.Remove(ProjectReferences.Checksum)) + //{ + // result[ProjectReferences.Checksum] = ProjectReferences; + //} + + //if (searchingChecksumsLeft.Remove(MetadataReferences.Checksum)) + //{ + // result[MetadataReferences.Checksum] = MetadataReferences; + //} + + //if (searchingChecksumsLeft.Remove(AnalyzerReferences.Checksum)) + //{ + // result[AnalyzerReferences.Checksum] = AnalyzerReferences; + //} + + //if (searchingChecksumsLeft.Remove(AdditionalDocuments.Checksum)) + //{ + // result[AdditionalDocuments.Checksum] = AdditionalDocuments; + //} + + //if (searchingChecksumsLeft.Remove(AnalyzerConfigDocuments.Checksum)) + //{ + // result[AnalyzerConfigDocuments.Checksum] = AnalyzerConfigDocuments; + //} ChecksumCollection.Find(state.ProjectReferences, ProjectReferences, searchingChecksumsLeft, result, cancellationToken); ChecksumCollection.Find(state.MetadataReferences, MetadataReferences, searchingChecksumsLeft, result, cancellationToken); From 4f2f0726b28e47df4f26831d68c65dc9d91aec40 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 9 Oct 2023 13:58:27 -0700 Subject: [PATCH 02/12] Fixup tests --- .../Remote/SnapshotSerializationTests.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/VisualStudio/Core/Test.Next/Remote/SnapshotSerializationTests.cs b/src/VisualStudio/Core/Test.Next/Remote/SnapshotSerializationTests.cs index accb89f504834..7ee05de74107d 100644 --- a/src/VisualStudio/Core/Test.Next/Remote/SnapshotSerializationTests.cs +++ b/src/VisualStudio/Core/Test.Next/Remote/SnapshotSerializationTests.cs @@ -90,9 +90,6 @@ public async Task CreateSolutionSnapshotId_Empty() var solutionObject = await validator.GetValueAsync(checksum).ConfigureAwait(false); await validator.VerifyChecksumInServiceAsync(solutionObject.Attributes, WellKnownSynchronizationKind.SolutionAttributes).ConfigureAwait(false); - var projectsSyncObject = await scope.GetTestAccessor().GetAssetAsync(solutionObject.Projects.Checksum, CancellationToken.None).ConfigureAwait(false); - await validator.VerifySynchronizationObjectInServiceAsync(projectsSyncObject).ConfigureAwait(false); - Assert.Equal(0, solutionObject.Projects.Count); } @@ -126,11 +123,7 @@ public async Task CreateSolutionSnapshotId_Project() await validator.VerifyChecksumInServiceAsync(solutionObject.Attributes, WellKnownSynchronizationKind.SolutionAttributes); - var projectSyncObject = await scope.GetTestAccessor().GetAssetAsync(solutionObject.Projects.Checksum, CancellationToken.None).ConfigureAwait(false); - await validator.VerifySynchronizationObjectInServiceAsync(projectSyncObject).ConfigureAwait(false); - Assert.Equal(1, solutionObject.Projects.Count); - await validator.VerifySnapshotInServiceAsync(validator.ToProjectObjects(solutionObject.Projects)[0], 0, 0, 0, 0, 0).ConfigureAwait(false); } [Fact] @@ -161,10 +154,6 @@ public async Task CreateSolutionSnapshotId() await validator.VerifySynchronizationObjectInServiceAsync(syncObject).ConfigureAwait(false); await validator.VerifyChecksumInServiceAsync(solutionObject.Attributes, WellKnownSynchronizationKind.SolutionAttributes).ConfigureAwait(false); - await validator.VerifyChecksumInServiceAsync(solutionObject.Projects.Checksum, WellKnownSynchronizationKind.ChecksumCollection).ConfigureAwait(false); - - Assert.Equal(1, solutionObject.Projects.Count); - await validator.VerifySnapshotInServiceAsync(validator.ToProjectObjects(solutionObject.Projects)[0], 1, 0, 0, 0, 0).ConfigureAwait(false); } [Fact] @@ -199,13 +188,8 @@ public async Task CreateSolutionSnapshotId_Full() await validator.VerifySynchronizationObjectInServiceAsync(syncObject).ConfigureAwait(false); await validator.VerifyChecksumInServiceAsync(solutionObject.Attributes, WellKnownSynchronizationKind.SolutionAttributes).ConfigureAwait(false); - await validator.VerifyChecksumInServiceAsync(solutionObject.Projects.Checksum, WellKnownSynchronizationKind.ChecksumCollection).ConfigureAwait(false); Assert.Equal(2, solutionObject.Projects.Count); - - var projects = validator.ToProjectObjects(solutionObject.Projects); - await validator.VerifySnapshotInServiceAsync(projects.Where(p => p.Checksum == firstProjectChecksum).First(), 1, 1, 1, 1, 1).ConfigureAwait(false); - await validator.VerifySnapshotInServiceAsync(projects.Where(p => p.Checksum == secondProjectChecksum).First(), 1, 0, 0, 0, 0).ConfigureAwait(false); } [Fact] From 336cb0837ca01840fbf99b6b0d671b18f5dac675 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 9 Oct 2023 14:19:56 -0700 Subject: [PATCH 03/12] Add contract call --- src/Workspaces/Remote/Core/SolutionAsset.cs | 2 +- src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Workspaces/Remote/Core/SolutionAsset.cs b/src/Workspaces/Remote/Core/SolutionAsset.cs index 1d77b868d5d2b..7e9cd8ec1a7ad 100644 --- a/src/Workspaces/Remote/Core/SolutionAsset.cs +++ b/src/Workspaces/Remote/Core/SolutionAsset.cs @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.Remote /// /// Represents a part of solution snapshot along with its checksum. /// - internal readonly struct SolutionAsset + internal sealed class SolutionAsset { public static readonly SolutionAsset Null = new(value: null, Checksum.Null, WellKnownSynchronizationKind.Null); diff --git a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs index e4f975a470aad..44b08dcdaf913 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs @@ -82,6 +82,7 @@ private async Task FindAssetsAsync(HashSet remainingChecksumsToFind, D using var resultPool = Creator.CreateResultSet(); await FindAssetsAsync(remainingChecksumsToFind, resultPool.Object, cancellationToken).ConfigureAwait(false); + Contract.ThrowIfTrue(remainingChecksumsToFind.Count > 0); foreach (var (checksum, value) in resultPool.Object) { From 3a0ef4c215ebaeb5853b60ec4080cbb4d6e4bc81 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 9 Oct 2023 14:20:54 -0700 Subject: [PATCH 04/12] Add contract call --- src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs index 44b08dcdaf913..ab00f822509e5 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs @@ -67,9 +67,7 @@ public async Task AddAssetsAsync( await FindAssetsAsync(checksumsToFind.Object, assetMap, cancellationToken).ConfigureAwait(false); Contract.ThrowIfTrue(assetMap.Count != numberOfChecksumsToSearch); - - // no checksum left to find - Debug.Assert(checksumsToFind.Object.Count == 0); + Contract.ThrowIfTrue(checksumsToFind.Object.Count > 0); } /// From fc8c491536a4213325222f39381961cebdfa3675 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 9 Oct 2023 14:30:20 -0700 Subject: [PATCH 05/12] inline --- .../Core/Portable/Serialization/PooledList.cs | 2 +- .../Remote/Core/SolutionAssetStorage.Scope.cs | 27 +++++-------------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/src/Workspaces/Core/Portable/Serialization/PooledList.cs b/src/Workspaces/Core/Portable/Serialization/PooledList.cs index e9f5e8424be82..fd00a457849b6 100644 --- a/src/Workspaces/Core/Portable/Serialization/PooledList.cs +++ b/src/Workspaces/Core/Portable/Serialization/PooledList.cs @@ -36,7 +36,7 @@ public static PooledObject> CreateChecksumSet(Checksum checksu public static PooledObject> CreateList() => SharedPools.Default>().GetPooledObject(); - public static PooledObject> CreateResultSet() + public static PooledObject> CreateResultMap() => SharedPools.Default>().GetPooledObject(); } } diff --git a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs index ab00f822509e5..27e09e4476daf 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs @@ -59,33 +59,20 @@ public async Task AddAssetsAsync( cancellationToken.ThrowIfCancellationRequested(); using var checksumsToFind = Creator.CreateChecksumSet(checksums); + using var resultMap = Creator.CreateResultMap(); var numberOfChecksumsToSearch = checksumsToFind.Object.Count; if (checksumsToFind.Object.Remove(Checksum.Null)) assetMap[Checksum.Null] = SolutionAsset.Null; - await FindAssetsAsync(checksumsToFind.Object, assetMap, cancellationToken).ConfigureAwait(false); - Contract.ThrowIfTrue(assetMap.Count != numberOfChecksumsToSearch); - Contract.ThrowIfTrue(checksumsToFind.Object.Count > 0); - } + await FindAssetsAsync(checksumsToFind.Object, resultMap.Object, cancellationToken).ConfigureAwait(false); - /// - /// Find an assets of the specified within . Once an asset of given checksum is found the corresponding asset is placed to - /// and the checksum is removed from . - /// - private async Task FindAssetsAsync(HashSet remainingChecksumsToFind, Dictionary result, CancellationToken cancellationToken) - { - using var resultPool = Creator.CreateResultSet(); + foreach (var (checksum, value) in resultMap.Object) + assetMap[checksum] = new SolutionAsset(checksum, value); - await FindAssetsAsync(remainingChecksumsToFind, resultPool.Object, cancellationToken).ConfigureAwait(false); - Contract.ThrowIfTrue(remainingChecksumsToFind.Count > 0); - - foreach (var (checksum, value) in resultPool.Object) - { - result[checksum] = new SolutionAsset(checksum, value); - } + Contract.ThrowIfTrue(checksumsToFind.Object.Count > 0); + Contract.ThrowIfTrue(assetMap.Count != numberOfChecksumsToSearch); } private async Task FindAssetsAsync(HashSet remainingChecksumsToFind, Dictionary result, CancellationToken cancellationToken) @@ -122,7 +109,7 @@ public async ValueTask GetAssetAsync(Checksum checksum, Cancellat } using var checksumPool = Creator.CreateChecksumSet(checksum); - using var resultPool = Creator.CreateResultSet(); + using var resultPool = Creator.CreateResultMap(); await scope.FindAssetsAsync(checksumPool.Object, resultPool.Object, cancellationToken).ConfigureAwait(false); Contract.ThrowIfTrue(resultPool.Object.Count != 1); From ca02e59bbe36459185d3327c07e2fd334f4682b9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 9 Oct 2023 14:49:24 -0700 Subject: [PATCH 06/12] move solution asset --- .../Remote/SerializationValidator.cs | 13 +++++++++--- .../Remote/SnapshotSerializationTests.cs | 15 ++++++++++---- .../Core/Test.Next/Remote}/SolutionAsset.cs | 0 .../Core/RemoteHostAssetSerialization.cs | 13 ++++++------ .../Remote/Core/SolutionAssetProvider.cs | 6 +++--- .../Remote/Core/SolutionAssetStorage.Scope.cs | 20 ++++++------------- .../Remote/Core/SolutionAssetStorage.cs | 2 +- 7 files changed, 38 insertions(+), 31 deletions(-) rename src/{Workspaces/Remote/Core => VisualStudio/Core/Test.Next/Remote}/SolutionAsset.cs (100%) diff --git a/src/VisualStudio/Core/Test.Next/Remote/SerializationValidator.cs b/src/VisualStudio/Core/Test.Next/Remote/SerializationValidator.cs index 0e186f10d901a..f9d4e628ca3c6 100644 --- a/src/VisualStudio/Core/Test.Next/Remote/SerializationValidator.cs +++ b/src/VisualStudio/Core/Test.Next/Remote/SerializationValidator.cs @@ -78,9 +78,16 @@ public SerializationValidator(HostWorkspaceServices services) Services = services; } - public async Task GetValueAsync(Checksum checksum) + private async Task GetRequiredAssetAsync(Checksum checksum) { var data = await AssetStorage.GetTestAccessor().GetRequiredAssetAsync(checksum, CancellationToken.None).ConfigureAwait(false); + Contract.ThrowIfNull(data); + return new(checksum, data); + } + + public async Task GetValueAsync(Checksum checksum) + { + var data = await GetRequiredAssetAsync(checksum).ConfigureAwait(false); Contract.ThrowIfNull(data.Value); using var context = new SolutionReplicationContext(); @@ -197,7 +204,7 @@ internal async Task VerifyAssetSerializationAsync( Func assetGetter) { // re-create asset from object - var syncObject = await AssetStorage.GetTestAccessor().GetRequiredAssetAsync(checksum, CancellationToken.None).ConfigureAwait(false); + var syncObject = await GetRequiredAssetAsync(checksum).ConfigureAwait(false); var recoveredValue = await GetValueAsync(checksum).ConfigureAwait(false); var recreatedSyncObject = assetGetter(recoveredValue, kind, Serializer); @@ -339,7 +346,7 @@ internal async Task VerifySynchronizationObjectInServiceAsync(ChecksumObjectC internal async Task VerifyChecksumInServiceAsync(Checksum checksum, WellKnownSynchronizationKind kind) { Assert.NotNull(checksum); - var otherObject = await AssetStorage.GetTestAccessor().GetRequiredAssetAsync(checksum, CancellationToken.None).ConfigureAwait(false); + var otherObject = await GetRequiredAssetAsync(checksum).ConfigureAwait(false); ChecksumEqual(checksum, kind, otherObject.Checksum, otherObject.Kind); } diff --git a/src/VisualStudio/Core/Test.Next/Remote/SnapshotSerializationTests.cs b/src/VisualStudio/Core/Test.Next/Remote/SnapshotSerializationTests.cs index 7ee05de74107d..b9a86dc26ad58 100644 --- a/src/VisualStudio/Core/Test.Next/Remote/SnapshotSerializationTests.cs +++ b/src/VisualStudio/Core/Test.Next/Remote/SnapshotSerializationTests.cs @@ -73,6 +73,13 @@ internal static Solution CreateFullSolution(Workspace workspace) loader: TextLoader.From(TextAndVersion.Create(SourceText.From("root = true"), VersionStamp.Create()))))); } + private static async Task GetRequiredAssetAsync(SolutionAssetStorage.Scope scope, Checksum checksum) + { + var data = await scope.GetTestAccessor().GetAssetAsync(checksum, CancellationToken.None).ConfigureAwait(false); + Contract.ThrowIfNull(data); + return new(checksum, data); + } + [Fact] public async Task CreateSolutionSnapshotId_Empty() { @@ -83,7 +90,7 @@ public async Task CreateSolutionSnapshotId_Empty() using var scope = await validator.AssetStorage.StoreAssetsAsync(solution, CancellationToken.None).ConfigureAwait(false); var checksum = scope.SolutionChecksum; - var solutionSyncObject = await scope.GetTestAccessor().GetAssetAsync(checksum, CancellationToken.None).ConfigureAwait(false); + var solutionSyncObject = await GetRequiredAssetAsync(scope, checksum).ConfigureAwait(false); await validator.VerifySynchronizationObjectInServiceAsync(solutionSyncObject).ConfigureAwait(false); @@ -115,7 +122,7 @@ public async Task CreateSolutionSnapshotId_Project() using var scope = await validator.AssetStorage.StoreAssetsAsync(project.Solution, CancellationToken.None).ConfigureAwait(false); var checksum = scope.SolutionChecksum; - var solutionSyncObject = await scope.GetTestAccessor().GetAssetAsync(checksum, CancellationToken.None).ConfigureAwait(false); + var solutionSyncObject = await GetRequiredAssetAsync(scope, checksum).ConfigureAwait(false); await validator.VerifySynchronizationObjectInServiceAsync(solutionSyncObject).ConfigureAwait(false); @@ -149,7 +156,7 @@ public async Task CreateSolutionSnapshotId() var validator = new SerializationValidator(workspace.Services); using var scope = await validator.AssetStorage.StoreAssetsAsync(document.Project.Solution, CancellationToken.None).ConfigureAwait(false); - var syncObject = await scope.GetTestAccessor().GetAssetAsync(scope.SolutionChecksum, CancellationToken.None).ConfigureAwait(false); + var syncObject = await GetRequiredAssetAsync(scope, scope.SolutionChecksum).ConfigureAwait(false); var solutionObject = await validator.GetValueAsync(syncObject.Checksum).ConfigureAwait(false); await validator.VerifySynchronizationObjectInServiceAsync(syncObject).ConfigureAwait(false); @@ -183,7 +190,7 @@ public async Task CreateSolutionSnapshotId_Full() var validator = new SerializationValidator(workspace.Services); using var scope = await validator.AssetStorage.StoreAssetsAsync(solution, CancellationToken.None).ConfigureAwait(false); - var syncObject = await scope.GetTestAccessor().GetAssetAsync(scope.SolutionChecksum, CancellationToken.None).ConfigureAwait(false); + var syncObject = await GetRequiredAssetAsync(scope, scope.SolutionChecksum).ConfigureAwait(false); var solutionObject = await validator.GetValueAsync(syncObject.Checksum).ConfigureAwait(false); await validator.VerifySynchronizationObjectInServiceAsync(syncObject).ConfigureAwait(false); diff --git a/src/Workspaces/Remote/Core/SolutionAsset.cs b/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs similarity index 100% rename from src/Workspaces/Remote/Core/SolutionAsset.cs rename to src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs diff --git a/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs b/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs index 37a673d75add1..812e1425dd6e8 100644 --- a/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs +++ b/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs @@ -21,7 +21,7 @@ internal static class RemoteHostAssetSerialization { public static async ValueTask WriteDataAsync( Stream stream, - Dictionary assetMap, + Dictionary assetMap, ISerializerService serializer, SolutionReplicationContext context, Checksum solutionChecksum, @@ -55,14 +55,15 @@ public static async ValueTask WriteDataAsync( return; - static void WriteAsset(ObjectWriter writer, ISerializerService serializer, SolutionReplicationContext context, SolutionAsset asset, CancellationToken cancellationToken) + static void WriteAsset(ObjectWriter writer, ISerializerService serializer, SolutionReplicationContext context, object asset, CancellationToken cancellationToken) { - Debug.Assert(asset.Kind != WellKnownSynchronizationKind.Null, "We should not be sending null assets"); - writer.WriteInt32((int)asset.Kind); + var kind = asset.GetWellKnownSynchronizationKind(); + Contract.ThrowIfTrue(kind == WellKnownSynchronizationKind.Null); + writer.WriteInt32((int)kind); // null is already indicated by checksum and kind above: - if (asset.Value is not null) - serializer.Serialize(asset.Value, writer, context, cancellationToken); + if (asset is not null) + serializer.Serialize(asset, writer, context, cancellationToken); } } diff --git a/src/Workspaces/Remote/Core/SolutionAssetProvider.cs b/src/Workspaces/Remote/Core/SolutionAssetProvider.cs index a27cb644fc29b..3b35344e781b1 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetProvider.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetProvider.cs @@ -58,15 +58,15 @@ private async ValueTask WriteAssetsWorkerAsync(PipeWriter pipeWriter, Checksum s var serializer = _services.GetRequiredService(); var scope = assetStorage.GetScope(solutionChecksum); - using var _ = PooledDictionary.GetInstance(out var assetMap); + using var resultMap = Creator.CreateResultMap(); - await scope.AddAssetsAsync(checksums, assetMap, cancellationToken).ConfigureAwait(false); + await scope.AddAssetsAsync(checksums, resultMap.Object, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); using var stream = new PipeWriterStream(pipeWriter); await RemoteHostAssetSerialization.WriteDataAsync( - stream, assetMap, serializer, scope.ReplicationContext, + stream, resultMap.Object, serializer, scope.ReplicationContext, solutionChecksum, checksums, cancellationToken).ConfigureAwait(false); } diff --git a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs index 27e09e4476daf..094e2137e267a 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs @@ -53,23 +53,19 @@ public void Dispose() /// public async Task AddAssetsAsync( ImmutableArray checksums, - Dictionary assetMap, + Dictionary assetMap, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using var checksumsToFind = Creator.CreateChecksumSet(checksums); - using var resultMap = Creator.CreateResultMap(); var numberOfChecksumsToSearch = checksumsToFind.Object.Count; if (checksumsToFind.Object.Remove(Checksum.Null)) - assetMap[Checksum.Null] = SolutionAsset.Null; + assetMap[Checksum.Null] = null; - await FindAssetsAsync(checksumsToFind.Object, resultMap.Object, cancellationToken).ConfigureAwait(false); - - foreach (var (checksum, value) in resultMap.Object) - assetMap[checksum] = new SolutionAsset(checksum, value); + await FindAssetsAsync(checksumsToFind.Object, assetMap, cancellationToken).ConfigureAwait(false); Contract.ThrowIfTrue(checksumsToFind.Object.Count > 0); Contract.ThrowIfTrue(assetMap.Count != numberOfChecksumsToSearch); @@ -100,13 +96,9 @@ public readonly struct TestAccessor(Scope scope) /// Retrieve asset of a specified available within from /// the storage. /// - public async ValueTask GetAssetAsync(Checksum checksum, CancellationToken cancellationToken) + public async ValueTask GetAssetAsync(Checksum checksum, CancellationToken cancellationToken) { - if (checksum == Checksum.Null) - { - // check nil case - return SolutionAsset.Null; - } + Contract.ThrowIfTrue(checksum == Checksum.Null); using var checksumPool = Creator.CreateChecksumSet(checksum); using var resultPool = Creator.CreateResultMap(); @@ -117,7 +109,7 @@ public async ValueTask GetAssetAsync(Checksum checksum, Cancellat var (resultingChecksum, value) = resultPool.Object.First(); Contract.ThrowIfFalse(checksum == resultingChecksum); - return new SolutionAsset(checksum, value); + return value; } } } diff --git a/src/Workspaces/Remote/Core/SolutionAssetStorage.cs b/src/Workspaces/Remote/Core/SolutionAssetStorage.cs index 5a2a5ffbf3d5c..49050acba04b9 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetStorage.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetStorage.cs @@ -116,7 +116,7 @@ internal TestAccessor(SolutionAssetStorage solutionAssetStorage) _solutionAssetStorage = solutionAssetStorage; } - public async ValueTask GetRequiredAssetAsync(Checksum checksum, CancellationToken cancellationToken) + public async ValueTask GetRequiredAssetAsync(Checksum checksum, CancellationToken cancellationToken) { return await _solutionAssetStorage._checksumToScope.Single().Value.GetTestAccessor().GetAssetAsync(checksum, cancellationToken).ConfigureAwait(false); } From 21a279b729e25a56ed0c4620089946d62b3133ee Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 11 Oct 2023 17:20:48 -0700 Subject: [PATCH 07/12] remove --- .../Workspace/Solution/StateChecksums.cs | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs b/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs index 08297be164dbd..c6348d8cdaad6 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs @@ -98,16 +98,6 @@ public async Task FindAsync( result[FrozenSourceGeneratedDocumentText] = await SerializableSourceText.FromTextDocumentStateAsync(state.FrozenSourceGeneratedDocumentState, cancellationToken).ConfigureAwait(false); } - //if (searchingChecksumsLeft.Remove(Projects.Checksum)) - //{ - // result[Projects.Checksum] = Projects; - //} - - //if (searchingChecksumsLeft.Remove(AnalyzerReferences.Checksum)) - //{ - // result[AnalyzerReferences.Checksum] = AnalyzerReferences; - //} - foreach (var (_, projectState) in state.ProjectStates) { if (searchingChecksumsLeft.Count == 0) @@ -242,36 +232,6 @@ public async Task FindAsync( result[ParseOptions] = state.ParseOptions; } - //if (searchingChecksumsLeft.Remove(Documents.Checksum)) - //{ - // result[Documents.Checksum] = Documents; - //} - - //if (searchingChecksumsLeft.Remove(ProjectReferences.Checksum)) - //{ - // result[ProjectReferences.Checksum] = ProjectReferences; - //} - - //if (searchingChecksumsLeft.Remove(MetadataReferences.Checksum)) - //{ - // result[MetadataReferences.Checksum] = MetadataReferences; - //} - - //if (searchingChecksumsLeft.Remove(AnalyzerReferences.Checksum)) - //{ - // result[AnalyzerReferences.Checksum] = AnalyzerReferences; - //} - - //if (searchingChecksumsLeft.Remove(AdditionalDocuments.Checksum)) - //{ - // result[AdditionalDocuments.Checksum] = AdditionalDocuments; - //} - - //if (searchingChecksumsLeft.Remove(AnalyzerConfigDocuments.Checksum)) - //{ - // result[AnalyzerConfigDocuments.Checksum] = AnalyzerConfigDocuments; - //} - ChecksumCollection.Find(state.ProjectReferences, ProjectReferences, searchingChecksumsLeft, result, cancellationToken); ChecksumCollection.Find(state.MetadataReferences, MetadataReferences, searchingChecksumsLeft, result, cancellationToken); ChecksumCollection.Find(state.AnalyzerReferences, AnalyzerReferences, searchingChecksumsLeft, result, cancellationToken); From d5f572916c448bd00431fda473d678fd36b8ab31 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 11 Oct 2023 17:24:23 -0700 Subject: [PATCH 08/12] Revert --- src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs b/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs index 7e9cd8ec1a7ad..1d77b868d5d2b 100644 --- a/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs +++ b/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.Remote /// /// Represents a part of solution snapshot along with its checksum. /// - internal sealed class SolutionAsset + internal readonly struct SolutionAsset { public static readonly SolutionAsset Null = new(value: null, Checksum.Null, WellKnownSynchronizationKind.Null); From bc04f57f82eded85965b0b8e1ce2dcbfba6d4b65 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 11 Oct 2023 17:33:00 -0700 Subject: [PATCH 09/12] Remove null concept --- .../Core/Test.Next/Remote/SolutionAsset.cs | 63 +++++++++---------- .../Remote/WellKnownSynchronizationKind.cs | 7 +-- .../Serialization/SerializationExtensions.cs | 1 - .../Serialization/SerializerService.cs | 10 --- .../Core/RemoteHostAssetSerialization.cs | 6 +- 5 files changed, 32 insertions(+), 55 deletions(-) diff --git a/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs b/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs index 1d77b868d5d2b..379411f01b4d2 100644 --- a/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs +++ b/src/VisualStudio/Core/Test.Next/Remote/SolutionAsset.cs @@ -5,46 +5,39 @@ using Microsoft.CodeAnalysis.Serialization; using Roslyn.Utilities; -namespace Microsoft.CodeAnalysis.Remote +namespace Microsoft.CodeAnalysis.Remote; + +/// +/// Represents a part of solution snapshot along with its checksum. +/// +internal readonly struct SolutionAsset { /// - /// Represents a part of solution snapshot along with its checksum. + /// Indicates what kind of object it. + /// + /// Used in transportation framework and deserialization service to hand shake how to send over data and + /// deserialize serialized data. /// - internal readonly struct SolutionAsset - { - public static readonly SolutionAsset Null = new(value: null, Checksum.Null, WellKnownSynchronizationKind.Null); - - /// - /// Indicates what kind of object it. - /// - /// Used in transportation framework and deserialization service to hand shake how to send over data and - /// deserialize serialized data. - /// - public readonly WellKnownSynchronizationKind Kind; - - /// - /// Checksum of . - /// - public readonly Checksum Checksum; + public readonly WellKnownSynchronizationKind Kind; - public readonly object? Value; - - public SolutionAsset(object? value, Checksum checksum, WellKnownSynchronizationKind kind) - { - // SolutionAsset is not allowed to hold strong references to SourceText. SerializableSourceText is used - // instead to allow data to be released from process address space when it is also held in temporary - // storage. - // https://github.com/dotnet/roslyn/issues/43802 - Contract.ThrowIfTrue(kind is WellKnownSynchronizationKind.SourceText); + /// + /// Checksum of . + /// + public readonly Checksum Checksum; - Checksum = checksum; - Kind = kind; - Value = value; - } + public readonly object? Value; - public SolutionAsset(Checksum checksum, object value) - : this(value, checksum, value.GetWellKnownSynchronizationKind()) - { - } + public SolutionAsset(Checksum checksum, object value) + { + var kind = value.GetWellKnownSynchronizationKind(); + // SolutionAsset is not allowed to hold strong references to SourceText. SerializableSourceText is used + // instead to allow data to be released from process address space when it is also held in temporary + // storage. + // https://github.com/dotnet/roslyn/issues/43802 + Contract.ThrowIfTrue(kind is WellKnownSynchronizationKind.SourceText); + + Checksum = checksum; + Kind = kind; + Value = value; } } diff --git a/src/Workspaces/Core/Portable/Remote/WellKnownSynchronizationKind.cs b/src/Workspaces/Core/Portable/Remote/WellKnownSynchronizationKind.cs index 5ccb06c14d357..56e7a182e4d6a 100644 --- a/src/Workspaces/Core/Portable/Remote/WellKnownSynchronizationKind.cs +++ b/src/Workspaces/Core/Portable/Remote/WellKnownSynchronizationKind.cs @@ -2,16 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - namespace Microsoft.CodeAnalysis.Serialization { - // TODO: Kind might not actually needed. see whether we can get rid of this internal enum WellKnownSynchronizationKind { - Null, + // Start at a different value from 0 so that if we ever get 0 we know it's a bug. - SolutionState, + SolutionState = 1, ProjectState, DocumentState, diff --git a/src/Workspaces/Core/Portable/Serialization/SerializationExtensions.cs b/src/Workspaces/Core/Portable/Serialization/SerializationExtensions.cs index 1cf58a27ba643..81c63a798420b 100644 --- a/src/Workspaces/Core/Portable/Serialization/SerializationExtensions.cs +++ b/src/Workspaces/Core/Portable/Serialization/SerializationExtensions.cs @@ -4,7 +4,6 @@ using System.Collections.Immutable; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; diff --git a/src/Workspaces/Core/Portable/Serialization/SerializerService.cs b/src/Workspaces/Core/Portable/Serialization/SerializerService.cs index 74aec50a9fcf4..25c295d876381 100644 --- a/src/Workspaces/Core/Portable/Serialization/SerializerService.cs +++ b/src/Workspaces/Core/Portable/Serialization/SerializerService.cs @@ -71,9 +71,6 @@ public Checksum CreateChecksum(object value, CancellationToken cancellationToken switch (kind) { - case WellKnownSynchronizationKind.Null: - return Checksum.Null; - case WellKnownSynchronizationKind.CompilationOptions: case WellKnownSynchronizationKind.ParseOptions: case WellKnownSynchronizationKind.ProjectReference: @@ -110,10 +107,6 @@ public void Serialize(object value, ObjectWriter writer, SolutionReplicationCont switch (kind) { - case WellKnownSynchronizationKind.Null: - // do nothing - return; - case WellKnownSynchronizationKind.SolutionAttributes: case WellKnownSynchronizationKind.ProjectAttributes: case WellKnownSynchronizationKind.DocumentAttributes: @@ -182,9 +175,6 @@ public void Serialize(object value, ObjectWriter writer, SolutionReplicationCont switch (kind) { - case WellKnownSynchronizationKind.Null: - return default; - case WellKnownSynchronizationKind.SolutionState: return (T)(object)SolutionStateChecksums.Deserialize(reader); diff --git a/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs b/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs index 812e1425dd6e8..1afe7cd0d52ac 100644 --- a/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs +++ b/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs @@ -57,13 +57,11 @@ public static async ValueTask WriteDataAsync( static void WriteAsset(ObjectWriter writer, ISerializerService serializer, SolutionReplicationContext context, object asset, CancellationToken cancellationToken) { + Contract.ThrowIfNull(asset); var kind = asset.GetWellKnownSynchronizationKind(); - Contract.ThrowIfTrue(kind == WellKnownSynchronizationKind.Null); writer.WriteInt32((int)kind); - // null is already indicated by checksum and kind above: - if (asset is not null) - serializer.Serialize(asset, writer, context, cancellationToken); + serializer.Serialize(asset, writer, context, cancellationToken); } } From d83c5e3d698a33a0506b11ab2bc2c076c82f948b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 11 Oct 2023 17:38:28 -0700 Subject: [PATCH 10/12] Do not allow nulls --- .../Test.Next/Remote/SerializationValidator.cs | 2 -- .../Serialization/SerializerService.cs | 2 +- .../Workspace/Solution/ChecksumCollection.cs | 6 +++--- .../Workspace/Solution/StateChecksums.cs | 6 +++--- .../Fakes/SimpleAssetSource.cs | 2 +- .../Core/RemoteHostAssetSerialization.cs | 5 +---- .../Remote/Core/SolutionAssetStorage.Scope.cs | 18 ++++++++---------- .../ServiceHub/Host/SolutionAssetSource.cs | 7 ------- 8 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/VisualStudio/Core/Test.Next/Remote/SerializationValidator.cs b/src/VisualStudio/Core/Test.Next/Remote/SerializationValidator.cs index f9d4e628ca3c6..3164ed53107c4 100644 --- a/src/VisualStudio/Core/Test.Next/Remote/SerializationValidator.cs +++ b/src/VisualStudio/Core/Test.Next/Remote/SerializationValidator.cs @@ -11,9 +11,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Remote; using Microsoft.CodeAnalysis.Serialization; -using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; diff --git a/src/Workspaces/Core/Portable/Serialization/SerializerService.cs b/src/Workspaces/Core/Portable/Serialization/SerializerService.cs index 25c295d876381..315653b19edb9 100644 --- a/src/Workspaces/Core/Portable/Serialization/SerializerService.cs +++ b/src/Workspaces/Core/Portable/Serialization/SerializerService.cs @@ -167,7 +167,7 @@ public void Serialize(object value, ObjectWriter writer, SolutionReplicationCont } } - public T? Deserialize(WellKnownSynchronizationKind kind, ObjectReader reader, CancellationToken cancellationToken) + public T Deserialize(WellKnownSynchronizationKind kind, ObjectReader reader, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Serializer_Deserialize, s_logKind, kind, cancellationToken)) { diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/ChecksumCollection.cs b/src/Workspaces/Core/Portable/Workspace/Solution/ChecksumCollection.cs index e556e26603a73..548bed42b60e2 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/ChecksumCollection.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/ChecksumCollection.cs @@ -47,7 +47,7 @@ public void AddAllTo(HashSet checksums) internal static async Task FindAsync( TextDocumentStates documentStates, HashSet searchingChecksumsLeft, - Dictionary result, + Dictionary result, CancellationToken cancellationToken) where TState : TextDocumentState { foreach (var (_, state) in documentStates.States) @@ -66,8 +66,8 @@ internal static void Find( IReadOnlyList values, ChecksumCollection checksums, HashSet searchingChecksumsLeft, - Dictionary result, - CancellationToken cancellationToken) + Dictionary result, + CancellationToken cancellationToken) where T : class { Contract.ThrowIfFalse(values.Count == checksums.Children.Length); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs b/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs index c6348d8cdaad6..ea24a05aa446f 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/StateChecksums.cs @@ -72,7 +72,7 @@ public static SolutionStateChecksums Deserialize(ObjectReader reader) public async Task FindAsync( SolutionState state, HashSet searchingChecksumsLeft, - Dictionary result, + Dictionary result, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -199,7 +199,7 @@ public static ProjectStateChecksums Deserialize(ObjectReader reader) public async Task FindAsync( ProjectState state, HashSet searchingChecksumsLeft, - Dictionary result, + Dictionary result, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -273,7 +273,7 @@ public static DocumentStateChecksums Deserialize(ObjectReader reader) public async Task FindAsync( TextDocumentState state, HashSet searchingChecksumsLeft, - Dictionary result, + Dictionary result, CancellationToken cancellationToken) { Debug.Assert(state.TryGetStateChecksums(out var stateChecksum) && this == stateChecksum); diff --git a/src/Workspaces/CoreTestUtilities/Fakes/SimpleAssetSource.cs b/src/Workspaces/CoreTestUtilities/Fakes/SimpleAssetSource.cs index df03e9cecb5e5..87d9e31bb9b65 100644 --- a/src/Workspaces/CoreTestUtilities/Fakes/SimpleAssetSource.cs +++ b/src/Workspaces/CoreTestUtilities/Fakes/SimpleAssetSource.cs @@ -37,7 +37,7 @@ public ValueTask> GetAssetsAsync( stream.Position = 0; using var reader = ObjectReader.GetReader(stream, leaveOpen: true, cancellationToken); var asset = deserializerService.Deserialize(data.GetWellKnownSynchronizationKind(), reader, cancellationToken); - Contract.ThrowIfTrue(asset is null); + Contract.ThrowIfNull(asset); results.Add(asset); } else diff --git a/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs b/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs index 1afe7cd0d52ac..2bd56d23a98ba 100644 --- a/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs +++ b/src/Workspaces/Remote/Core/RemoteHostAssetSerialization.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -89,9 +88,7 @@ public static ImmutableArray ReadData(Stream stream, Checksum solutionCh // in service hub, cancellation means simply closed stream var result = serializerService.Deserialize(kind, reader, cancellationToken); - - Debug.Assert(result != null, "We should not be requesting null assets"); - + Contract.ThrowIfNull(result); results.Add(result); } diff --git a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs index 094e2137e267a..39e1fd5d0514e 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -53,25 +52,24 @@ public void Dispose() /// public async Task AddAssetsAsync( ImmutableArray checksums, - Dictionary assetMap, + Dictionary assetMap, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - using var checksumsToFind = Creator.CreateChecksumSet(checksums); + using var obj = Creator.CreateChecksumSet(checksums); + var checksumsToFind = obj.Object; - var numberOfChecksumsToSearch = checksumsToFind.Object.Count; + var numberOfChecksumsToSearch = checksumsToFind.Count; + Contract.ThrowIfTrue(checksumsToFind.Contains(Checksum.Null)); - if (checksumsToFind.Object.Remove(Checksum.Null)) - assetMap[Checksum.Null] = null; + await FindAssetsAsync(checksumsToFind, assetMap, cancellationToken).ConfigureAwait(false); - await FindAssetsAsync(checksumsToFind.Object, assetMap, cancellationToken).ConfigureAwait(false); - - Contract.ThrowIfTrue(checksumsToFind.Object.Count > 0); + Contract.ThrowIfTrue(checksumsToFind.Count > 0); Contract.ThrowIfTrue(assetMap.Count != numberOfChecksumsToSearch); } - private async Task FindAssetsAsync(HashSet remainingChecksumsToFind, Dictionary result, CancellationToken cancellationToken) + private async Task FindAssetsAsync(HashSet remainingChecksumsToFind, Dictionary result, CancellationToken cancellationToken) { var solutionState = this.Solution; if (solutionState.TryGetStateChecksums(out var stateChecksums)) diff --git a/src/Workspaces/Remote/ServiceHub/Host/SolutionAssetSource.cs b/src/Workspaces/Remote/ServiceHub/Host/SolutionAssetSource.cs index 95aa88020a349..addf63d8f3512 100644 --- a/src/Workspaces/Remote/ServiceHub/Host/SolutionAssetSource.cs +++ b/src/Workspaces/Remote/ServiceHub/Host/SolutionAssetSource.cs @@ -2,19 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; using System.Collections.Immutable; -using System.IO; -using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Serialization; using Microsoft.ServiceHub.Framework; using Microsoft.VisualStudio.Threading; -using Roslyn.Utilities; -using StreamJsonRpc; namespace Microsoft.CodeAnalysis.Remote { From a1d5d8f6fd15569c6bb5fe63dfa1d8b8ab0bb5fa Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 11 Oct 2023 17:42:16 -0700 Subject: [PATCH 11/12] Simplify --- src/Workspaces/Core/Portable/Serialization/PooledList.cs | 8 ++++++-- src/Workspaces/Remote/Core/SolutionAssetProvider.cs | 6 +++--- src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs | 8 ++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Workspaces/Core/Portable/Serialization/PooledList.cs b/src/Workspaces/Core/Portable/Serialization/PooledList.cs index fd00a457849b6..8ee5c6988d8c5 100644 --- a/src/Workspaces/Core/Portable/Serialization/PooledList.cs +++ b/src/Workspaces/Core/Portable/Serialization/PooledList.cs @@ -36,7 +36,11 @@ public static PooledObject> CreateChecksumSet(Checksum checksu public static PooledObject> CreateList() => SharedPools.Default>().GetPooledObject(); - public static PooledObject> CreateResultMap() - => SharedPools.Default>().GetPooledObject(); + public static PooledObject> CreateResultMap(out Dictionary result) + { + var pooled = SharedPools.Default>().GetPooledObject(); + result = pooled.Object; + return pooled; + } } } diff --git a/src/Workspaces/Remote/Core/SolutionAssetProvider.cs b/src/Workspaces/Remote/Core/SolutionAssetProvider.cs index 3b35344e781b1..c02a124b3d3ba 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetProvider.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetProvider.cs @@ -58,15 +58,15 @@ private async ValueTask WriteAssetsWorkerAsync(PipeWriter pipeWriter, Checksum s var serializer = _services.GetRequiredService(); var scope = assetStorage.GetScope(solutionChecksum); - using var resultMap = Creator.CreateResultMap(); + using var _ = Creator.CreateResultMap(out var resultMap); - await scope.AddAssetsAsync(checksums, resultMap.Object, cancellationToken).ConfigureAwait(false); + await scope.AddAssetsAsync(checksums, resultMap, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); using var stream = new PipeWriterStream(pipeWriter); await RemoteHostAssetSerialization.WriteDataAsync( - stream, resultMap.Object, serializer, scope.ReplicationContext, + stream, resultMap, serializer, scope.ReplicationContext, solutionChecksum, checksums, cancellationToken).ConfigureAwait(false); } diff --git a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs index 39e1fd5d0514e..a5ab26a8b3d1b 100644 --- a/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs +++ b/src/Workspaces/Remote/Core/SolutionAssetStorage.Scope.cs @@ -99,12 +99,12 @@ public async ValueTask GetAssetAsync(Checksum checksum, CancellationToke Contract.ThrowIfTrue(checksum == Checksum.Null); using var checksumPool = Creator.CreateChecksumSet(checksum); - using var resultPool = Creator.CreateResultMap(); + using var _ = Creator.CreateResultMap(out var resultPool); - await scope.FindAssetsAsync(checksumPool.Object, resultPool.Object, cancellationToken).ConfigureAwait(false); - Contract.ThrowIfTrue(resultPool.Object.Count != 1); + await scope.FindAssetsAsync(checksumPool.Object, resultPool, cancellationToken).ConfigureAwait(false); + Contract.ThrowIfTrue(resultPool.Count != 1); - var (resultingChecksum, value) = resultPool.Object.First(); + var (resultingChecksum, value) = resultPool.First(); Contract.ThrowIfFalse(checksum == resultingChecksum); return value; From 7188f10f3a848bef64452809da9842af63d89652 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 11 Oct 2023 17:59:09 -0700 Subject: [PATCH 12/12] NRT --- .../Remote/ServiceHub/Host/TestUtils.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Workspaces/Remote/ServiceHub/Host/TestUtils.cs b/src/Workspaces/Remote/ServiceHub/Host/TestUtils.cs index c49594bcba43e..6efa6d2d0e41f 100644 --- a/src/Workspaces/Remote/ServiceHub/Host/TestUtils.cs +++ b/src/Workspaces/Remote/ServiceHub/Host/TestUtils.cs @@ -81,7 +81,7 @@ internal static async Task AssertChecksumsAsync( return; - static void AppendMismatch(List> items, string title, StringBuilder stringBuilder) + static void AppendMismatch(List> items, string title, StringBuilder stringBuilder) { if (items.Count == 0) { @@ -97,13 +97,13 @@ static void AppendMismatch(List> items, string t stringBuilder.AppendLine(); } - async Task>> GetAssetFromAssetServiceAsync(IEnumerable checksums) + async Task>> GetAssetFromAssetServiceAsync(IEnumerable checksums) { - var items = new List>(); + var items = new List>(); foreach (var checksum in checksums) { - items.Add(new KeyValuePair(checksum, await assetService.GetAssetAsync(checksum, CancellationToken.None).ConfigureAwait(false))); + items.Add(new KeyValuePair(checksum, await assetService.GetAssetAsync(checksum, CancellationToken.None).ConfigureAwait(false))); } return items; @@ -141,9 +141,9 @@ async Task> GetAllChildrenChecksumsAsync(Checksum solutionChec /// create checksum to correspoing object map from solution /// this map should contain every parts of solution that can be used to re-create the solution back /// - public static async Task> GetAssetMapAsync(this Solution solution, CancellationToken cancellationToken) + public static async Task> GetAssetMapAsync(this Solution solution, CancellationToken cancellationToken) { - var map = new Dictionary(); + var map = new Dictionary(); await solution.AppendAssetMapAsync(map, cancellationToken).ConfigureAwait(false); return map; } @@ -152,19 +152,19 @@ async Task> GetAllChildrenChecksumsAsync(Checksum solutionChec /// create checksum to correspoing object map from project /// this map should contain every parts of project that can be used to re-create the project back /// - public static async Task> GetAssetMapAsync(this Project project, CancellationToken cancellationToken) + public static async Task> GetAssetMapAsync(this Project project, CancellationToken cancellationToken) { - var map = new Dictionary(); + var map = new Dictionary(); await project.AppendAssetMapAsync(map, cancellationToken).ConfigureAwait(false); return map; } - public static Task AppendAssetMapAsync(this Solution solution, Dictionary map, CancellationToken cancellationToken) + public static Task AppendAssetMapAsync(this Solution solution, Dictionary map, CancellationToken cancellationToken) => AppendAssetMapAsync(solution, map, projectId: null, cancellationToken); public static async Task AppendAssetMapAsync( - this Solution solution, Dictionary map, ProjectId? projectId, CancellationToken cancellationToken) + this Solution solution, Dictionary map, ProjectId? projectId, CancellationToken cancellationToken) { if (projectId == null) { @@ -186,7 +186,7 @@ public static async Task AppendAssetMapAsync( } } - private static async Task AppendAssetMapAsync(this Project project, Dictionary map, CancellationToken cancellationToken) + private static async Task AppendAssetMapAsync(this Project project, Dictionary map, CancellationToken cancellationToken) { if (!RemoteSupportedLanguages.IsSupported(project.Language)) {