blob: cdd45e1d2b26ceaa9fd26b7af44bec41a05213e2 [file] [log] [blame] [raw]
/***************************************************************************
statistics.cpp
-------------------
begin : Fri Nov 16 2007
copyright : (C) 2007 - 2012 by Roland Riegel
email : feedback@roland-riegel.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "setting.h"
#include "settingstore.h"
#include "statistics.h"
using namespace std;
void Statistics::insertDataFrame(const DataFrame& dataFrame)
{
if(!dataFrame.isValid())
return;
m_dataFrames.push_back(dataFrame);
unsigned int frameCount = m_dataFrames.size();
if(frameCount < 2)
return;
unsigned int averageCount = getAverageWindow();
unsigned int secondCount = getSecondWindow();
if(frameCount > averageCount)
{
m_dataFrames.erase(m_dataFrames.begin(), m_dataFrames.begin() + (frameCount - averageCount));
frameCount = averageCount;
}
vector<DataFrame>::const_reverse_iterator itFrameSecond = m_dataFrames.rbegin();
vector<DataFrame>::const_reverse_iterator itFrameAverage = m_dataFrames.rbegin();
if(frameCount > secondCount)
itFrameSecond += secondCount;
else
itFrameSecond += frameCount - 1;
if(frameCount > averageCount)
itFrameAverage += averageCount;
else
itFrameAverage += frameCount - 1;
calculateAverage(*itFrameSecond, m_dataFrames.back(), m_second);
calculateAverage(*itFrameAverage, m_dataFrames.back(), m_average);
if(frameCount > 2)
calculateMinMax(m_second, m_min, m_max);
else
m_min = m_max = m_second;
}
void Statistics::reset()
{
m_second = DataFrame();
m_average = DataFrame();
m_min = DataFrame();
m_max = DataFrame();
m_dataFrames.clear();
}
float Statistics::getUnitFactor(DataUnit unit, unsigned long long value)
{
float factor = 1.0 / (unit % 2 == 0 ? 8 : 1);
switch(unit)
{
case humanReadableBit:
case humanReadableByte:
for(int i = 0; i < 3; ++i)
{
if(value / factor < 1024)
return factor;
factor *= 1024;
}
return factor;
case humanReadableSiBit:
case humanReadableSiByte:
for(int i = 0; i < 3; i++) {
if(value / factor < 1000) return factor;
factor *= 1000;
}
return factor;
case bit:
case byte:
return factor;
case kibiBit:
case kibiByte:
return factor * 1024;
case mebiBit:
case mebiByte:
return factor * 1024 * 1024;
case gibiBit:
case gibiByte:
return factor * 1024 * 1024 * 1024;
case kiloBit:
case kiloByte:
return factor * 1000;
case megaBit:
case megaByte:
return factor * 1000 * 1000;
case gigaBit:
case gigaByte:
return factor * 1000 * 1000 * 1000;
default: // should never be executed
return factor;
}
}
string Statistics::getUnitString(DataUnit unit, unsigned long long value)
{
const string description = (unit % 2 == 0 ? "Bit" : "Byte");
const string units[] = { "", "Ki", "Mi", "Gi" };
const string si_units[] = { "", "K", "M", "G" };
switch(unit)
{
case humanReadableBit:
case humanReadableByte:
value *= (unit % 2 == 0 ? 8 : 1);
for(int i = 0; i < 3; ++i)
{
if(value < 1024)
return units[i] + description;
value /= 1024;
}
return units[3] + description;
case humanReadableSiBit:
case humanReadableSiByte:
value *= (unit % 2 == 0 ? 8 : 1);
for(int i = 0; i < 3; i++) {
if(value < 1000) return si_units[i] + description;
value /= 1000;
}
return si_units[3] + description;
case bit:
case byte:
return description;
case kibiBit:
case kibiByte:
return "Ki" + description;
case mebiBit:
case mebiByte:
return "Mi" + description;
case gibiBit:
case gibiByte:
return "Gi" + description;
case kiloBit:
case kiloByte:
return "K" + description;
case megaBit:
case megaByte:
return "M" + description;
case gigaBit:
case gigaByte:
return "G" + description;
default: // should never be executed
return description;
}
}
void Statistics::calculateAverage(const DataFrame& dataFrameFrom, const DataFrame& dataFrameTo, DataFrame& result)
{
float timeSpan = (dataFrameTo.getTimeStampSeconds() + dataFrameTo.getTimeStampMicroseconds() / 1000000.0) -
(dataFrameFrom.getTimeStampSeconds() + dataFrameFrom.getTimeStampMicroseconds() / 1000000.0);
if(timeSpan <= 0)
return;
result.setTotalDataIn((unsigned long long)((dataFrameTo.getTotalDataIn() - dataFrameFrom.getTotalDataIn()) / timeSpan));
result.setTotalDataOut((unsigned long long)((dataFrameTo.getTotalDataOut() - dataFrameFrom.getTotalDataOut()) / timeSpan));
result.setTotalPacketsIn((unsigned long long)((dataFrameTo.getTotalPacketsIn() - dataFrameFrom.getTotalPacketsIn()) / timeSpan));
result.setTotalPacketsOut((unsigned long long)((dataFrameTo.getTotalPacketsOut() - dataFrameFrom.getTotalPacketsOut()) / timeSpan));
result.setTotalErrorsIn((unsigned long long)((dataFrameTo.getTotalErrorsIn() - dataFrameFrom.getTotalErrorsIn()) / timeSpan));
result.setTotalErrorsOut((unsigned long long)((dataFrameTo.getTotalErrorsOut() - dataFrameFrom.getTotalErrorsOut()) / timeSpan));
result.setTotalDropsIn((unsigned long long)((dataFrameTo.getTotalDropsIn() - dataFrameFrom.getTotalDropsIn()) / timeSpan));
result.setTotalDropsOut((unsigned long long)((dataFrameTo.getTotalDropsOut() - dataFrameFrom.getTotalDropsOut()) / timeSpan));
}
void Statistics::calculateMinMax(const DataFrame& dataFrame, DataFrame& min, DataFrame& max)
{
if(dataFrame.getTotalDataIn() < min.getTotalDataIn())
min.setTotalDataIn(dataFrame.getTotalDataIn());
if(dataFrame.getTotalDataIn() > max.getTotalDataIn())
max.setTotalDataIn(dataFrame.getTotalDataIn());
if(dataFrame.getTotalDataOut() < min.getTotalDataOut())
min.setTotalDataOut(dataFrame.getTotalDataOut());
if(dataFrame.getTotalDataOut() > max.getTotalDataOut())
max.setTotalDataOut(dataFrame.getTotalDataOut());
if(dataFrame.getTotalPacketsIn() < min.getTotalPacketsIn())
min.setTotalPacketsIn(dataFrame.getTotalPacketsIn());
if(dataFrame.getTotalPacketsIn() > max.getTotalPacketsIn())
max.setTotalPacketsIn(dataFrame.getTotalPacketsIn());
if(dataFrame.getTotalPacketsOut() < min.getTotalPacketsOut())
min.setTotalPacketsOut(dataFrame.getTotalPacketsOut());
if(dataFrame.getTotalPacketsOut() > max.getTotalPacketsOut())
max.setTotalPacketsOut(dataFrame.getTotalPacketsOut());
if(dataFrame.getTotalErrorsIn() < min.getTotalErrorsIn())
min.setTotalErrorsIn(dataFrame.getTotalErrorsIn());
if(dataFrame.getTotalErrorsIn() > max.getTotalErrorsIn())
max.setTotalErrorsIn(dataFrame.getTotalErrorsIn());
if(dataFrame.getTotalErrorsOut() < min.getTotalErrorsOut())
min.setTotalErrorsOut(dataFrame.getTotalErrorsOut());
if(dataFrame.getTotalErrorsOut() > max.getTotalErrorsOut())
max.setTotalErrorsOut(dataFrame.getTotalErrorsOut());
if(dataFrame.getTotalDropsIn() < min.getTotalDropsIn())
min.setTotalDropsIn(dataFrame.getTotalDropsIn());
if(dataFrame.getTotalDropsIn() > max.getTotalDropsIn())
max.setTotalDropsIn(dataFrame.getTotalDropsIn());
if(dataFrame.getTotalDropsOut() < min.getTotalDropsOut())
min.setTotalDropsOut(dataFrame.getTotalDropsOut());
if(dataFrame.getTotalDropsOut() > max.getTotalDropsOut())
max.setTotalDropsOut(dataFrame.getTotalDropsOut());
}
unsigned int Statistics::getAverageWindow()
{
unsigned int refreshInterval = SettingStore::get("RefreshInterval");
unsigned int averageWindow = SettingStore::get("AverageWindow");
return (unsigned int) (1000.0 / refreshInterval * averageWindow);
}
unsigned int Statistics::getSecondWindow()
{
unsigned int refreshInterval = SettingStore::get("RefreshInterval");
unsigned int secondWindow = (unsigned int) (1000.0 / refreshInterval);
return secondWindow > 0 ? secondWindow : 1;
}