Skip to content

Commit

Permalink
Merge pull request #1170 from json-api-dotnet/json-sourcegen
Browse files Browse the repository at this point in the history
Minor serialization tweaks
  • Loading branch information
maurei committed Sep 6, 2022
2 parents 0185311 + f760e8f commit 3069341
Show file tree
Hide file tree
Showing 24 changed files with 254 additions and 253 deletions.
4 changes: 2 additions & 2 deletions benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(TargetFrameworkName)</TargetFramework>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>

<ItemGroup>
Expand All @@ -10,6 +11,5 @@

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="Moq" Version="$(MoqVersion)" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace Benchmarks.Deserialization;

[MarkdownExporter]
[MemoryDiagnoser]
// ReSharper disable once ClassCanBeSealed.Global
public class OperationsDeserializationBenchmarks : DeserializationBenchmarkBase
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace Benchmarks.Deserialization;

[MarkdownExporter]
[MemoryDiagnoser]
// ReSharper disable once ClassCanBeSealed.Global
public class ResourceDeserializationBenchmarks : DeserializationBenchmarkBase
{
Expand Down
31 changes: 4 additions & 27 deletions benchmarks/QueryString/QueryStringParserBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using System.ComponentModel.Design;
using BenchmarkDotNet.Attributes;
using Benchmarks.Tools;
using JsonApiDotNetCore;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Middleware;
using JsonApiDotNetCore.QueryStrings;
using JsonApiDotNetCore.QueryStrings.Internal;
using JsonApiDotNetCore.Resources;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging.Abstractions;

namespace Benchmarks.QueryString;
Expand Down Expand Up @@ -71,31 +70,9 @@ public void DescendingSort()
[Benchmark]
public void ComplexQuery()
{
Run(100, () =>
{
const string queryString =
"?filter[alt-attr-name]=abc,eq:abc&sort=-alt-attr-name&include=child&page[size]=1&fields[alt-resource-name]=alt-attr-name";
_queryStringAccessor.SetQueryString(queryString);
_queryStringReader.ReadAll(null);
});
}

private void Run(int iterations, Action action)
{
for (int index = 0; index < iterations; index++)
{
action();
}
}

private sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor
{
public IQueryCollection Query { get; private set; } = new QueryCollection();
const string queryString = "?filter[alt-attr-name]=abc,eq:abc&sort=-alt-attr-name&include=child&page[size]=1&fields[alt-resource-name]=alt-attr-name";

public void SetQueryString(string queryString)
{
Query = new QueryCollection(QueryHelpers.ParseQuery(queryString));
}
_queryStringAccessor.SetQueryString(queryString);
_queryStringReader.ReadAll(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace Benchmarks.Serialization;

[MarkdownExporter]
[MemoryDiagnoser]
// ReSharper disable once ClassCanBeSealed.Global
public class OperationsSerializationBenchmarks : SerializationBenchmarkBase
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Benchmarks.Serialization;

[MarkdownExporter]
[MemoryDiagnoser]
// ReSharper disable once ClassCanBeSealed.Global
public class ResourceSerializationBenchmarks : SerializationBenchmarkBase
{
Expand Down
147 changes: 3 additions & 144 deletions benchmarks/Serialization/SerializationBenchmarkBase.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
using System.Collections.Immutable;
using System.Text.Json;
using System.Text.Json.Serialization;
using Benchmarks.Tools;
using JetBrains.Annotations;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Middleware;
using JsonApiDotNetCore.Queries;
using JsonApiDotNetCore.Queries.Expressions;
using JsonApiDotNetCore.Queries.Internal;
using JsonApiDotNetCore.QueryStrings;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCore.Resources.Annotations;
using JsonApiDotNetCore.Serialization.Objects;
using JsonApiDotNetCore.Serialization.Response;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging.Abstractions;

namespace Benchmarks.Serialization;
Expand Down Expand Up @@ -45,9 +41,9 @@ protected SerializationBenchmarkBase()
// ReSharper restore VirtualMemberCallInConstructor

var linkBuilder = new FakeLinkBuilder();
var metaBuilder = new FakeMetaBuilder();
var metaBuilder = new NoMetaBuilder();
IQueryConstraintProvider[] constraintProviders = Array.Empty<IQueryConstraintProvider>();
var resourceDefinitionAccessor = new FakeResourceDefinitionAccessor();
var resourceDefinitionAccessor = new NeverResourceDefinitionAccessor();
var sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor);
var requestQueryStringAccessor = new FakeRequestQueryStringAccessor();

Expand Down Expand Up @@ -122,141 +118,4 @@ public sealed class OutgoingResource : Identifiable<int>
[HasMany]
public ISet<OutgoingResource> Multi5 { get; set; } = null!;
}

private sealed class FakeResourceDefinitionAccessor : IResourceDefinitionAccessor
{
public IImmutableSet<IncludeElementExpression> OnApplyIncludes(ResourceType resourceType, IImmutableSet<IncludeElementExpression> existingIncludes)
{
return existingIncludes;
}

public FilterExpression? OnApplyFilter(ResourceType resourceType, FilterExpression? existingFilter)
{
return existingFilter;
}

public SortExpression? OnApplySort(ResourceType resourceType, SortExpression? existingSort)
{
return existingSort;
}

public PaginationExpression? OnApplyPagination(ResourceType resourceType, PaginationExpression? existingPagination)
{
return existingPagination;
}

public SparseFieldSetExpression? OnApplySparseFieldSet(ResourceType resourceType, SparseFieldSetExpression? existingSparseFieldSet)
{
return existingSparseFieldSet;
}

public object? GetQueryableHandlerForQueryStringParameter(Type resourceClrType, string parameterName)
{
return null;
}

public IDictionary<string, object?>? GetMeta(ResourceType resourceType, IIdentifiable resourceInstance)
{
return null;
}

public Task OnPrepareWriteAsync<TResource>(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task<IIdentifiable?> OnSetToOneRelationshipAsync<TResource>(TResource leftResource, HasOneAttribute hasOneRelationship,
IIdentifiable? rightResourceId, WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.FromResult(rightResourceId);
}

public Task OnSetToManyRelationshipAsync<TResource>(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds,
WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task OnAddToRelationshipAsync<TResource>(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task OnRemoveFromRelationshipAsync<TResource>(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task OnWritingAsync<TResource>(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task OnWriteSucceededAsync<TResource>(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public void OnDeserialize(IIdentifiable resource)
{
}

public void OnSerialize(IIdentifiable resource)
{
}
}

private sealed class FakeLinkBuilder : ILinkBuilder
{
public TopLevelLinks GetTopLevelLinks()
{
return new TopLevelLinks
{
Self = "TopLevel:Self"
};
}

public ResourceLinks GetResourceLinks(ResourceType resourceType, IIdentifiable resource)
{
return new ResourceLinks
{
Self = "Resource:Self"
};
}

public RelationshipLinks GetRelationshipLinks(RelationshipAttribute relationship, IIdentifiable leftResource)
{
return new RelationshipLinks
{
Self = "Relationship:Self",
Related = "Relationship:Related"
};
}
}

private sealed class FakeMetaBuilder : IMetaBuilder
{
public void Add(IDictionary<string, object?> values)
{
}

public IDictionary<string, object?>? Build()
{
return null;
}
}

private sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor
{
public IQueryCollection Query { get; } = new QueryCollection(0);
}
}
39 changes: 39 additions & 0 deletions benchmarks/Tools/FakeLinkBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCore.Resources.Annotations;
using JsonApiDotNetCore.Serialization.Objects;
using JsonApiDotNetCore.Serialization.Response;
using Microsoft.AspNetCore.Http;

namespace Benchmarks.Tools;

/// <summary>
/// Renders hard-coded fake links, without depending on <see cref="HttpContext" />.
/// </summary>
internal sealed class FakeLinkBuilder : ILinkBuilder
{
public TopLevelLinks GetTopLevelLinks()
{
return new TopLevelLinks
{
Self = "TopLevel:Self"
};
}

public ResourceLinks GetResourceLinks(ResourceType resourceType, IIdentifiable resource)
{
return new ResourceLinks
{
Self = "Resource:Self"
};
}

public RelationshipLinks GetRelationshipLinks(RelationshipAttribute relationship, IIdentifiable leftResource)
{
return new RelationshipLinks
{
Self = "Relationship:Self",
Related = "Relationship:Related"
};
}
}
18 changes: 18 additions & 0 deletions benchmarks/Tools/FakeRequestQueryStringAccessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using JsonApiDotNetCore.QueryStrings;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;

namespace Benchmarks.Tools;

/// <summary>
/// Enables to inject a query string, instead of obtaining it from <see cref="HttpContext" />.
/// </summary>
internal sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor
{
public IQueryCollection Query { get; private set; } = new QueryCollection();

public void SetQueryString(string queryString)
{
Query = new QueryCollection(QueryHelpers.ParseQuery(queryString));
}
}

0 comments on commit 3069341

Please sign in to comment.