AggregatorStore<TAggregator>
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
namespace System.Diagnostics.Metrics
{
[SecuritySafeCritical]
internal struct AggregatorStore<TAggregator> where TAggregator : Aggregator
{
private volatile object _stateUnion;
private volatile AggregatorLookupFunc<TAggregator> _cachedLookupFunc;
private readonly Func<TAggregator> _createAggregatorFunc;
public AggregatorStore(Func<TAggregator> createAggregator)
{
_stateUnion = null;
_cachedLookupFunc = null;
_createAggregatorFunc = createAggregator;
}
public TAggregator GetAggregator(ReadOnlySpan<KeyValuePair<string, object>> labels)
{
AggregatorLookupFunc<TAggregator> cachedLookupFunc = _cachedLookupFunc;
if (cachedLookupFunc != null && cachedLookupFunc(labels, out TAggregator aggregator))
return aggregator;
return GetAggregatorSlow(labels);
}
private TAggregator GetAggregatorSlow(ReadOnlySpan<KeyValuePair<string, object>> labels)
{
(_cachedLookupFunc = LabelInstructionCompiler.Create<TAggregator>(ref this, _createAggregatorFunc, labels))(labels, out TAggregator aggregator);
return aggregator;
}
public void Collect(Action<LabeledAggregationStatistics> visitFunc)
{
object stateUnion2 = _stateUnion;
object stateUnion = _stateUnion;
TAggregator val = stateUnion as TAggregator;
if (val == null) {
FixedSizeLabelNameDictionary<StringSequence1, ObjectSequence1, TAggregator> fixedSizeLabelNameDictionary = stateUnion as FixedSizeLabelNameDictionary<StringSequence1, ObjectSequence1, TAggregator>;
if (fixedSizeLabelNameDictionary == null) {
FixedSizeLabelNameDictionary<StringSequence2, ObjectSequence2, TAggregator> fixedSizeLabelNameDictionary2 = stateUnion as FixedSizeLabelNameDictionary<StringSequence2, ObjectSequence2, TAggregator>;
if (fixedSizeLabelNameDictionary2 == null) {
FixedSizeLabelNameDictionary<StringSequence3, ObjectSequence3, TAggregator> fixedSizeLabelNameDictionary3 = stateUnion as FixedSizeLabelNameDictionary<StringSequence3, ObjectSequence3, TAggregator>;
if (fixedSizeLabelNameDictionary3 == null) {
FixedSizeLabelNameDictionary<StringSequenceMany, ObjectSequenceMany, TAggregator> fixedSizeLabelNameDictionary4 = stateUnion as FixedSizeLabelNameDictionary<StringSequenceMany, ObjectSequenceMany, TAggregator>;
if (fixedSizeLabelNameDictionary4 == null)
(stateUnion as MultiSizeLabelNameDictionary<TAggregator>)?.Collect(visitFunc);
else
fixedSizeLabelNameDictionary4.Collect(visitFunc);
} else
fixedSizeLabelNameDictionary3.Collect(visitFunc);
} else
fixedSizeLabelNameDictionary2.Collect(visitFunc);
} else
fixedSizeLabelNameDictionary.Collect(visitFunc);
} else {
IAggregationStatistics stats = val.Collect();
visitFunc(new LabeledAggregationStatistics(stats, Array.Empty<KeyValuePair<string, string>>()));
}
}
public TAggregator GetAggregator()
{
MultiSizeLabelNameDictionary<TAggregator> multiSizeLabelNameDictionary2;
while (true) {
object stateUnion = _stateUnion;
if (stateUnion == null) {
TAggregator val = _createAggregatorFunc();
if (val == null)
return val;
if (Interlocked.CompareExchange(ref _stateUnion, val, null) == null)
return val;
} else {
TAggregator val2 = stateUnion as TAggregator;
if (val2 != null)
return val2;
MultiSizeLabelNameDictionary<TAggregator> multiSizeLabelNameDictionary = stateUnion as MultiSizeLabelNameDictionary<TAggregator>;
if (multiSizeLabelNameDictionary != null)
return multiSizeLabelNameDictionary.GetNoLabelAggregator(_createAggregatorFunc);
multiSizeLabelNameDictionary2 = new MultiSizeLabelNameDictionary<TAggregator>(stateUnion);
if (Interlocked.CompareExchange(ref _stateUnion, multiSizeLabelNameDictionary2, stateUnion) == stateUnion)
break;
}
}
return multiSizeLabelNameDictionary2.GetNoLabelAggregator(_createAggregatorFunc);
}
public ConcurrentDictionary<TObjectSequence, TAggregator> GetLabelValuesDictionary<TStringSequence, TObjectSequence>([In] [System.Runtime.CompilerServices.IsReadOnly] ref TStringSequence names) where TStringSequence : IStringSequence, IEquatable<TStringSequence> where TObjectSequence : IObjectSequence, IEquatable<TObjectSequence>
{
MultiSizeLabelNameDictionary<TAggregator> multiSizeLabelNameDictionary2;
while (true) {
object stateUnion = this._stateUnion;
if (stateUnion == null) {
FixedSizeLabelNameDictionary<TStringSequence, TObjectSequence, TAggregator> fixedSizeLabelNameDictionary = new FixedSizeLabelNameDictionary<TStringSequence, TObjectSequence, TAggregator>();
if (Interlocked.CompareExchange(ref this._stateUnion, fixedSizeLabelNameDictionary, null) == null)
return fixedSizeLabelNameDictionary.GetValuesDictionary(ref names);
} else {
FixedSizeLabelNameDictionary<TStringSequence, TObjectSequence, TAggregator> fixedSizeLabelNameDictionary2 = stateUnion as FixedSizeLabelNameDictionary<TStringSequence, TObjectSequence, TAggregator>;
if (fixedSizeLabelNameDictionary2 != null)
return fixedSizeLabelNameDictionary2.GetValuesDictionary(ref names);
MultiSizeLabelNameDictionary<TAggregator> multiSizeLabelNameDictionary = stateUnion as MultiSizeLabelNameDictionary<TAggregator>;
if (multiSizeLabelNameDictionary != null)
return multiSizeLabelNameDictionary.GetFixedSizeLabelNameDictionary<TStringSequence, TObjectSequence>().GetValuesDictionary(ref names);
multiSizeLabelNameDictionary2 = new MultiSizeLabelNameDictionary<TAggregator>(stateUnion);
if (Interlocked.CompareExchange(ref this._stateUnion, multiSizeLabelNameDictionary2, stateUnion) == stateUnion)
break;
}
}
return multiSizeLabelNameDictionary2.GetFixedSizeLabelNameDictionary<TStringSequence, TObjectSequence>().GetValuesDictionary(ref names);
}
}
}