diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs
index 0f660181fb..f4fae44ffc 100644
--- a/src/Umbraco.Core/Models/IContentBase.cs
+++ b/src/Umbraco.Core/Models/IContentBase.cs
@@ -4,6 +4,7 @@ using Umbraco.Core.Models.Entities;
namespace Umbraco.Core.Models
{
+
///
/// Provides a base class for content items.
///
diff --git a/src/Umbraco.Core/Models/IReadOnlyContentBase.cs b/src/Umbraco.Core/Models/IReadOnlyContentBase.cs
new file mode 100644
index 0000000000..3ed39b63ab
--- /dev/null
+++ b/src/Umbraco.Core/Models/IReadOnlyContentBase.cs
@@ -0,0 +1,72 @@
+using System;
+
+namespace Umbraco.Core.Models
+{
+ public interface IReadOnlyContentBase
+ {
+ ///
+ /// Gets the integer identifier of the entity.
+ ///
+ int Id { get; }
+
+ ///
+ /// Gets the Guid unique identifier of the entity.
+ ///
+ Guid Key { get; }
+
+ ///
+ /// Gets the creation date.
+ ///
+ DateTime CreateDate { get; }
+
+ ///
+ /// Gets the last update date.
+ ///
+ DateTime UpdateDate { get; }
+
+ ///
+ /// Gets the name of the entity.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the identifier of the user who created this entity.
+ ///
+ int CreatorId { get; }
+
+ ///
+ /// Gets the identifier of the parent entity.
+ ///
+ int ParentId { get; }
+
+ ///
+ /// Gets the level of the entity.
+ ///
+ int Level { get; }
+
+ ///
+ /// Gets the path to the entity.
+ ///
+ string Path { get; }
+
+ ///
+ /// Gets the sort order of the entity.
+ ///
+ int SortOrder { get; }
+
+ ///
+ /// Gets the content type id
+ ///
+ int ContentTypeId { get; }
+
+ ///
+ /// Gets the identifier of the writer.
+ ///
+ int WriterId { get; }
+
+ ///
+ /// Gets the version identifier.
+ ///
+ int VersionId { get; }
+ }
+}
diff --git a/src/Umbraco.Core/Models/ReadOnlyContentBaseAdapter.cs b/src/Umbraco.Core/Models/ReadOnlyContentBaseAdapter.cs
new file mode 100644
index 0000000000..f707d2ab1c
--- /dev/null
+++ b/src/Umbraco.Core/Models/ReadOnlyContentBaseAdapter.cs
@@ -0,0 +1,42 @@
+using System;
+
+namespace Umbraco.Core.Models
+{
+ internal struct ReadOnlyContentBaseAdapter : IReadOnlyContentBase
+ {
+ private readonly IContentBase _content;
+
+ private ReadOnlyContentBaseAdapter(IContentBase content)
+ {
+ _content = content ?? throw new ArgumentNullException(nameof(content));
+ }
+
+ public static ReadOnlyContentBaseAdapter Create(IContentBase content) => new ReadOnlyContentBaseAdapter(content);
+
+ public int Id => _content.Id;
+
+ public Guid Key => _content.Key;
+
+ public DateTime CreateDate => _content.CreateDate;
+
+ public DateTime UpdateDate => _content.UpdateDate;
+
+ public string Name => _content.Name;
+
+ public int CreatorId => _content.CreatorId;
+
+ public int ParentId => _content.ParentId;
+
+ public int Level => _content.Level;
+
+ public string Path => _content.Path;
+
+ public int SortOrder => _content.SortOrder;
+
+ public int ContentTypeId => _content.ContentTypeId;
+
+ public int WriterId => _content.WriterId;
+
+ public int VersionId => _content.VersionId;
+ }
+}
diff --git a/src/Umbraco.Core/PropertyEditors/CompressedStorageAttribute.cs b/src/Umbraco.Core/PropertyEditors/CompressedStorageAttribute.cs
deleted file mode 100644
index 31689c4ee9..0000000000
--- a/src/Umbraco.Core/PropertyEditors/CompressedStorageAttribute.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-
-namespace Umbraco.Core.PropertyEditors
-{
- ///
- /// When assigned to a DataEditor it indicates that the values it generates can be compressed
- ///
- ///
- /// Used in conjunction with
- ///
- [AttributeUsage(AttributeTargets.Class)]
- public sealed class CompressedStorageAttribute : Attribute
- {
- public CompressedStorageAttribute(bool isCompressed = true)
- {
- IsCompressed = isCompressed;
- }
-
- public bool IsCompressed { get; }
- }
-}
diff --git a/src/Umbraco.Core/PropertyEditors/CompressedStoragePropertyEditorCompressionOptions.cs b/src/Umbraco.Core/PropertyEditors/CompressedStoragePropertyEditorCompressionOptions.cs
deleted file mode 100644
index a99452a5b1..0000000000
--- a/src/Umbraco.Core/PropertyEditors/CompressedStoragePropertyEditorCompressionOptions.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using Umbraco.Core.Models;
-
-namespace Umbraco.Core.PropertyEditors
-{
-
- ///
- /// Ensures all property types that have a property editor attributed with use data compression
- ///
- internal class CompressedStoragePropertyEditorCompressionOptions : IPropertyCompressionOptions
- {
- private readonly IReadOnlyDictionary _contentTypes;
- private readonly PropertyEditorCollection _propertyEditors;
- private readonly ConcurrentDictionary<(int, string), CompressedStorageAttribute> _compressedStoragePropertyEditorCache;
-
- public CompressedStoragePropertyEditorCompressionOptions(
- IReadOnlyDictionary contentTypes,
- PropertyEditorCollection propertyEditors,
- ConcurrentDictionary<(int, string), CompressedStorageAttribute> compressedStoragePropertyEditorCache)
- {
- _contentTypes = contentTypes ?? throw new System.ArgumentNullException(nameof(contentTypes));
- _propertyEditors = propertyEditors ?? throw new System.ArgumentNullException(nameof(propertyEditors));
- _compressedStoragePropertyEditorCache = compressedStoragePropertyEditorCache;
- }
-
- public bool IsCompressed(int contentTypeId, string alias)
- {
- var compressedStorage = _compressedStoragePropertyEditorCache.GetOrAdd((contentTypeId, alias), x =>
- {
- if (!_contentTypes.TryGetValue(contentTypeId, out var ct))
- return null;
-
- var propertyType = ct.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == alias);
- if (propertyType == null) return null;
-
- if (!_propertyEditors.TryGet(propertyType.PropertyEditorAlias, out var propertyEditor)) return null;
-
- var attribute = propertyEditor.GetType().GetCustomAttribute(true);
- return attribute;
- });
-
- return compressedStorage?.IsCompressed ?? false;
- }
- }
-}
diff --git a/src/Umbraco.Core/PropertyEditors/IPropertyCompressionOptions.cs b/src/Umbraco.Core/PropertyEditors/IPropertyCacheCompression.cs
similarity index 50%
rename from src/Umbraco.Core/PropertyEditors/IPropertyCompressionOptions.cs
rename to src/Umbraco.Core/PropertyEditors/IPropertyCacheCompression.cs
index d1add38f19..96a559630b 100644
--- a/src/Umbraco.Core/PropertyEditors/IPropertyCompressionOptions.cs
+++ b/src/Umbraco.Core/PropertyEditors/IPropertyCacheCompression.cs
@@ -3,10 +3,13 @@
namespace Umbraco.Core.PropertyEditors
{
///
- /// Determines if a property type's value should be compressed
+ /// Determines if a property type's value should be compressed in memory
///
- public interface IPropertyCompressionOptions
+ ///
+ ///
+ ///
+ public interface IPropertyCacheCompression
{
- bool IsCompressed(int contentTypeId, string propertyTypeAlias);
+ bool IsCompressed(IReadOnlyContentBase content, string propertyTypeAlias);
}
}
diff --git a/src/Umbraco.Core/PropertyEditors/IPropertyCacheCompressionOptions.cs b/src/Umbraco.Core/PropertyEditors/IPropertyCacheCompressionOptions.cs
new file mode 100644
index 0000000000..2fa0153f9e
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/IPropertyCacheCompressionOptions.cs
@@ -0,0 +1,9 @@
+using Umbraco.Core.Models;
+
+namespace Umbraco.Core.PropertyEditors
+{
+ public interface IPropertyCacheCompressionOptions
+ {
+ bool IsCompressed(IReadOnlyContentBase content, PropertyType propertyType, IDataEditor dataEditor);
+ }
+}
diff --git a/src/Umbraco.Core/PropertyEditors/NoopPropertyCacheCompressionOptions.cs b/src/Umbraco.Core/PropertyEditors/NoopPropertyCacheCompressionOptions.cs
new file mode 100644
index 0000000000..1f12d45769
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/NoopPropertyCacheCompressionOptions.cs
@@ -0,0 +1,12 @@
+using Umbraco.Core.Models;
+
+namespace Umbraco.Core.PropertyEditors
+{
+ ///
+ /// Default implementation for which does not compress any property data
+ ///
+ internal class NoopPropertyCacheCompressionOptions : IPropertyCacheCompressionOptions
+ {
+ public bool IsCompressed(IReadOnlyContentBase content, PropertyType propertyType, IDataEditor dataEditor) => false;
+ }
+}
diff --git a/src/Umbraco.Core/PropertyEditors/PropertyCacheCompression.cs b/src/Umbraco.Core/PropertyEditors/PropertyCacheCompression.cs
new file mode 100644
index 0000000000..6be21fca7f
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/PropertyCacheCompression.cs
@@ -0,0 +1,49 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.Models;
+
+namespace Umbraco.Core.PropertyEditors
+{
+
+ ///
+ /// Compresses property data based on config
+ ///
+ internal class PropertyCacheCompression : IPropertyCacheCompression
+ {
+ private readonly IPropertyCacheCompressionOptions _compressionOptions;
+ private readonly IReadOnlyDictionary _contentTypes;
+ private readonly PropertyEditorCollection _propertyEditors;
+ private readonly ConcurrentDictionary<(int contentTypeId, string propertyAlias), bool> _isCompressedCache;
+
+ public PropertyCacheCompression(
+ IPropertyCacheCompressionOptions compressionOptions,
+ IReadOnlyDictionary contentTypes,
+ PropertyEditorCollection propertyEditors,
+ ConcurrentDictionary<(int, string), bool> compressedStoragePropertyEditorCache)
+ {
+ _compressionOptions = compressionOptions;
+ _contentTypes = contentTypes ?? throw new System.ArgumentNullException(nameof(contentTypes));
+ _propertyEditors = propertyEditors ?? throw new System.ArgumentNullException(nameof(propertyEditors));
+ _isCompressedCache = compressedStoragePropertyEditorCache;
+ }
+
+ public bool IsCompressed(IReadOnlyContentBase content, string alias)
+ {
+ var compressedStorage = _isCompressedCache.GetOrAdd((content.ContentTypeId, alias), x =>
+ {
+ if (!_contentTypes.TryGetValue(x.contentTypeId, out var ct))
+ return false;
+
+ var propertyType = ct.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == alias);
+ if (propertyType == null) return false;
+
+ if (!_propertyEditors.TryGet(propertyType.PropertyEditorAlias, out var propertyEditor)) return false;
+
+ return _compressionOptions.IsCompressed(content, propertyType, propertyEditor);
+ });
+
+ return compressedStorage;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 6c473235a7..a146d5cc4a 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -152,14 +152,17 @@
+
+
-
-
-
+
+
+
+
diff --git a/src/Umbraco.Tests/PublishedContent/ContentSerializationTests.cs b/src/Umbraco.Tests/PublishedContent/ContentSerializationTests.cs
index 4be80083b8..b3543dad1a 100644
--- a/src/Umbraco.Tests/PublishedContent/ContentSerializationTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/ContentSerializationTests.cs
@@ -2,6 +2,7 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
+using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web.PublishedCache.NuCache.DataSource;
@@ -11,13 +12,13 @@ namespace Umbraco.Tests.PublishedContent
public class ContentSerializationTests
{
[Test]
- public void Ensure_Same_Results()
+ public void GivenACacheModel_WhenItsSerializedAndDeserializedWithAnySerializer_TheResultsAreTheSame()
{
var jsonSerializer = new JsonContentNestedDataSerializer();
- var msgPackSerializer = new MsgPackContentNestedDataSerializer(Mock.Of());
+ var msgPackSerializer = new MsgPackContentNestedDataSerializer(Mock.Of());
var now = DateTime.Now;
- var content = new ContentCacheDataModel
+ var cacheModel = new ContentCacheDataModel
{
PropertyData = new Dictionary
{
@@ -53,14 +54,16 @@ namespace Umbraco.Tests.PublishedContent
UrlSegment = "home"
};
- var json = jsonSerializer.Serialize(1, content).StringData;
- var msgPack = msgPackSerializer.Serialize(1, content).ByteData;
+ var content = Mock.Of(x => x.ContentTypeId == 1);
+
+ var json = jsonSerializer.Serialize(content, cacheModel).StringData;
+ var msgPack = msgPackSerializer.Serialize(content, cacheModel).ByteData;
Console.WriteLine(json);
Console.WriteLine(msgPackSerializer.ToJson(msgPack));
- var jsonContent = jsonSerializer.Deserialize(1, json, null);
- var msgPackContent = msgPackSerializer.Deserialize(1, null, msgPack);
+ var jsonContent = jsonSerializer.Deserialize(content, json, null);
+ var msgPackContent = msgPackSerializer.Deserialize(content, null, msgPack);
CollectionAssert.AreEqual(jsonContent.CultureData.Keys, msgPackContent.CultureData.Keys);
diff --git a/src/Umbraco.Web/PropertyEditors/BlockListPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/BlockListPropertyEditor.cs
index 2c1221e99e..42023382f1 100644
--- a/src/Umbraco.Web/PropertyEditors/BlockListPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/BlockListPropertyEditor.cs
@@ -13,7 +13,6 @@ namespace Umbraco.Web.PropertyEditors
///
/// Represents a block list property editor.
///
- [CompressedStorage]
[DataEditor(
Constants.PropertyEditors.Aliases.BlockList,
"Block List",
diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
index 7ce312c516..862837381a 100644
--- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
@@ -17,7 +17,6 @@ namespace Umbraco.Web.PropertyEditors
///
/// Represents a grid property and parameter editor.
///
- [CompressedStorage]
[DataEditor(
Constants.PropertyEditors.Aliases.Grid,
"Grid layout",
diff --git a/src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs
index 6ce66aaa00..2d66da5461 100644
--- a/src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs
@@ -7,7 +7,6 @@ namespace Umbraco.Web.PropertyEditors
///
/// Represents a markdown editor.
///
- [CompressedStorage]
[DataEditor(
Constants.PropertyEditors.Aliases.MarkdownEditor,
"Markdown editor",
diff --git a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs
index 0e1cea3399..ca3c5a2a04 100644
--- a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs
@@ -22,7 +22,6 @@ namespace Umbraco.Web.PropertyEditors
///
/// Represents a nested content property editor.
///
- [CompressedStorage]
[DataEditor(
Constants.PropertyEditors.Aliases.NestedContent,
"Nested Content",
diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
index 7c7a358bf3..42777f11ad 100644
--- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
@@ -17,7 +17,6 @@ namespace Umbraco.Web.PropertyEditors
///
/// Represents a rich text property editor.
///
- [CompressedStorage]
[DataEditor(
Constants.PropertyEditors.Aliases.TinyMce,
"Rich Text Editor",
diff --git a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs
index 878330820a..c7bc2efbda 100644
--- a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs
@@ -7,7 +7,6 @@ namespace Umbraco.Web.PropertyEditors
///
/// Represents a textarea property and parameter editor.
///
- [CompressedStorage]
[DataEditor(
Constants.PropertyEditors.Aliases.TextArea,
EditorType.PropertyValue | EditorType.MacroParameter,
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentSourceDto.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentSourceDto.cs
index be2f9921d1..343885b037 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentSourceDto.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentSourceDto.cs
@@ -1,12 +1,13 @@
using System;
+using Umbraco.Core.Models;
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
{
// read-only dto
- internal class ContentSourceDto
+ internal class ContentSourceDto : IReadOnlyContentBase
{
public int Id { get; set; }
- public Guid Uid { get; set; }
+ public Guid Key { get; set; }
public int ContentTypeId { get; set; }
public int Level { get; set; }
@@ -37,5 +38,10 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
public int PubTemplateId { get; set; }
public string PubData { get; set; }
public byte[] PubDataRaw { get; set; }
+
+ // Explicit implementation
+ DateTime IReadOnlyContentBase.UpdateDate => EditVersionDate;
+ string IReadOnlyContentBase.Name => EditName;
+ int IReadOnlyContentBase.WriterId => EditWriterId;
}
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs
index 3bd30d2d73..4584344891 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs
@@ -383,7 +383,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
}
else
{
- var deserializedContent = serializer.Deserialize(dto.ContentTypeId, dto.EditData, dto.EditDataRaw);
+ var deserializedContent = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw);
d = new ContentData
{
@@ -410,7 +410,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
}
else
{
- var deserializedContent = serializer.Deserialize(dto.ContentTypeId, dto.PubData, dto.PubDataRaw);
+ var deserializedContent = serializer.Deserialize(dto, dto.PubData, dto.PubDataRaw);
p = new ContentData
{
@@ -427,7 +427,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
}
}
- var n = new ContentNode(dto.Id, dto.Uid,
+ var n = new ContentNode(dto.Id, dto.Key,
dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);
var s = new ContentNodeKit
@@ -446,7 +446,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
if (dto.EditData == null && dto.EditDataRaw == null)
throw new InvalidOperationException("No data for media " + dto.Id);
- var deserializedMedia = serializer.Deserialize(dto.ContentTypeId, dto.EditData, dto.EditDataRaw);
+ var deserializedMedia = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw);
var p = new ContentData
{
@@ -460,7 +460,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
CultureInfos = deserializedMedia.CultureData
};
- var n = new ContentNode(dto.Id, dto.Uid,
+ var n = new ContentNode(dto.Id, dto.Key,
dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);
var s = new ContentNodeKit
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/IContentCacheDataSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/IContentCacheDataSerializer.cs
index f628c8981b..d1a83d8452 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/IContentCacheDataSerializer.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/IContentCacheDataSerializer.cs
@@ -1,4 +1,4 @@
-using Umbraco.Core.PropertyEditors;
+using Umbraco.Core.Models;
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
{
@@ -14,19 +14,12 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
///
/// Deserialize the data into a
///
- ///
- ///
- ///
- ///
- ContentCacheDataModel Deserialize(int contentTypeId, string stringData, byte[] byteData);
+ ContentCacheDataModel Deserialize(IReadOnlyContentBase content, string stringData, byte[] byteData);
///
/// Serializes the
///
- ///
- ///
- ///
- ContentCacheDataSerializationResult Serialize(int contentTypeId, ContentCacheDataModel model);
+ ContentCacheDataSerializationResult Serialize(IReadOnlyContentBase content, ContentCacheDataModel model);
}
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/JsonContentNestedDataSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/JsonContentNestedDataSerializer.cs
index e7bb5656bb..c4d40f721f 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/JsonContentNestedDataSerializer.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/JsonContentNestedDataSerializer.cs
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
+using Umbraco.Core.Models;
using Umbraco.Core.Serialization;
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
@@ -21,7 +22,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
DateFormatString = "o"
};
- public ContentCacheDataModel Deserialize(int contentTypeId, string stringData, byte[] byteData)
+ public ContentCacheDataModel Deserialize(IReadOnlyContentBase content, string stringData, byte[] byteData)
{
if (stringData == null && byteData != null)
throw new NotSupportedException($"{typeof(JsonContentNestedDataSerializer)} does not support byte[] serialization");
@@ -29,7 +30,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
return JsonConvert.DeserializeObject(stringData, _jsonSerializerSettings);
}
- public ContentCacheDataSerializationResult Serialize(int contentTypeId, ContentCacheDataModel model)
+ public ContentCacheDataSerializationResult Serialize(IReadOnlyContentBase content, ContentCacheDataModel model)
{
// note that numeric values (which are Int32) are serialized without their
// type (eg "value":1234) and JsonConvert by default deserializes them as Int64
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MsgPackContentNestedDataSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MsgPackContentNestedDataSerializer.cs
index 6ffa130da0..944d93107d 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MsgPackContentNestedDataSerializer.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MsgPackContentNestedDataSerializer.cs
@@ -4,6 +4,7 @@ using MessagePack.Resolvers;
using System;
using System.Linq;
using System.Text;
+using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
@@ -15,9 +16,9 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
public class MsgPackContentNestedDataSerializer : IContentCacheDataSerializer
{
private readonly MessagePackSerializerOptions _options;
- private readonly IPropertyCompressionOptions _propertyOptions;
+ private readonly IPropertyCacheCompression _propertyOptions;
- public MsgPackContentNestedDataSerializer(IPropertyCompressionOptions propertyOptions)
+ public MsgPackContentNestedDataSerializer(IPropertyCacheCompression propertyOptions)
{
_propertyOptions = propertyOptions ?? throw new ArgumentNullException(nameof(propertyOptions));
@@ -46,21 +47,21 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
return json;
}
- public ContentCacheDataModel Deserialize(int contentTypeId, string stringData, byte[] byteData)
+ public ContentCacheDataModel Deserialize(IReadOnlyContentBase content, string stringData, byte[] byteData)
{
if (byteData != null)
{
- var content = MessagePackSerializer.Deserialize(byteData, _options);
- Expand(contentTypeId, content);
- return content;
+ var cacheModel = MessagePackSerializer.Deserialize(byteData, _options);
+ Expand(content, cacheModel);
+ return cacheModel;
}
else if (stringData != null)
{
// NOTE: We don't really support strings but it's possible if manually used (i.e. tests)
var bin = Convert.FromBase64String(stringData);
- var content = MessagePackSerializer.Deserialize(bin, _options);
- Expand(contentTypeId, content);
- return content;
+ var cacheModel = MessagePackSerializer.Deserialize(bin, _options);
+ Expand(content, cacheModel);
+ return cacheModel;
}
else
{
@@ -68,9 +69,9 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
}
}
- public ContentCacheDataSerializationResult Serialize(int contentTypeId, ContentCacheDataModel model)
+ public ContentCacheDataSerializationResult Serialize(IReadOnlyContentBase content, ContentCacheDataModel model)
{
- Compress(contentTypeId, model);
+ Compress(content, model);
var bytes = MessagePackSerializer.Serialize(model, _options);
return new ContentCacheDataSerializationResult(null, bytes);
}
@@ -86,11 +87,11 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
/// read/decompressed as a string to be displayed on the front-end. This allows for potentially a significant
/// memory savings but could also affect performance of first rendering pages while decompression occurs.
///
- private void Compress(int contentTypeId, ContentCacheDataModel model)
+ private void Compress(IReadOnlyContentBase content, ContentCacheDataModel model)
{
foreach(var propertyAliasToData in model.PropertyData)
{
- if (_propertyOptions.IsCompressed(contentTypeId, propertyAliasToData.Key))
+ if (_propertyOptions.IsCompressed(content, propertyAliasToData.Key))
{
foreach(var property in propertyAliasToData.Value.Where(x => x.Value != null && x.Value is string))
{
@@ -104,11 +105,11 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
/// Used during deserialization to map the property data as lazy or expand the value
///
///
- private void Expand(int contentTypeId, ContentCacheDataModel nestedData)
+ private void Expand(IReadOnlyContentBase content, ContentCacheDataModel nestedData)
{
foreach (var propertyAliasToData in nestedData.PropertyData)
{
- if (_propertyOptions.IsCompressed(contentTypeId, propertyAliasToData.Key))
+ if (_propertyOptions.IsCompressed(content, propertyAliasToData.Key))
{
foreach (var property in propertyAliasToData.Value.Where(x => x.Value != null))
{
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MsgPackContentNestedDataSerializerFactory.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MsgPackContentNestedDataSerializerFactory.cs
index b509334604..fcc3fa2bb8 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MsgPackContentNestedDataSerializerFactory.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/MsgPackContentNestedDataSerializerFactory.cs
@@ -12,14 +12,21 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
private readonly IMediaTypeService _mediaTypeService;
private readonly IMemberTypeService _memberTypeService;
private readonly PropertyEditorCollection _propertyEditors;
- private readonly ConcurrentDictionary<(int, string), CompressedStorageAttribute> _compressedStoragePropertyEditorCache = new ConcurrentDictionary<(int, string), CompressedStorageAttribute>();
+ private readonly IPropertyCacheCompressionOptions _compressionOptions;
+ private readonly ConcurrentDictionary<(int, string), bool> _isCompressedCache = new ConcurrentDictionary<(int, string), bool>();
- public MsgPackContentNestedDataSerializerFactory(IContentTypeService contentTypeService, IMediaTypeService mediaTypeService, IMemberTypeService memberTypeService, PropertyEditorCollection propertyEditors)
+ public MsgPackContentNestedDataSerializerFactory(
+ IContentTypeService contentTypeService,
+ IMediaTypeService mediaTypeService,
+ IMemberTypeService memberTypeService,
+ PropertyEditorCollection propertyEditors,
+ IPropertyCacheCompressionOptions compressionOptions)
{
_contentTypeService = contentTypeService;
_mediaTypeService = mediaTypeService;
_memberTypeService = memberTypeService;
_propertyEditors = propertyEditors;
+ _compressionOptions = compressionOptions;
}
public IContentCacheDataSerializer Create(ContentCacheDataSerializerEntityType types)
@@ -53,8 +60,8 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
}
}
- var options = new CompressedStoragePropertyEditorCompressionOptions(contentTypes, _propertyEditors, _compressedStoragePropertyEditorCache);
- var serializer = new MsgPackContentNestedDataSerializer(options);
+ var compression = new PropertyCacheCompression(_compressionOptions, contentTypes, _propertyEditors, _isCompressedCache);
+ var serializer = new MsgPackContentNestedDataSerializer(compression);
return serializer;
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs b/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs
index faeb4f90b4..98d8b91386 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComposer.cs
@@ -20,9 +20,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
else
{
- composition.RegisterUnique();
+ composition.RegisterUnique();
}
-
+
+ composition.RegisterUnique();
+
composition.RegisterUnique(factory => new ContentDataSerializer(new DictionaryOfPropertyDataSerializer()));
// register the NuCache database data source
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
index ad8705ef47..dbbcb4ee9b 100755
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
@@ -1456,7 +1456,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
UrlSegment = content.GetUrlSegment(_urlSegmentProviders)
};
- var serialized = serializer.Serialize(content.ContentTypeId, contentCacheData);
+ var serialized = serializer.Serialize(ReadOnlyContentBaseAdapter.Create(content), contentCacheData);
var dto = new ContentNuDto
{