| File: Latency\Internal\CheckpointTracker.cs | Web Access |
| Project: src\src\Libraries\Microsoft.Extensions.Telemetry\Microsoft.Extensions.Telemetry.csproj (Microsoft.Extensions.Telemetry) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Threading; using Microsoft.Extensions.ObjectPool; namespace Microsoft.Extensions.Diagnostics.Latency.Internal; /// <summary> /// Class that tracks checkpoints. /// </summary> internal sealed class CheckpointTracker : IResettable { internal TimeProvider TimeProvider; private readonly Registry _checkpointNames; private readonly int[] _checkpointAdded; private readonly Checkpoint[] _checkpoints; private int _numCheckpoints; public long Elapsed { get => TimeProvider.GetTimestamp() - field; private set; } public long Frequency => TimeProvider.TimestampFrequency; /// <summary> /// Initializes a new instance of the <see cref="CheckpointTracker"/> class. /// </summary> /// <param name="registry">Registry of checkpoint names.</param> public CheckpointTracker(Registry registry) { _checkpointNames = registry; var keyCount = _checkpointNames.KeyCount; _checkpointAdded = new int[keyCount]; _checkpoints = new Checkpoint[keyCount]; TimeProvider = TimeProvider.System; Elapsed = TimeProvider.GetTimestamp(); } /// <summary> /// Resets the CheckpointTracker. /// </summary> public bool TryReset() { Elapsed = TimeProvider.GetTimestamp(); _numCheckpoints = 0; Array.Clear(_checkpointAdded, 0, _checkpointAdded.Length); return true; } public CheckpointToken GetToken(string name) { int pos = _checkpointNames.GetRegisteredKeyIndex(name); return new CheckpointToken(name, pos); } /// <summary> /// Add checkpoint for token. /// </summary> /// <param name="token">Token for checkpoint.</param> /// <remarks> If same checkpoint is added more than once, first write wins.</remarks> public void Add(CheckpointToken token) { if (token.Position > -1 && Interlocked.CompareExchange(ref _checkpointAdded[token.Position], 1, 0) == 0) { var p = Interlocked.Increment(ref _numCheckpoints); _checkpoints[p - 1] = new Checkpoint(token.Name, Elapsed, Frequency); } } /// <summary> /// Gets list of checkpoints added. /// </summary> public ArraySegment<Checkpoint> Checkpoints => new(_checkpoints, 0, _numCheckpoints); }