in BASE/src/Microsoft.ApplicationInsights/Metrics/Implementation/ConcurrentDatastructures/MultidimensionalCube2.cs [274:402]
private MultidimensionalPointResult<TPoint> TryCreatePoint(string[] coordinates, string pointMoniker)
{
#pragma warning disable SA1509 // Opening braces must not be preceded by blank line
// We already have tried getting the existing point and failed.
// We also checked that _totalPointsCountLimit was not reached (outside the lock).
// Lastly, we took a lock.
// Now we can begin the slow path.
// First, we need to try retrieving the point again, now under the lock:
TPoint point;
bool hasPoint = this.points.TryGetValue(pointMoniker, out point);
if (hasPoint)
{
var result = new MultidimensionalPointResult<TPoint>(MultidimensionalPointResultCodes.Success_ExistingPointRetrieved, point);
return result;
}
// Then, check total count again now that we are under lock:
if (this.totalPointsCount >= this.totalPointsCountLimit)
{
var result = new MultidimensionalPointResult<TPoint>(MultidimensionalPointResultCodes.Failure_TotalPointsCountLimitReached, -1);
return result;
}
// Examine each dimension and see if it reached values count limit. If not, track the new value:
int reachedValsLimitDim = -1;
BitArray valueAddedToDims = new BitArray(length: coordinates.Length, defaultValue: false);
bool dimensionCappingApplied = false;
for (int i = 0; i < coordinates.Length; i++)
{
HashSet<string> dimVals = this.dimensionValues[i];
string coordinateVal = coordinates[i];
if ((dimVals.Count >= this.dimensionValuesCountLimits[i]) && (false == dimVals.Contains(coordinateVal)))
{
if (this.applyDimensionCapping)
{
// throwing away the actual dimension value here as we are asked to apply dimensioncapping.
coordinates[i] = this.dimensionCapValue;
dimensionCappingApplied = true;
}
else
{
reachedValsLimitDim = i;
break;
}
}
bool added = dimVals.Add(coordinates[i]);
valueAddedToDims.Set(i, added);
}
// We hit the _dimensionValuesCountLimits at some dimension.
// Remove what we just added to dim value sets and give up.
if (reachedValsLimitDim != -1)
{
for (int i = 0; i <= reachedValsLimitDim; i++)
{
if (valueAddedToDims.Get(i))
{
this.dimensionValues[i].Remove(coordinates[i]);
}
}
var result = new MultidimensionalPointResult<TPoint>(MultidimensionalPointResultCodes.Failure_SubdimensionsCountLimitReached, reachedValsLimitDim);
return result;
}
if (dimensionCappingApplied)
{
// We did dimension capping - i.e one or more dimension values were replaced, requiring us to reconstruct the moniker with new values.
pointMoniker = BuildPointMoniker(coordinates);
// Check again (with new moniker) if the point already exists.
hasPoint = this.points.TryGetValue(pointMoniker, out point);
if (hasPoint)
{
var result = new MultidimensionalPointResult<TPoint>(MultidimensionalPointResultCodes.Success_ExistingPointRetrieved, point);
return result;
}
// Continue with point creation using new moniker.
}
// Create new point:
try
{
point = this.pointsFactory(coordinates);
}
catch (Exception ex)
{
// User code in _pointsFactory may throw. In that case we need to clean up from the added value containers:
for (int i = 0; i <= reachedValsLimitDim; i++)
{
if (valueAddedToDims.Get(i))
{
this.dimensionValues[i].Remove(coordinates[i]);
}
}
ExceptionDispatchInfo.Capture(ex).Throw();
throw; // This line will never be reached
}
{
bool added = this.points.TryAdd(pointMoniker, point);
if (false == added)
{
throw new InvalidOperationException(Invariant($"Internal SDK bug. Please report this! (pointMoniker: {pointMoniker})")
+ Invariant($" Info: Failed to add a point to the {nameof(this.points)}-collection in")
+ Invariant($" class {nameof(MultidimensionalCube2<TPoint>)} despite passing all the cerfification checks."));
}
}
// Inc total points count.
this.totalPointsCount++;
{
var result = new MultidimensionalPointResult<TPoint>(
dimensionCappingApplied ? MultidimensionalPointResultCodes.Success_NewPointCreatedAboveDimCapLimit : MultidimensionalPointResultCodes.Success_NewPointCreated,
point);
return result;
}
#pragma warning restore SA1509 // Opening braces must not be preceded by blank line
}