From 0ca8ae3b541e79cea9fa5605176435749bbf4f4c Mon Sep 17 00:00:00 2001 From: martincostello Date: Mon, 14 Apr 2025 11:49:25 +0100 Subject: [PATCH 1/3] Use SHA512.HashDataAsync Use `SHA512.HashDataAsync()` for .NET 8 to reduce allocations. --- .../Models/OpenApiDocument.cs | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 0f15a27d9..719b7db39 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -524,20 +524,37 @@ public void SetReferenceHostDocument() /// The hash value. public async Task GetHashCodeAsync(CancellationToken cancellationToken = default) { + byte[]? hash; + +#if NET + using var memoryStream = new MemoryStream(); + using var streamWriter = new StreamWriter(memoryStream); + + await WriteDocumentAsync(streamWriter, cancellationToken).ConfigureAwait(false); + + memoryStream.Seek(0, SeekOrigin.Begin); + + hash = await SHA512.HashDataAsync(memoryStream, cancellationToken).ConfigureAwait(false); +#else using HashAlgorithm sha = SHA512.Create(); using var cryptoStream = new CryptoStream(Stream.Null, sha, CryptoStreamMode.Write); using var streamWriter = new StreamWriter(cryptoStream); - var openApiJsonWriter = new OpenApiJsonWriter(streamWriter, new() { Terse = true }); - SerializeAsV3(openApiJsonWriter); - await openApiJsonWriter.FlushAsync(cancellationToken).ConfigureAwait(false); + await WriteDocumentAsync(streamWriter, cancellationToken).ConfigureAwait(false); -#if NET5_0_OR_GREATER - await cryptoStream.FlushFinalBlockAsync(cancellationToken).ConfigureAwait(false); -#else cryptoStream.FlushFinalBlock(); + + hash = sha.Hash; #endif - return ConvertByteArrayToString(sha.Hash ?? []); + + return ConvertByteArrayToString(hash ?? []); + + async Task WriteDocumentAsync(TextWriter writer, CancellationToken token) + { + var openApiJsonWriter = new OpenApiJsonWriter(writer, new() { Terse = true }); + SerializeAsV3(openApiJsonWriter); + await openApiJsonWriter.FlushAsync(cancellationToken).ConfigureAwait(false); + } } private static string ConvertByteArrayToString(byte[] hash) From 5b5bac911afc1e7a5e7e18414a5904b0717fde63 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 14 Apr 2025 08:37:24 -0400 Subject: [PATCH 2/3] Apply suggestions from code review --- src/Microsoft.OpenApi/Models/OpenApiDocument.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 719b7db39..b9b2e7f62 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -524,9 +524,7 @@ public void SetReferenceHostDocument() /// The hash value. public async Task GetHashCodeAsync(CancellationToken cancellationToken = default) { - byte[]? hash; - -#if NET +#if NET7_OR_GREATER using var memoryStream = new MemoryStream(); using var streamWriter = new StreamWriter(memoryStream); @@ -534,7 +532,7 @@ public async Task GetHashCodeAsync(CancellationToken cancellationToken = memoryStream.Seek(0, SeekOrigin.Begin); - hash = await SHA512.HashDataAsync(memoryStream, cancellationToken).ConfigureAwait(false); + var hash = await SHA512.HashDataAsync(memoryStream, cancellationToken).ConfigureAwait(false); #else using HashAlgorithm sha = SHA512.Create(); using var cryptoStream = new CryptoStream(Stream.Null, sha, CryptoStreamMode.Write); @@ -544,7 +542,7 @@ public async Task GetHashCodeAsync(CancellationToken cancellationToken = cryptoStream.FlushFinalBlock(); - hash = sha.Hash; + var hash = sha.Hash; #endif return ConvertByteArrayToString(hash ?? []); From 69051c887e936031fc6c28bce54ed00f17d69fe5 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 14 Apr 2025 08:39:28 -0400 Subject: [PATCH 3/3] chore: uses 31 serialization method --- src/Microsoft.OpenApi/Models/OpenApiDocument.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index b9b2e7f62..f7b487cf1 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -550,7 +550,7 @@ public async Task GetHashCodeAsync(CancellationToken cancellationToken = async Task WriteDocumentAsync(TextWriter writer, CancellationToken token) { var openApiJsonWriter = new OpenApiJsonWriter(writer, new() { Terse = true }); - SerializeAsV3(openApiJsonWriter); + SerializeAsV31(openApiJsonWriter); await openApiJsonWriter.FlushAsync(cancellationToken).ConfigureAwait(false); } }