/// <summary> /// Flushes the values buffer to update the aggregate state held by subclasses. /// </summary> /// <param name="buffer"></param> private void UpdateAggregate(MetricValuesBufferBase <TBufferedValue> buffer) { if (buffer == null) { return; } #if DEBUG unchecked { Interlocked.Increment(ref s_countBufferFlushes); } #endif object stage1Result; // This lock is only contended is a user called CreateAggregateUnsafe or CompleteAggregation. // This is very unlikely to be the case in a tight loop. lock (buffer) { int maxFlushIndex = Math.Min(buffer.PeekLastWriteIndex(), buffer.Capacity - 1); int minFlushIndex = buffer.NextFlushIndex; if (minFlushIndex > maxFlushIndex) { return; } stage1Result = UpdateAggregate_Stage1(buffer, minFlushIndex, maxFlushIndex); buffer.NextFlushIndex = maxFlushIndex + 1; } UpdateAggregate_Stage2(stage1Result); }