Variants - invariant segments, property values
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Collections;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.PublishedCache.NuCache.DataSource;
|
||||
@@ -21,12 +22,15 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
private readonly object _locko = new object();
|
||||
|
||||
// the invariant-neutral source and inter values
|
||||
private readonly object _sourceValue;
|
||||
private bool _interInitialized;
|
||||
private object _interValue;
|
||||
|
||||
private List<PropertyValue> _sourceVValues;
|
||||
// the variant source and inter values
|
||||
private Dictionary<CompositeIntStringKey, SourceInterValue> _sourceValues;
|
||||
|
||||
// the variant and non-variant object values
|
||||
private CacheValues _cacheValues;
|
||||
|
||||
private string _valuesCacheKey;
|
||||
@@ -51,9 +55,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_sourceVValues == null)
|
||||
_sourceVValues = new List<PropertyValue>();
|
||||
_sourceVValues.Add(new PropertyValue { LanguageId = sourceValue.LanguageId, Segment = sourceValue.Segment, SourceValue = sourceValue.Value });
|
||||
if (_sourceValues == null)
|
||||
_sourceValues = new Dictionary<CompositeIntStringKey, SourceInterValue>();
|
||||
_sourceValues[new CompositeIntStringKey(sourceValue.LanguageId, sourceValue.Segment)]
|
||||
= new SourceInterValue { LanguageId = sourceValue.LanguageId, Segment = sourceValue.Segment, SourceValue = sourceValue.Value };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,7 +75,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
: base(origin.PropertyType, origin.ReferenceCacheLevel)
|
||||
{
|
||||
_sourceValue = origin._sourceValue;
|
||||
_sourceVValues = origin._sourceVValues;
|
||||
_sourceValues = origin._sourceValues;
|
||||
|
||||
_contentUid = origin._contentUid;
|
||||
_content = content;
|
||||
@@ -143,22 +148,19 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (languageId == null && segment == null)
|
||||
{
|
||||
if (_interInitialized) return _interValue;
|
||||
|
||||
_interValue = PropertyType.ConvertSourceToInter(_content, _sourceValue, _isPreviewing);
|
||||
_interInitialized = true;
|
||||
return _interValue;
|
||||
}
|
||||
|
||||
if (_sourceVValues == null)
|
||||
_sourceVValues = new List<PropertyValue>();
|
||||
if (_sourceValues == null)
|
||||
_sourceValues = new Dictionary<CompositeIntStringKey, SourceInterValue>();
|
||||
|
||||
var vvalue = _sourceVValues.FirstOrDefault(x => x.LanguageId == languageId && x.Segment == segment);
|
||||
|
||||
if (vvalue == null)
|
||||
_sourceVValues.Add(vvalue = new PropertyValue { LanguageId = languageId, Segment = segment });
|
||||
var k = new CompositeIntStringKey(languageId, segment);
|
||||
if (!_sourceValues.TryGetValue(k, out var vvalue))
|
||||
_sourceValues[k] = vvalue = new SourceInterValue { LanguageId = languageId, Segment = segment };
|
||||
|
||||
if (vvalue.InterInitialized) return vvalue.InterValue;
|
||||
|
||||
vvalue.InterValue = PropertyType.ConvertSourceToInter(_content, vvalue.SourceValue, _isPreviewing);
|
||||
vvalue.InterInitialized = true;
|
||||
return vvalue.InterValue;
|
||||
@@ -169,13 +171,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (languageId == null && segment == null)
|
||||
return _sourceValue;
|
||||
|
||||
List<PropertyValue> vvalues;
|
||||
lock (_locko)
|
||||
{
|
||||
vvalues = _sourceVValues;
|
||||
if (_sourceValues == null) return null;
|
||||
return _sourceValues.TryGetValue(new CompositeIntStringKey(languageId, segment), out var sourceValue) ? sourceValue.SourceValue : null;
|
||||
}
|
||||
|
||||
return vvalues?.FirstOrDefault(x => x.LanguageId == languageId && x.Segment == segment);
|
||||
}
|
||||
|
||||
public override object GetValue(int? languageId = null, string segment = null)
|
||||
@@ -183,10 +183,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
lock (_locko)
|
||||
{
|
||||
var cacheValues = GetCacheValues(PropertyType.CacheLevel).For(languageId, segment);
|
||||
if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue;
|
||||
|
||||
// initial reference cache level always is .Content
|
||||
cacheValues.ObjectValue = PropertyType.ConvertInterToObject(_content, PropertyCacheLevel.Element, GetInterValue(languageId, segment), _isPreviewing);
|
||||
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;
|
||||
|
||||
if (cacheValues.ObjectInitialized) return cacheValues.ObjectValue;
|
||||
cacheValues.ObjectValue = PropertyType.ConvertInterToObject(_content, initialCacheLevel, GetInterValue(languageId, segment), _isPreviewing);
|
||||
cacheValues.ObjectInitialized = true;
|
||||
return cacheValues.ObjectValue;
|
||||
}
|
||||
@@ -197,10 +199,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
lock (_locko)
|
||||
{
|
||||
var cacheValues = GetCacheValues(PropertyType.CacheLevel).For(languageId, segment);
|
||||
if (cacheValues.XPathInitialized) return cacheValues.XPathValue;
|
||||
|
||||
// initial reference cache level always is .Content
|
||||
cacheValues.XPathValue = PropertyType.ConvertInterToXPath(_content, PropertyCacheLevel.Element, GetInterValue(languageId, segment), _isPreviewing);
|
||||
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;
|
||||
|
||||
if (cacheValues.XPathInitialized) return cacheValues.XPathValue;
|
||||
cacheValues.XPathValue = PropertyType.ConvertInterToXPath(_content, initialCacheLevel, GetInterValue(languageId, segment), _isPreviewing);
|
||||
cacheValues.XPathInitialized = true;
|
||||
return cacheValues.XPathValue;
|
||||
}
|
||||
@@ -208,40 +212,45 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region Classes
|
||||
|
||||
private class CacheValues
|
||||
private class CacheValue
|
||||
{
|
||||
private int? _languageId;
|
||||
private string _segment;
|
||||
public bool ObjectInitialized { get; set; }
|
||||
public object ObjectValue { get; set; }
|
||||
public bool XPathInitialized { get; set; }
|
||||
public object XPathValue { get; set; }
|
||||
}
|
||||
|
||||
public bool ObjectInitialized;
|
||||
public object ObjectValue;
|
||||
public bool XPathInitialized;
|
||||
public object XPathValue;
|
||||
|
||||
private List<CacheValues> _values;
|
||||
private class CacheValues : CacheValue
|
||||
{
|
||||
private Dictionary<CompositeIntStringKey, CacheValue> _values;
|
||||
|
||||
// this is always invoked from within a lock, so does not require its own lock
|
||||
public CacheValues For(int? languageId, string segment)
|
||||
public CacheValue For(int? languageId, string segment)
|
||||
{
|
||||
if (languageId == null && segment == null)
|
||||
return this;
|
||||
|
||||
if (_values == null)
|
||||
_values = new List<CacheValues>();
|
||||
_values = new Dictionary<CompositeIntStringKey, CacheValue>();
|
||||
|
||||
var values = _values.FirstOrDefault(x => x._languageId == languageId && x._segment == segment);
|
||||
var k = new CompositeIntStringKey(languageId, segment);
|
||||
if (!_values.TryGetValue(k, out var value))
|
||||
_values[k] = value = new CacheValue();
|
||||
|
||||
if (values == null)
|
||||
_values.Add(values = new CacheValues { _languageId = languageId, _segment = segment });
|
||||
|
||||
return values;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private class PropertyValue
|
||||
private class SourceInterValue
|
||||
{
|
||||
private string _segment;
|
||||
|
||||
public int? LanguageId { get; set; }
|
||||
public string Segment { get; set; }
|
||||
public string Segment
|
||||
{
|
||||
get => _segment;
|
||||
internal set => _segment = value?.ToLowerInvariant();
|
||||
}
|
||||
public object SourceValue { get; set; }
|
||||
public bool InterInitialized { get; set; }
|
||||
public object InterValue { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user