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 var json = JsonConvert.SerializeObject(model); return(new ContentCacheDataSerializationResult(json, null)); }
/// <summary> /// Used during serialization to compress properties /// </summary> /// <param name="model"></param> /// <remarks> /// This will essentially 'double compress' property data. The MsgPack data as a whole will already be compressed /// but this will go a step further and double compress property data so that it is stored in the nucache file /// as compressed bytes and therefore will exist in memory as compressed bytes. That is, until the bytes are /// 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. /// </remarks> private void Compress(IReadOnlyContentBase content, ContentCacheDataModel model) { foreach (var propertyAliasToData in model.PropertyData) { if (_propertyOptions.IsCompressed(content, propertyAliasToData.Key)) { foreach (var property in propertyAliasToData.Value.Where(x => x.Value != null && x.Value is string)) { property.Value = LZ4Pickler.Pickle(Encoding.UTF8.GetBytes((string)property.Value), LZ4Level.L00_FAST); } } } }
public bool IsCompressed(IReadOnlyContentBase content, PropertyType propertyType, IDataEditor dataEditor, bool published) { if (!published && propertyType.SupportsPublishing && propertyType.ValueStorageType == ValueStorageType.Ntext) { //Only compress non published content that supports publishing and the property is text return(true); } if (propertyType.ValueStorageType == ValueStorageType.Integer && Umbraco.Core.Constants.PropertyEditors.Aliases.Boolean.Equals(dataEditor.Alias)) { //Compress boolean values from int to bool return(true); } return(false); }
/// <summary> /// Used during deserialization to map the property data as lazy or expand the value /// </summary> /// <param name="content"></param> /// <param name="nestedData"></param> /// <param name="published"></param> private void Expand(IReadOnlyContentBase content, ContentCacheDataModel nestedData, bool published) { foreach (var propertyAliasToData in nestedData.PropertyData) { if (_propertyOptions.IsCompressed(content, propertyAliasToData.Key, published)) { foreach (var property in propertyAliasToData.Value.Where(x => x.Value != null)) { if (property.Value is byte[] byteArrayValue) { property.Value = new LazyCompressedString(byteArrayValue); } } } } }
public ContentCacheDataModel Deserialize(IReadOnlyContentBase content, string stringData, byte[] byteData, bool published) { if (stringData == null && byteData != null) { throw new NotSupportedException($"{typeof(JsonContentNestedDataSerializer)} does not support byte[] serialization"); } JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings); using (JsonTextReader reader = new JsonTextReader(new StringReader(stringData))) { // reader will get buffer from array pool reader.ArrayPool = JsonArrayPool.Instance; reader.PropertyNameTable = _propertyNameTable; return(serializer.Deserialize <ContentCacheDataModel>(reader)); } }
public ContentCacheDataModel?Deserialize(IReadOnlyContentBase content, string?stringData, byte[]?byteData, bool published) { if (byteData != null) { var cacheModel = MessagePackSerializer.Deserialize <ContentCacheDataModel>(byteData, _options); Expand(content, cacheModel, published); 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 cacheModel = MessagePackSerializer.Deserialize <ContentCacheDataModel>(bin, _options); Expand(content, cacheModel, published); return(cacheModel); } else { return(null); } }
public bool IsCompressed(IReadOnlyContentBase content, IPropertyType propertyType, IDataEditor dataEditor, bool published) => false;