Browse Source

Optimize memory usage by copying same field values to new data and fix parsing error with geojson.

pull/786/head
Sebastian 4 years ago
parent
commit
acb2ca2779
  1. 63
      backend/src/Squidex.Domain.Apps.Core.Model/Contents/ContentData.cs
  2. 4
      backend/src/Squidex.Domain.Apps.Core.Model/Contents/GeoJsonValue.cs
  3. 17
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs
  4. 6
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs
  5. 10
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.State.cs
  6. 50
      backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/ContentDataTests.cs

63
backend/src/Squidex.Domain.Apps.Core.Model/Contents/ContentData.cs

@ -38,6 +38,49 @@ namespace Squidex.Domain.Apps.Core.Contents
return this;
}
public ContentData UseSameFields(ContentData? other)
{
if (other == null || other.Count == 0)
{
return this;
}
foreach (var (fieldName, fieldData) in this.ToList())
{
if (fieldData == null)
{
continue;
}
if (!other.TryGetValue(fieldName, out var otherField) || otherField == null)
{
continue;
}
if (otherField.Equals(fieldData))
{
this[fieldName] = otherField;
}
else
{
foreach (var (language, value) in fieldData.ToList())
{
if (!otherField.TryGetValue(language, out var otherValue) || otherValue == null)
{
continue;
}
if (otherValue.Equals(value))
{
fieldData[language] = otherValue;
}
}
}
}
return this;
}
private static ContentData MergeTo(ContentData target, params ContentData[] sources)
{
Guard.NotEmpty(sources, nameof(sources));
@ -49,19 +92,23 @@ namespace Squidex.Domain.Apps.Core.Contents
foreach (var source in sources)
{
foreach (var (key, contentFieldData) in source)
foreach (var (fieldName, sourceFieldData) in source)
{
if (contentFieldData != null)
if (sourceFieldData == null)
{
var fieldValue = target.GetOrAdd(key, _ => new ContentFieldData());
continue;
}
if (fieldValue != null)
{
foreach (var (fieldName, value) in contentFieldData)
var targetFieldData = target.GetOrAdd(fieldName, _ => new ContentFieldData());
if (targetFieldData == null)
{
fieldValue[fieldName] = value;
}
continue;
}
foreach (var (partition, value) in sourceFieldData)
{
targetFieldData[partition] = value;
}
}
}

4
backend/src/Squidex.Domain.Apps.Core.Model/Contents/GeoJsonValue.cs

@ -22,7 +22,7 @@ namespace Squidex.Domain.Apps.Core.Contents
Guard.NotNull(serializer, nameof(serializer));
Guard.NotNull(value, nameof(value));
geoJSON = null!;
geoJSON = null;
if (value is JsonObject obj)
{
@ -42,6 +42,8 @@ namespace Squidex.Domain.Apps.Core.Contents
}
geoJSON = new Point(new Position(lat.Value, lon.Value));
return GeoJsonParseResult.Success;
}
return GeoJsonParseResult.InvalidValue;

17
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs

@ -19,14 +19,19 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
var result = new ContentData(content.Count);
foreach (var (fieldName, data) in content)
if (converters == null || converters.Length == 0)
{
if (data == null || !schema.FieldsByName.TryGetValue(fieldName, out var field))
return result;
}
foreach (var (fieldName, fieldData) in content)
{
if (fieldData == null || !schema.FieldsByName.TryGetValue(fieldName, out var field))
{
continue;
}
ContentFieldData? newData = data;
ContentFieldData? newData = fieldData;
if (newData != null)
{
@ -44,8 +49,11 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
private static ContentFieldData? ConvertData(IRootField field, ContentFieldData data, FieldConverter[] converters)
{
if (converters != null)
if (converters == null || converters.Length == 0)
{
return data;
}
for (var i = 0; i < converters.Length; i++)
{
data = converters[i](data!, field)!;
@ -55,7 +63,6 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
break;
}
}
}
return data;
}

6
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs

@ -119,8 +119,11 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
{
foreach (var languageCode in languages.AllKeys)
{
if (!data.TryGetNonNull(languageCode, out _))
if (data.TryGetNonNull(languageCode, out _))
{
continue;
}
foreach (var fallback in languages.GetPriorities(languageCode))
{
if (data.TryGetNonNull(fallback, out var value))
@ -131,7 +134,6 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
}
}
}
}
return data;
};

10
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.State.cs

@ -71,7 +71,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
case ContentDraftCreated e:
{
NewVersion = new ContentVersion(e.Status, e.MigratedData ?? CurrentVersion.Data);
var newData = e.MigratedData?.UseSameFields(Data) ?? CurrentVersion.Data;
NewVersion = new ContentVersion(e.Status, newData);
ScheduleJob = null;
@ -95,7 +97,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
if (e.Status == Status.Published)
{
CurrentVersion = new ContentVersion(e.Status, NewVersion.Data);
CurrentVersion = new ContentVersion(e.Status, NewVersion.Data.UseSameFields(Data));
NewVersion = null;
}
@ -130,11 +132,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
if (NewVersion != null)
{
NewVersion = NewVersion.WithData(e.Data);
NewVersion = NewVersion.WithData(e.Data.UseSameFields(Data));
}
else
{
CurrentVersion = CurrentVersion.WithData(e.Data);
CurrentVersion = CurrentVersion.WithData(e.Data.UseSameFields(Data));
}
break;

50
backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/ContentDataTests.cs

@ -159,5 +159,55 @@ namespace Squidex.Domain.Apps.Core.Model.Contents
Assert.NotSame(value, source[key]);
}
}
[Fact]
public void Should_copy_fields_from_other_data_if_they_are_equal()
{
var oldData =
new ContentData()
.AddField("field1",
new ContentFieldData()
.AddInvariant(1))
.AddField("field2",
new ContentFieldData()
.AddInvariant(2));
var newData =
new ContentData()
.AddField("field1",
new ContentFieldData()
.AddInvariant(1))
.AddField("field2",
new ContentFieldData()
.AddInvariant(3));
newData.UseSameFields(oldData);
Assert.Same(newData["field1"], oldData["field1"]);
Assert.NotSame(newData["field2"], oldData["field2"]);
}
[Fact]
public void Should_copy_field_values_from_other_data_if_they_are_equal()
{
var oldData =
new ContentData()
.AddField("field1",
new ContentFieldData()
.AddLocalized("en", 1)
.AddLocalized("de", 2));
var newData =
new ContentData()
.AddField("field1",
new ContentFieldData()
.AddLocalized("en", 1)
.AddLocalized("de", 3));
newData.UseSameFields(oldData);
Assert.Same(newData["field1"]!["en"], oldData["field1"]!["en"]);
Assert.NotSame(newData["field1"]!["de"], oldData["field1"]!["de"]);
Assert.NotSame(newData["field1"], oldData["field1"]);
}
}
}

Loading…
Cancel
Save