Browse Source

More optimizations.

pull/335/head
Sebastian Stehle 7 years ago
parent
commit
ac1ccac34c
  1. 20
      src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonReader.cs
  2. 5
      src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs
  3. 35
      src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs
  4. 6
      src/Squidex.Infrastructure/Json/Newtonsoft/EnvelopeHeadersConverter.cs
  5. 17
      src/Squidex.Infrastructure/Json/Newtonsoft/ISupportedTypes.cs
  6. 10
      src/Squidex.Infrastructure/Json/Newtonsoft/InstantConverter.cs
  7. 16
      src/Squidex.Infrastructure/Json/Newtonsoft/JsonClassConverter.cs
  8. 21
      src/Squidex.Infrastructure/Json/Newtonsoft/JsonValueConverter.cs
  9. 28
      src/Squidex.Infrastructure/Log/JsonLogWriter.cs
  10. 4
      src/Squidex/Config/Domain/SerializationServices.cs
  11. 1
      src/Squidex/Squidex.csproj

20
src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonReader.cs

@ -37,16 +37,6 @@ namespace Squidex.Infrastructure.MongoDb
{ {
SetToken(NewtonsoftJsonToken.PropertyName, bsonReader.ReadName().UnescapeBson()); SetToken(NewtonsoftJsonToken.PropertyName, bsonReader.ReadName().UnescapeBson());
} }
else if (bsonReader.State == BsonReaderState.EndOfDocument)
{
SetToken(NewtonsoftJsonToken.EndObject);
bsonReader.ReadEndDocument();
}
else if (bsonReader.State == BsonReaderState.EndOfArray)
{
SetToken(NewtonsoftJsonToken.EndArray);
bsonReader.ReadEndArray();
}
else if (bsonReader.State == BsonReaderState.Value) else if (bsonReader.State == BsonReaderState.Value)
{ {
switch (bsonReader.CurrentBsonType) switch (bsonReader.CurrentBsonType)
@ -95,6 +85,16 @@ namespace Squidex.Infrastructure.MongoDb
throw new NotSupportedException(); throw new NotSupportedException();
} }
} }
else if (bsonReader.State == BsonReaderState.EndOfDocument)
{
SetToken(NewtonsoftJsonToken.EndObject);
bsonReader.ReadEndDocument();
}
else if (bsonReader.State == BsonReaderState.EndOfArray)
{
SetToken(NewtonsoftJsonToken.EndArray);
bsonReader.ReadEndArray();
}
if (bsonReader.State == BsonReaderState.Initial) if (bsonReader.State == BsonReaderState.Initial)
{ {

5
src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs

@ -101,10 +101,7 @@ namespace Squidex.Infrastructure.MongoDb
{ {
var update = updater(Builders<T>.Update.Set(x => x.Version, newVersion)); var update = updater(Builders<T>.Update.Set(x => x.Version, newVersion));
await collection.UpdateOneAsync(x => x.Id.Equals(key) && x.Version == oldVersion, await collection.UpdateOneAsync(x => x.Id.Equals(key) && x.Version == oldVersion, update, Upsert);
update
.Set(x => x.Version, newVersion),
Upsert);
} }
catch (MongoWriteException ex) catch (MongoWriteException ex)
{ {

35
src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
@ -14,10 +15,23 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
public sealed class ConverterContractResolver : CamelCasePropertyNamesContractResolver public sealed class ConverterContractResolver : CamelCasePropertyNamesContractResolver
{ {
private readonly JsonConverter[] converters; private readonly JsonConverter[] converters;
private readonly object lockObject = new object();
private Dictionary<Type, JsonConverter> converterCache = new Dictionary<Type, JsonConverter>();
public ConverterContractResolver(params JsonConverter[] converters) public ConverterContractResolver(params JsonConverter[] converters)
{ {
this.converters = converters; this.converters = converters;
foreach (var converter in converters)
{
if (converter is ISupportedTypes supportedTypes)
{
foreach (var type in supportedTypes.SupportedTypes)
{
converterCache[type] = converter;
}
}
}
} }
protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
@ -38,15 +52,32 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
return result; return result;
} }
var cache = converterCache;
if (cache == null || !cache.TryGetValue(objectType, out result))
{
foreach (var converter in converters) foreach (var converter in converters)
{ {
if (converter.CanConvert(objectType)) if (converter.CanConvert(objectType))
{ {
return converter; result = converter;
}
}
lock (lockObject)
{
cache = converterCache;
var updatedCache = (cache != null)
? new Dictionary<Type, JsonConverter>(cache)
: new Dictionary<Type, JsonConverter>();
updatedCache[objectType] = result;
converterCache = updatedCache;
} }
} }
return null; return result;
} }
} }
} }

6
src/Squidex.Infrastructure/Json/Newtonsoft/EnvelopeHeadersConverter.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json.Objects; using Squidex.Infrastructure.Json.Objects;
@ -14,6 +15,11 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class EnvelopeHeadersConverter : JsonValueConverter public sealed class EnvelopeHeadersConverter : JsonValueConverter
{ {
public override IEnumerable<Type> SupportedTypes
{
get { yield return typeof(EnvelopeHeaders); }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{ {
var result = base.ReadJson(reader, objectType, existingValue, serializer); var result = base.ReadJson(reader, objectType, existingValue, serializer);

17
src/Squidex.Infrastructure/Json/Newtonsoft/ISupportedTypes.cs

@ -0,0 +1,17 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
namespace Squidex.Infrastructure.Json.Newtonsoft
{
public interface ISupportedTypes
{
IEnumerable<Type> SupportedTypes { get; }
}
}

10
src/Squidex.Infrastructure/Json/Newtonsoft/InstantConverter.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using NodaTime; using NodaTime;
using NodaTime.Text; using NodaTime.Text;
@ -14,6 +15,15 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class InstantConverter : JsonConverter public sealed class InstantConverter : JsonConverter
{ {
public IEnumerable<Type> SupportedTypes
{
get
{
yield return typeof(Instant);
yield return typeof(Instant?);
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{ {
if (value != null) if (value != null)

16
src/Squidex.Infrastructure/Json/Newtonsoft/JsonClassConverter.cs

@ -6,12 +6,18 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Squidex.Infrastructure.Json.Newtonsoft namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public abstract class JsonClassConverter<T> : JsonConverter where T : class public abstract class JsonClassConverter<T> : JsonConverter, ISupportedTypes where T : class
{ {
public IEnumerable<Type> SupportedTypes
{
get { yield return typeof(T); }
}
public sealed override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) public sealed override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{ {
if (reader.TokenType == JsonToken.Null) if (reader.TokenType == JsonToken.Null)
@ -22,6 +28,8 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
return ReadValue(reader, objectType, serializer); return ReadValue(reader, objectType, serializer);
} }
protected abstract T ReadValue(JsonReader reader, Type objectType, JsonSerializer serializer);
public sealed override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) public sealed override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{ {
if (value == null) if (value == null)
@ -33,13 +41,11 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
WriteValue(writer, (T)value, serializer); WriteValue(writer, (T)value, serializer);
} }
protected abstract void WriteValue(JsonWriter writer, T value, JsonSerializer serializer);
public override bool CanConvert(Type objectType) public override bool CanConvert(Type objectType)
{ {
return objectType == typeof(T); return objectType == typeof(T);
} }
protected abstract void WriteValue(JsonWriter writer, T value, JsonSerializer serializer);
protected abstract T ReadValue(JsonReader reader, Type objectType, JsonSerializer serializer);
} }
} }

21
src/Squidex.Infrastructure/Json/Newtonsoft/JsonValueConverter.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.Json.Objects; using Squidex.Infrastructure.Json.Objects;
@ -14,8 +15,24 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Infrastructure.Json.Newtonsoft namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public class JsonValueConverter : JsonConverter public class JsonValueConverter : JsonConverter, ISupportedTypes
{ {
private readonly HashSet<Type> supportedTypes = new HashSet<Type>
{
typeof(IJsonValue),
typeof(JsonArray),
typeof(JsonBoolean),
typeof(JsonNull),
typeof(JsonNumber),
typeof(JsonObject),
typeof(JsonString)
};
public virtual IEnumerable<Type> SupportedTypes
{
get { return supportedTypes; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{ {
return ReadJson(reader); return ReadJson(reader);
@ -161,7 +178,7 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
public override bool CanConvert(Type objectType) public override bool CanConvert(Type objectType)
{ {
return typeof(IJsonValue).IsAssignableFrom(objectType); return supportedTypes.Contains(objectType);
} }
} }
} }

28
src/Squidex.Infrastructure/Log/JsonLogWriter.cs

@ -96,7 +96,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteProperty(string property, string value) IObjectWriter IObjectWriter.WriteProperty(string property, string value)
{ {
jsonWriter.WritePropertyName(property.ToCamelCase()); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteValue(value); jsonWriter.WriteValue(value);
return this; return this;
@ -104,7 +104,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteProperty(string property, double value) IObjectWriter IObjectWriter.WriteProperty(string property, double value)
{ {
jsonWriter.WritePropertyName(property.ToCamelCase()); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteValue(value); jsonWriter.WriteValue(value);
return this; return this;
@ -112,7 +112,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteProperty(string property, long value) IObjectWriter IObjectWriter.WriteProperty(string property, long value)
{ {
jsonWriter.WritePropertyName(property.ToCamelCase()); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteValue(value); jsonWriter.WriteValue(value);
return this; return this;
@ -120,7 +120,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteProperty(string property, bool value) IObjectWriter IObjectWriter.WriteProperty(string property, bool value)
{ {
jsonWriter.WritePropertyName(property.ToCamelCase()); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteValue(value); jsonWriter.WriteValue(value);
return this; return this;
@ -128,7 +128,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteProperty(string property, DateTime value) IObjectWriter IObjectWriter.WriteProperty(string property, DateTime value)
{ {
jsonWriter.WritePropertyName(property.ToCamelCase()); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteValue(value.ToString("o", CultureInfo.InvariantCulture)); jsonWriter.WriteValue(value.ToString("o", CultureInfo.InvariantCulture));
return this; return this;
@ -136,7 +136,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteProperty(string property, DateTimeOffset value) IObjectWriter IObjectWriter.WriteProperty(string property, DateTimeOffset value)
{ {
jsonWriter.WritePropertyName(property.ToCamelCase()); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteValue(value.ToString("o", CultureInfo.InvariantCulture)); jsonWriter.WriteValue(value.ToString("o", CultureInfo.InvariantCulture));
return this; return this;
@ -144,7 +144,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteProperty(string property, TimeSpan value) IObjectWriter IObjectWriter.WriteProperty(string property, TimeSpan value)
{ {
jsonWriter.WritePropertyName(property.ToCamelCase()); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteValue(value); jsonWriter.WriteValue(value);
return this; return this;
@ -152,7 +152,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteObject(string property, Action<IObjectWriter> objectWriter) IObjectWriter IObjectWriter.WriteObject(string property, Action<IObjectWriter> objectWriter)
{ {
jsonWriter.WritePropertyName(property); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteStartObject(); jsonWriter.WriteStartObject();
objectWriter?.Invoke(this); objectWriter?.Invoke(this);
@ -164,7 +164,7 @@ namespace Squidex.Infrastructure.Log
IObjectWriter IObjectWriter.WriteArray(string property, Action<IArrayWriter> arrayWriter) IObjectWriter IObjectWriter.WriteArray(string property, Action<IArrayWriter> arrayWriter)
{ {
jsonWriter.WritePropertyName(property.ToCamelCase()); jsonWriter.WritePropertyName(Format(property));
jsonWriter.WriteStartArray(); jsonWriter.WriteStartArray();
arrayWriter?.Invoke(this); arrayWriter?.Invoke(this);
@ -185,6 +185,16 @@ namespace Squidex.Infrastructure.Log
return this; return this;
} }
private static string Format(string property)
{
if (ReferenceEquals(string.IsInterned(property), property))
{
return property;
}
return property.ToCamelCase();
}
public override string ToString() public override string ToString()
{ {
jsonWriter.WriteEndObject(); jsonWriter.WriteEndObject();

4
src/Squidex/Config/Domain/SerializationServices.cs

@ -9,8 +9,6 @@ using Microsoft.Extensions.DependencyInjection;
using Migrate_01; using Migrate_01;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using NodaTime;
using NodaTime.Serialization.JsonNet;
using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Core.Apps.Json; using Squidex.Domain.Apps.Core.Apps.Json;
using Squidex.Domain.Apps.Core.Rules.Json; using Squidex.Domain.Apps.Core.Rules.Json;
@ -68,8 +66,6 @@ namespace Squidex.Config.Domain
settings.DateParseHandling = DateParseHandling.None; settings.DateParseHandling = DateParseHandling.None;
settings.TypeNameHandling = typeNameHandling; settings.TypeNameHandling = typeNameHandling;
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
} }
static SerializationServices() static SerializationServices()

1
src/Squidex/Squidex.csproj

@ -80,7 +80,6 @@
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="2.1.2" /> <PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="2.1.2" />
<PackageReference Include="MongoDB.Driver" Version="2.7.2" /> <PackageReference Include="MongoDB.Driver" Version="2.7.2" />
<PackageReference Include="NJsonSchema" Version="9.12.2" /> <PackageReference Include="NJsonSchema" Version="9.12.2" />
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="2.0.0" />
<PackageReference Include="NSwag.AspNetCore" Version="11.20.1" /> <PackageReference Include="NSwag.AspNetCore" Version="11.20.1" />
<PackageReference Include="OpenCover" Version="4.6.519" /> <PackageReference Include="OpenCover" Version="4.6.519" />
<PackageReference Include="Orleans.Providers.MongoDB" Version="2.0.1" /> <PackageReference Include="Orleans.Providers.MongoDB" Version="2.0.1" />

Loading…
Cancel
Save