Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
CounterSetInstanceBase.cs597 linesDownload Raw Back to perfCounters
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Concurrent;5using System.Collections.Generic;6using System.Diagnostics;7using System.Diagnostics.CodeAnalysis;8using System.Diagnostics.PerformanceData;9using System.Globalization;10using System.Management.Automation.Tracing;11 12namespace System.Management.Automation.PerformanceData13{14    /// <summary>15    /// An abstract class that forms the base class for any Counter Set type.16    /// A Counter Set Instance is required to register a given performance counter category17    /// with PSPerfCountersMgr.18    /// </summary>19    public abstract class CounterSetInstanceBase : IDisposable20    {21        private readonly PowerShellTraceSource _tracer = PowerShellTraceSourceFactory.GetTraceSource();22        #region Protected Members23 24        /// <summary>25        /// An instance of counterSetRegistrarBase type encapsulates all the information26        /// about a counter set and its associated counters.27        /// </summary>28        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]29        protected CounterSetRegistrarBase _counterSetRegistrarBase;30 31        // NOTE: Check whether the following dictionaries need to be concurrent32        // because there would be only 1 thread creating the instance,33        // and that instance would then be shared by multiple threads for data access.34        // Those threads won't modify/manipulate the dictionary, but they would only access it.35 36        /// <summary>37        /// Dictionary mapping counter name to id.38        /// </summary>39        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]40        protected ConcurrentDictionary<string, int> _counterNameToIdMapping;41        /// <summary>42        /// Dictionary mapping counter id to counter type.43        /// </summary>44        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]45        protected ConcurrentDictionary<int, CounterType> _counterIdToTypeMapping;46 47        #region Constructors48        /// <summary>49        /// Constructor.50        /// </summary>51        protected CounterSetInstanceBase(CounterSetRegistrarBase counterSetRegistrarInst)52        {53            this._counterSetRegistrarBase = counterSetRegistrarInst;54            _counterNameToIdMapping = new ConcurrentDictionary<string, int>();55            _counterIdToTypeMapping = new ConcurrentDictionary<int, CounterType>();56 57            CounterInfo[] counterInfoArray = this._counterSetRegistrarBase.CounterInfoArray;58 59            for (int i = 0; i < counterInfoArray.Length; i++)60            {61                this._counterIdToTypeMapping.TryAdd(counterInfoArray[i].Id, counterInfoArray[i].Type);62                if (!string.IsNullOrWhiteSpace(counterInfoArray[i].Name))63                {64                    this._counterNameToIdMapping.TryAdd(counterInfoArray[i].Name, counterInfoArray[i].Id);65                }66            }67        }68 69        #endregion70 71        /// <summary>72        /// Method that retrieves the target counter id.73        /// NOTE: If isNumerator is true, then input counter id is returned.74        /// But, if isNumerator is false, then a check is made on the input75        /// counter's type to ensure that denominator is indeed value for such a counter.76        /// </summary>77        protected bool RetrieveTargetCounterIdIfValid(int counterId, bool isNumerator, out int targetCounterId)78        {79            targetCounterId = counterId;80            if (isNumerator == false)81            {82                bool isDenominatorValid = false;83                CounterType counterType = this._counterIdToTypeMapping[counterId];84                switch (counterType)85                {86                    case CounterType.MultiTimerPercentageActive:87                    case CounterType.MultiTimerPercentageActive100Ns:88                    case CounterType.MultiTimerPercentageNotActive:89                    case CounterType.MultiTimerPercentageNotActive100Ns:90                    case CounterType.RawFraction32:91                    case CounterType.RawFraction64:92                    case CounterType.SampleFraction:93                    case CounterType.AverageCount64:94                    case CounterType.AverageTimer32:95                        isDenominatorValid = true;96                        break;97                }98 99                if (isDenominatorValid == false)100                {101                    InvalidOperationException invalidOperationException =102                        new InvalidOperationException(103                            string.Format(104                            CultureInfo.InvariantCulture,105                            "Denominator for update not valid for the given counter id {0}",106                            counterId));107                    _tracer.TraceException(invalidOperationException);108                    return false;109                }110 111                targetCounterId = counterId + 1;112            }113 114            return true;115        }116 117        #endregion118 119        #region Public Methods120 121        /// <summary>122        /// If isNumerator is true, then updates the numerator component123        /// of target counter 'counterId' by a value given by 'stepAmount'.124        /// Otherwise, updates the denominator component by 'stepAmount'.125        /// </summary>126        public abstract bool UpdateCounterByValue(127            int counterId,128            long stepAmount,129            bool isNumerator);130 131        /// <summary>132        /// If isNumerator is true, then updates the numerator component133        /// of target counter 'counterName' by a value given by 'stepAmount'.134        /// Otherwise, updates the denominator component by 'stepAmount'.135        /// </summary>136        public abstract bool UpdateCounterByValue(137            string counterName,138            long stepAmount,139            bool isNumerator);140 141        /// <summary>142        /// If isNumerator is true, then sets the numerator component of target143        /// counter 'counterId' to 'counterValue'.144        /// Otherwise, sets the denominator component to 'counterValue'.145        /// </summary>146        public abstract bool SetCounterValue(147            int counterId,148            long counterValue,149            bool isNumerator);150 151        /// <summary>152        /// If isNumerator is true, then sets the numerator component of target153        /// Counter 'counterName' to 'counterValue'.154        /// Otherwise, sets the denominator component to 'counterValue'.155        /// </summary>156        public abstract bool SetCounterValue(157            string counterName,158            long counterValue,159            bool isNumerator);160 161        /// <summary>162        /// This method retrieves the counter value associated with counter 'counterId'163        /// based on isNumerator parameter.164        /// </summary>165        public abstract bool GetCounterValue(int counterId, bool isNumerator, out long counterValue);166 167        /// <summary>168        /// This method retrieves the counter value associated with counter 'counterName'169        /// based on isNumerator parameter.170        /// </summary>171        public abstract bool GetCounterValue(string counterName, bool isNumerator, out long counterValue);172 173        /// <summary>174        /// An abstract method that will be implemented by the derived type175        /// so as to dispose the appropriate counter set instance.176        /// </summary>177        public abstract void Dispose();178 179        /*180        /// <summary>181        /// Resets the target counter 'counterId' to 0. If the given182        /// counter has both numerator and denominator components, then183        /// they both are set to 0.184        /// </summary>185        public bool ResetCounter(186            int counterId)187        {188            this.SetCounterValue(counterId, 0, true);189            this.SetCounterValue(counterId, 0, false);190        }191 192        /// <summary>193        /// Resets the target counter 'counterName' to 0. If the given194        /// counter has both numerator and denominator components, then195        /// they both are set to 0.196        /// </summary>197        public void ResetCounter(string counterName)198        {199            this.SetCounterValue(counterName, 0, true);200            this.SetCounterValue(counterName, 0, false);201        }202        */203        #endregion204    }205 206    /// <summary>207    /// PSCounterSetInstance is a thin wrapper208    /// on System.Diagnostics.PerformanceData.CounterSetInstance.209    /// </summary>210    public class PSCounterSetInstance : CounterSetInstanceBase211    {212        #region Private Members213        private bool _Disposed;214        private CounterSet _CounterSet;215        private CounterSetInstance _CounterSetInstance;216        private readonly PowerShellTraceSource _tracer = PowerShellTraceSourceFactory.GetTraceSource();217 218        #region Private Methods219 220        private void CreateCounterSetInstance()221        {222            _CounterSet =223                new CounterSet(224                    base._counterSetRegistrarBase.ProviderId,225                    base._counterSetRegistrarBase.CounterSetId,226                    base._counterSetRegistrarBase.CounterSetInstType);227 228            // Add the counters to the counter set definition.229            foreach (CounterInfo counterInfo in base._counterSetRegistrarBase.CounterInfoArray)230            {231                if (counterInfo.Name == null)232                {233                    _CounterSet.AddCounter(counterInfo.Id, counterInfo.Type);234                }235                else236                {237                    _CounterSet.AddCounter(counterInfo.Id, counterInfo.Type, counterInfo.Name);238                }239            }240 241            string instanceName = PSPerfCountersMgr.Instance.GetCounterSetInstanceName();242            // Create an instance of the counter set (contains the counter data).243            _CounterSetInstance = _CounterSet.CreateCounterSetInstance(instanceName);244        }245 246        private void UpdateCounterByValue(CounterData TargetCounterData, long stepAmount)247        {248            Debug.Assert(TargetCounterData != null);249            if (stepAmount == -1)250            {251                TargetCounterData.Decrement();252            }253            else if (stepAmount == 1)254            {255                TargetCounterData.Increment();256            }257            else258            {259                TargetCounterData.IncrementBy(stepAmount);260            }261        }262 263        #endregion264 265        #endregion266 267        #region Constructors268        /// <summary>269        /// Constructor for creating an instance of PSCounterSetInstance.270        /// </summary>271        public PSCounterSetInstance(CounterSetRegistrarBase counterSetRegBaseObj)272            : base(counterSetRegBaseObj)273        {274            CreateCounterSetInstance();275        }276 277        #endregion278 279        #region Destructor280 281        /// <summary>282        /// This destructor will run only if the Dispose method283        /// does not get called.284        /// It gives the base class opportunity to finalize.285        /// </summary>286        ~PSCounterSetInstance()287        {288            Dispose(false);289        }290 291        #endregion292 293        #region Protected Methods294        /// <summary>295        /// Dispose(bool disposing) executes in two distinct scenarios.296        /// If disposing equals true, the method has been called directly297        /// or indirectly by a user's code. Managed and unmanaged resources298        /// can be disposed.299        /// If disposing equals false, the method has been called by the300        /// runtime from inside the finalizer and you should not reference301        /// other objects. Only unmanaged resources can be disposed.302        /// </summary>303        protected virtual void Dispose(bool disposing)304        {305            // Check to see if Dispose has already been called.306            if (!_Disposed)307            {308                // If disposing equals true, dispose all managed309                // and unmanaged resources.310                if (disposing)311                {312                    // Dispose managed resources.313                    _CounterSetInstance.Dispose();314                    _CounterSet.Dispose();315                }316                // Note disposing has been done.317                _Disposed = true;318            }319        }320 321        #endregion322 323        #region IDisposable Overrides324        /// <summary>325        /// Dispose Method implementation for IDisposable interface.326        /// </summary>327        public override void Dispose()328        {329            this.Dispose(true);330            // This object will be cleaned up by the Dispose method.331            // Therefore, you should call GC.SuppressFinalize to332            // take this object off the finalization queue333            // and prevent finalization code for this object334            // from executing a second time.335            GC.SuppressFinalize(this);336        }337 338        #endregion339 340        #region CounterSetInstanceBase Overrides341 342        #region Public Methods343 344        /// <summary>345        /// If isNumerator is true, then updates the numerator component346        /// of target counter 'counterId' by a value given by 'stepAmount'.347        /// Otherwise, updates the denominator component by 'stepAmount'.348        /// </summary>349        public override bool UpdateCounterByValue(int counterId, long stepAmount, bool isNumerator)350        {351            if (_Disposed)352            {353                ObjectDisposedException objectDisposedException =354                    new ObjectDisposedException("PSCounterSetInstance");355                _tracer.TraceException(objectDisposedException);356                return false;357            }358 359            int targetCounterId;360            if (base.RetrieveTargetCounterIdIfValid(counterId, isNumerator, out targetCounterId))361            {362                CounterData targetCounterData = _CounterSetInstance.Counters[targetCounterId];363                if (targetCounterData != null)364                {365                    this.UpdateCounterByValue(targetCounterData, stepAmount);366                    return true;367                }368                else369                {370                    InvalidOperationException invalidOperationException =371                    new InvalidOperationException(372                        string.Format(373                        CultureInfo.InvariantCulture,374                        "Lookup for counter corresponding to counter id {0} failed",375                        counterId));376                    _tracer.TraceException(invalidOperationException);377                    return false;378                }379            }380            else381            {382                return false;383            }384        }385        /// <summary>386        /// If isNumerator is true, then updates the numerator component387        /// of target counter 'counterName' by a value given by 'stepAmount'.388        /// Otherwise, updates the denominator component by 'stepAmount'.389        /// </summary>390        public override bool UpdateCounterByValue(string counterName, long stepAmount, bool isNumerator)391        {392            if (_Disposed)393            {394                ObjectDisposedException objectDisposedException =395                    new ObjectDisposedException("PSCounterSetInstance");396                _tracer.TraceException(objectDisposedException);397                return false;398            }399            // retrieve counter id associated with the counter name400            if (counterName == null)401            {402                ArgumentNullException argNullException = new ArgumentNullException(nameof(counterName));403                _tracer.TraceException(argNullException);404                return false;405            }406 407            try408            {409                int targetCounterId = this._counterNameToIdMapping[counterName];410                return this.UpdateCounterByValue(targetCounterId, stepAmount, isNumerator);411            }412            catch (KeyNotFoundException)413            {414                InvalidOperationException invalidOperationException =415                    new InvalidOperationException(416                    string.Format(417                    CultureInfo.InvariantCulture,418                    "Lookup for counter corresponding to counter name {0} failed",419                    counterName));420                _tracer.TraceException(invalidOperationException);421                return false;422            }423        }424 425        /// <summary>426        /// If isNumerator is true, then sets the numerator component427        /// of target counter 'counterId' to 'counterValue'.428        /// Otherwise, sets the denominator component to 'counterValue'.429        /// </summary>430        public override bool SetCounterValue(int counterId, long counterValue, bool isNumerator)431        {432            if (_Disposed)433            {434                ObjectDisposedException objectDisposedException =435                    new ObjectDisposedException("PSCounterSetInstance");436                _tracer.TraceException(objectDisposedException);437                return false;438            }439 440            int targetCounterId;441            if (base.RetrieveTargetCounterIdIfValid(counterId, isNumerator, out targetCounterId))442            {443                CounterData targetCounterData = _CounterSetInstance.Counters[targetCounterId];444 445                if (targetCounterData != null)446                {447                    targetCounterData.Value = counterValue;448                    return true;449                }450                else451                {452                    InvalidOperationException invalidOperationException =453                        new InvalidOperationException(454                            string.Format(455                            CultureInfo.InvariantCulture,456                            "Lookup for counter corresponding to counter id {0} failed",457                            counterId));458                    _tracer.TraceException(invalidOperationException);459                    return false;460                }461            }462            else463            {464                return false;465            }466        }467 468        /// <summary>469        /// If isNumerator is true, then updates the numerator component470        /// of target counter 'counterName' by a value given by 'counterValue'.471        /// Otherwise, sets the denominator component to 'counterValue'.472        /// </summary>473        public override bool SetCounterValue(string counterName, long counterValue, bool isNumerator)474        {475            if (_Disposed)476            {477                ObjectDisposedException objectDisposedException =478                    new ObjectDisposedException("PSCounterSetInstance");479                _tracer.TraceException(objectDisposedException);480                return false;481            }482 483            // retrieve counter id associated with the counter name484            if (counterName == null)485            {486                ArgumentNullException argNullException = new ArgumentNullException(nameof(counterName));487                _tracer.TraceException(argNullException);488                return false;489            }490 491            try492            {493                int targetCounterId = this._counterNameToIdMapping[counterName];494                return this.SetCounterValue(targetCounterId, counterValue, isNumerator);495            }496            catch (KeyNotFoundException)497            {498                InvalidOperationException invalidOperationException =499                    new InvalidOperationException(500                    string.Format(501                    CultureInfo.InvariantCulture,502                    "Lookup for counter corresponding to counter name {0} failed",503                    counterName));504                _tracer.TraceException(invalidOperationException);505                return false;506            }507        }508 509        /// <summary>510        /// This method retrieves the counter value associated with counter 'counterId'511        /// based on isNumerator parameter.512        /// </summary>513        public override bool GetCounterValue(int counterId, bool isNumerator, out long counterValue)514        {515            counterValue = -1;516            if (_Disposed)517            {518                ObjectDisposedException objectDisposedException =519                    new ObjectDisposedException("PSCounterSetInstance");520                _tracer.TraceException(objectDisposedException);521                return false;522            }523 524            int targetCounterId;525            if (base.RetrieveTargetCounterIdIfValid(counterId, isNumerator, out targetCounterId))526            {527                CounterData targetCounterData = _CounterSetInstance.Counters[targetCounterId];528 529                if (targetCounterData != null)530                {531                    counterValue = targetCounterData.Value;532                    return true;533                }534                else535                {536                    InvalidOperationException invalidOperationException =537                        new InvalidOperationException(538                            string.Format(539                            CultureInfo.InvariantCulture,540                            "Lookup for counter corresponding to counter id {0} failed",541                            counterId));542                    _tracer.TraceException(invalidOperationException);543                    return false;544                }545            }546            else547            {548                return false;549            }550        }551 552        /// <summary>553        /// This method retrieves the counter value associated with counter 'counterName'554        /// based on isNumerator parameter.555        /// </summary>556        public override bool GetCounterValue(string counterName, bool isNumerator, out long counterValue)557        {558            counterValue = -1;559            if (_Disposed)560            {561                ObjectDisposedException objectDisposedException =562                    new ObjectDisposedException("PSCounterSetInstance");563                _tracer.TraceException(objectDisposedException);564                return false;565            }566 567            // retrieve counter id associated with the counter name568            if (counterName == null)569            {570                ArgumentNullException argNullException = new ArgumentNullException(nameof(counterName));571                _tracer.TraceException(argNullException);572                return false;573            }574 575            try576            {577                int targetCounterId = this._counterNameToIdMapping[counterName];578                return this.GetCounterValue(targetCounterId, isNumerator, out counterValue);579            }580            catch (KeyNotFoundException)581            {582                InvalidOperationException invalidOperationException =583                    new InvalidOperationException(584                        string.Format(585                        CultureInfo.InvariantCulture,586                        "Lookup for counter corresponding to counter name {0} failed",587                        counterName));588                _tracer.TraceException(invalidOperationException);589                return false;590            }591        }592 593        #endregion594        #endregion595    }596}597