Example #1
0
            /// <summary>
            /// Update the weighted moving average for the available results.
            /// </summary>
            /// <remarks>
            /// Results are stored in <see cref="WeightedResult"/> if there are results to compute.
            /// </remarks>
            public void Update()
            {
                if (m_NumResults == 0)
                {
                    return; // Nothing to do
                }

                // The specified weight is a percentage [0.0f..1.0f], so we'll
                // use 100.0 as our "arbitrary" weighing value. Do not use a
                // weight if there is only one result.
                float currentResultWeight = ((m_NumResults == 1) ? 1.0f : m_Weight) * 100.0f;

                // Give the current result the appropriate weight.  We'll cast back to integer at the end.
                QosStatsResult currentResult      = m_Results[m_CurrentResult];
                float          weightedLatencyMs  = currentResult.LatencyMs * (currentResultWeight / 100.0f);
                float          weightedPacketLoss = currentResult.PacketLoss * (currentResultWeight / 100.0f);

                // Combine the remaining results and apply the remainder of the weight equally.
                if (m_NumResults > 1)
                {
                    float remainingWeightPerResult = (100.0f - currentResultWeight) / (m_NumResults - 1);
                    uint  nextValidIndex           = NextValidIndex(m_CurrentResult); // find the index of the next set of valid results.
                    for (int i = 0; i < m_NumResults - 1; ++i)                        // m_NumResults-1 so we don't include the currentResult again
                    {
                        QosStatsResult result = m_Results[(nextValidIndex + i) % m_MaxResults];
                        weightedLatencyMs  += result.LatencyMs * (remainingWeightPerResult / 100.0f);
                        weightedPacketLoss += result.PacketLoss * (remainingWeightPerResult / 100.0f);
                    }
                }

                WeightedResult = new QosStatsResult(
                    Mathf.RoundToInt(weightedLatencyMs),
                    Mathf.Min(weightedPacketLoss, 1.0f));  // Make sure precision issues don't yield >100% packet loss
            }
Example #2
0
            public WeightedMovingAverage(uint numResults, float weightOfCurrentResult)
            {
                m_MaxResults = numResults;
                m_Weight     = weightOfCurrentResult;

                // Initial results are flagged as invalid until we have some results.
                m_Results = new QosStatsResult[m_MaxResults];
                for (int i = 0; i < m_MaxResults; ++i)
                {
                    m_Results[i] = new QosStatsResult(-1, -1f);
                }
                WeightedResult = new QosStatsResult(-1, -1f);
            }
Example #3
0
            public void AddResult(QosStatsResult result, bool updateAfterAdd = false)
            {
                if (m_NumResults < m_MaxResults)
                {
                    ++m_NumResults;
                }

                m_CurrentResult            = (m_CurrentResult + 1) % m_NumResults;
                m_Results[m_CurrentResult] = result;

                if (updateAfterAdd)
                {
                    Update();
                }
            }
Example #4
0
        /// <summary>
        /// Get an array of all the results currently being tracked for the given key.
        /// </summary>
        /// <param name="ipAndPort">IP:Port string to get results for</param>
        /// <param name="results">Array of results (unweighted) used to compute the weighted average.</param>
        /// <returns>true if record(s) were found, false if key does not exist or no valid records found</returns>
        /// <remarks>There is no way to determine which results correspond to the most recently added results.</remarks>
        public bool TryGetAllResults(string ipAndPort, out QosStatsResult[] results)
        {
            m_ResultsLock.EnterReadLock();
            try
            {
                if (!m_Results.TryGetValue(ipAndPort, out WeightedMovingAverage wma))
                {
                    results = new QosStatsResult[0];
                    return(false);
                }

                wma.AllResults(out results);
                return(results.Length > 0);
            }
            finally
            {
                m_ResultsLock.ExitReadLock();
            }
        }
Example #5
0
        /// <summary>
        /// Get the weighted rolling average for the given key.
        /// </summary>
        /// <param name="ipAndPort">IP:Port string to get results for</param>
        /// <param name="result">The weighted rolling average for the given ipAndPort</param>
        /// <returns>true if the record was found, false otherwise</returns>
        public bool TryGetWeightedAverage(string ipAndPort, out QosStatsResult result)
        {
            m_ResultsLock.EnterReadLock();
            try
            {
                if (!m_Results.TryGetValue(ipAndPort, out WeightedMovingAverage wma))
                {
                    result = new QosStatsResult(-1, -1f); // Make result invalid
                    return(false);
                }

                wma.Update();
                result = wma.WeightedResult.IsValid() ? wma.WeightedResult : new QosStatsResult(-1, -1f);
                return(result.IsValid());
            }
            finally
            {
                m_ResultsLock.ExitReadLock();
            }
        }
Example #6
0
 public void AllResults(out QosStatsResult[] results)
 {
     results = new QosStatsResult[m_Results.Length];
     m_Results.CopyTo(results, 0);
 }