Skip to content

Commit

Permalink
Ported over #15928 changes for 13.3 RC
Browse files Browse the repository at this point in the history
  • Loading branch information
kjac committed Apr 10, 2024
1 parent d765e69 commit 259cdac
Showing 1 changed file with 61 additions and 73 deletions.
134 changes: 61 additions & 73 deletions src/Umbraco.PublishedCache.NuCache/Property.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Concurrent;
using System.Xml.Serialization;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Collections;
Expand All @@ -19,7 +20,6 @@ internal class Property : PublishedPropertyBase
private readonly bool _isMember;
private readonly bool _isPreviewing;

private readonly object _locko = new();
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;

// the invariant-neutral source and inter values
Expand All @@ -33,7 +33,7 @@ internal class Property : PublishedPropertyBase
private object? _interValue;

// the variant source and inter values
private Dictionary<CompositeStringStringKey, SourceInterValue>? _sourceValues;
private ConcurrentDictionary<CompositeStringStringKey, SourceInterValue>? _sourceValues;

private string? _valuesCacheKey;

Expand Down Expand Up @@ -68,7 +68,7 @@ public Property(
{
if (_sourceValues == null)
{
_sourceValues = new Dictionary<CompositeStringStringKey, SourceInterValue>();
_sourceValues = InitializeConcurrentDictionary<CompositeStringStringKey, SourceInterValue>();
}

_sourceValues[new CompositeStringStringKey(sourceValue.Culture, sourceValue.Segment)]
Expand Down Expand Up @@ -125,30 +125,27 @@ public override bool HasValue(string? culture = null, string? segment = null)
return hasValue.Value;
}

lock (_locko)
value = GetInterValue(culture, segment);
hasValue = PropertyType.IsValue(value, PropertyValueLevel.Inter);
if (hasValue.HasValue)
{
value = GetInterValue(culture, segment);
hasValue = PropertyType.IsValue(value, PropertyValueLevel.Inter);
if (hasValue.HasValue)
{
return hasValue.Value;
}

CacheValue cacheValues = GetCacheValues(PropertyType.CacheLevel).For(culture, segment);
return hasValue.Value;
}

// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;
CacheValue cacheValues = GetCacheValues(PropertyType.CacheLevel).For(culture, segment);

if (!cacheValues.ObjectInitialized)
{
cacheValues.ObjectValue =
PropertyType.ConvertInterToObject(_content, initialCacheLevel, value, _isPreviewing);
cacheValues.ObjectInitialized = true;
}
// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;

value = cacheValues.ObjectValue;
return PropertyType.IsValue(value, PropertyValueLevel.Object) ?? false;
if (!cacheValues.ObjectInitialized)
{
cacheValues.ObjectValue =
PropertyType.ConvertInterToObject(_content, initialCacheLevel, value, _isPreviewing);
cacheValues.ObjectInitialized = true;
}

value = cacheValues.ObjectValue;
return PropertyType.IsValue(value, PropertyValueLevel.Object) ?? false;
}

public override object? GetSourceValue(string? culture = null, string? segment = null)
Expand All @@ -160,19 +157,16 @@ public override bool HasValue(string? culture = null, string? segment = null)
return _sourceValue;
}

lock (_locko)
if (_sourceValues == null)
{
if (_sourceValues == null)
{
return null;
}

return _sourceValues.TryGetValue(
new CompositeStringStringKey(culture, segment),
out SourceInterValue? sourceValue)
? sourceValue.SourceValue
: null;
return null;
}

return _sourceValues.TryGetValue(
new CompositeStringStringKey(culture, segment),
out SourceInterValue? sourceValue)
? sourceValue.SourceValue
: null;
}

private CacheValues GetCacheValues(PropertyCacheLevel cacheLevel)
Expand Down Expand Up @@ -227,7 +221,6 @@ private CacheValues GetCacheValues(IAppCache? cache)
return (CacheValues)cache.Get(ValuesCacheKey, () => new CacheValues())!;
}

// this is always invoked from within a lock, so does not require its own lock
private object? GetInterValue(string? culture, string? segment)
{
if (culture == string.Empty && segment == string.Empty)
Expand All @@ -244,7 +237,7 @@ private CacheValues GetCacheValues(IAppCache? cache)

if (_sourceValues == null)
{
_sourceValues = new Dictionary<CompositeStringStringKey, SourceInterValue>();
_sourceValues = InitializeConcurrentDictionary<CompositeStringStringKey, SourceInterValue>();
}

var k = new CompositeStringStringKey(culture, segment);
Expand Down Expand Up @@ -273,23 +266,20 @@ private CacheValues GetCacheValues(IAppCache? cache)
_content.VariationContextAccessor.ContextualizeVariation(_variations, _content.Id, ref culture, ref segment);

object? value;
lock (_locko)
{
CacheValue cacheValues = GetCacheValues(PropertyType.CacheLevel).For(culture, segment);
CacheValue cacheValues = GetCacheValues(PropertyType.CacheLevel).For(culture, segment);

// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;
// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;

if (cacheValues.ObjectInitialized)
{
return cacheValues.ObjectValue;
}

cacheValues.ObjectValue = PropertyType.ConvertInterToObject(_content, initialCacheLevel, GetInterValue(culture, segment), _isPreviewing);
cacheValues.ObjectInitialized = true;
value = cacheValues.ObjectValue;
if (cacheValues.ObjectInitialized)
{
return cacheValues.ObjectValue;
}

cacheValues.ObjectValue = PropertyType.ConvertInterToObject(_content, initialCacheLevel, GetInterValue(culture, segment), _isPreviewing);
cacheValues.ObjectInitialized = true;
value = cacheValues.ObjectValue;

return value;
}

Expand All @@ -298,41 +288,36 @@ private CacheValues GetCacheValues(IAppCache? cache)
{
_content.VariationContextAccessor.ContextualizeVariation(_variations, _content.Id, ref culture, ref segment);

lock (_locko)
{
CacheValue cacheValues = GetCacheValues(PropertyType.CacheLevel).For(culture, segment);

// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;
CacheValue cacheValues = GetCacheValues(PropertyType.CacheLevel).For(culture, segment);

if (cacheValues.XPathInitialized)
{
return cacheValues.XPathValue;
}
// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;

cacheValues.XPathValue = PropertyType.ConvertInterToXPath(_content, initialCacheLevel, GetInterValue(culture, segment), _isPreviewing);
cacheValues.XPathInitialized = true;
if (cacheValues.XPathInitialized)
{
return cacheValues.XPathValue;
}

cacheValues.XPathValue = PropertyType.ConvertInterToXPath(_content, initialCacheLevel, GetInterValue(culture, segment), _isPreviewing);
cacheValues.XPathInitialized = true;
return cacheValues.XPathValue;
}

public override object? GetDeliveryApiValue(bool expanding, string? culture = null, string? segment = null)
{
_content.VariationContextAccessor.ContextualizeVariation(_variations, _content.Id, ref culture, ref segment);

object? value;
lock (_locko)
{
CacheValue cacheValues = GetCacheValues(expanding ? PropertyType.DeliveryApiCacheLevelForExpansion : PropertyType.DeliveryApiCacheLevel).For(culture, segment);
CacheValue cacheValues = GetCacheValues(expanding ? PropertyType.DeliveryApiCacheLevelForExpansion : PropertyType.DeliveryApiCacheLevel).For(culture, segment);

// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;

object? GetDeliveryApiObject() => PropertyType.ConvertInterToDeliveryApiObject(_content, initialCacheLevel, GetInterValue(culture, segment), _isPreviewing, expanding);
value = expanding
? GetDeliveryApiExpandedObject(cacheValues, GetDeliveryApiObject)
: GetDeliveryApiDefaultObject(cacheValues, GetDeliveryApiObject);
}
// initial reference cache level always is .Content
const PropertyCacheLevel initialCacheLevel = PropertyCacheLevel.Element;

object? GetDeliveryApiObject() => PropertyType.ConvertInterToDeliveryApiObject(_content, initialCacheLevel, GetInterValue(culture, segment), _isPreviewing, expanding);
value = expanding
? GetDeliveryApiExpandedObject(cacheValues, GetDeliveryApiObject)
: GetDeliveryApiDefaultObject(cacheValues, GetDeliveryApiObject);

return value;
}
Expand Down Expand Up @@ -382,9 +367,8 @@ private class CacheValue

private class CacheValues : CacheValue
{
private Dictionary<CompositeStringStringKey, CacheValue>? _values;
private ConcurrentDictionary<CompositeStringStringKey, CacheValue>? _values;

// this is always invoked from within a lock, so does not require its own lock
public CacheValue For(string? culture, string? segment)
{
if (culture == string.Empty && segment == string.Empty)
Expand All @@ -394,7 +378,7 @@ public CacheValue For(string? culture, string? segment)

if (_values == null)
{
_values = new Dictionary<CompositeStringStringKey, CacheValue>();
_values = InitializeConcurrentDictionary<CompositeStringStringKey, CacheValue>();
}

var k = new CompositeStringStringKey(culture, segment);
Expand Down Expand Up @@ -431,5 +415,9 @@ public string? Segment
public object? InterValue { get; set; }
}

private static ConcurrentDictionary<TKey, TValue> InitializeConcurrentDictionary<TKey, TValue>()
where TKey : notnull
=> new(-1, 5);

#endregion
}

0 comments on commit 259cdac

Please sign in to comment.