// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.SqlTools.Hosting.Utility; namespace Microsoft.SqlTools.CoreServices { /// /// A class to calculate the value for the metrics using the given bucket /// public class InteractionMetrics { /// /// Creates new instance given a bucket of metrics /// public InteractionMetrics(int[] metrics) { Validate.IsNotNull("metrics", metrics); if(metrics.Length == 0) { throw new ArgumentOutOfRangeException("metrics"); } Counters = new ConcurrentDictionary(); if (!IsSorted(metrics)) { Array.Sort(metrics); } Metrics = metrics; } private ConcurrentDictionary Counters { get; } private object perfCountersLock = new object(); /// /// The metrics bucket /// public int[] Metrics { get; private set; } /// /// Returns true if the given list is sorted /// private bool IsSorted(int[] metrics) { if (metrics.Length > 1) { int previous = metrics[0]; for (int i = 1; i < metrics.Length; i++) { if(metrics[i] < previous) { return false; } previous = metrics[i]; } } return true; } /// /// Update metric value given new number /// public void UpdateMetrics(double duration, T newValue, Func updateValueFactory) { int metric = Metrics[Metrics.Length - 1]; for (int i = 0; i < Metrics.Length; i++) { if (duration <= Metrics[i]) { metric = Metrics[i]; break; } } string key = metric.ToString(); Counters.AddOrUpdate(key, newValue, updateValueFactory); } /// /// Returns the quantile /// public Dictionary Quantile { get { return Counters.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } } } }