/*******************************************************************************
* gMix open source project - https://svs.informatik.uni-hamburg.de/gmix/
* Copyright (C) 2014 SVS
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package staticContent.evaluation.traceParser.engine.dataStructure;
import java.io.IOException;
import java.util.Vector;
import staticContent.evaluation.traceParser.engine.Protocol;
import staticContent.evaluation.traceParser.engine.fileReader.FlowGroupFlowIterator;
import staticContent.evaluation.traceParser.engine.fileReader.FlowIterator;
import staticContent.evaluation.traceParser.interfaces.FlowFilter;
import staticContent.evaluation.traceParser.statistics.calculator.Stat;
import staticContent.framework.util.Util;
public class ExtendedHost extends Host {
private static final long serialVersionUID = -890714043677144719L;
private transient boolean statCalculationDone = false;
public ExtendedHost(FlowFilter filter) {
super(filter);
}
/**
* use this method to calculate and store some statistic values about this host.
* after the calculation, the flowGroups data structure will be cleared.
* this method is supposed to be used to gather statistics of large trace
* files that do not fit into ram (while iterating the trace).
* flowGroups data structure will be no longer available after this call.
* use recreateFlowGroups() to load the flow groups from the trace file again
* at a later point in time
*/
public void calculateStatistics() {
if (statCalculationDone)
return;
this.statCalculationDone = true;
calculateStatistics(this);
this.flowGroups.clear();
}
public void calculateStatistics(FlowIterator source) {
if (statCalculationDone)
return;
this.statCalculationDone = true;
calculateStatistics(source, this);
this.flowGroups.clear();
}
public static void calculateStatistics(Host h) {
if (h.flowGroups == null || h.flowGroups.size() == 0)
throw new RuntimeException("use loadFlowGroups()");
calculateStatistics(h.getFlowIterator(), h);
}
public static void calculateStatistics(FlowIterator source, Host h) {
try {
h.stat_numberOfFlows = 0;
h.stat_avgUserThinkTime = Util.NOT_SET;
h.stat_minUserThinkTime = Util.NOT_SET;
h.stat_maxUserThinkTime = Util.NOT_SET;
h.stat_protocolDistributionPerFlow = new int[Protocol.values().length];
Stat userThinkTimePerFlowGroup = new Stat();
Vector<Integer> userThinkTimes = new Vector<Integer>();
Stat durationPerFlowGroup = new Stat();
Stat flowsPerFlowGroup = new Stat();
Stat requestBytesPerFlow = new Stat();
Stat replyBytesPerFlow = new Stat();
Stat durationPerFlow = new Stat();
long firstActivity = Long.MAX_VALUE;
long latestActivity = Long.MIN_VALUE;
h.stat_numberOfFlowGroups = 0;
long endOfLastFlowGroup = 0;
while (source.hasNextFlow() && source.peekNextFlow().senderId == h.hostId) { // for each flow group
h.stat_numberOfFlowGroups++;
long fg_numberOfFlows = 0;
long fg_start = Long.MIN_VALUE;
long fg_end = Long.MAX_VALUE;
//long fg_userThinkTime = 0;
fg_start = source.peekNextFlow().startOfFlow;
fg_end = source.peekNextFlow().endOfFlow;
FlowGroupFlowIterator flows = source.getFlowGroupFlowIterator();
Flow flow;
while (flows.hasNext()) { // for each flow of the current flow group
flow = flows.next();
fg_numberOfFlows++;
if (flow.endOfFlow > fg_end)
fg_end = flow.endOfFlow;
requestBytesPerFlow.addValue(flow.requestSize);
replyBytesPerFlow.addValue(flow.replySize);
durationPerFlow.addValue(flow.endOfFlow - flow.startOfFlow);
assert (flow.endOfFlow - flow.startOfFlow) >= 0;
h.stat_protocolDistributionPerFlow[flow.layer4protocol.ordinal()]++;
}
if (h.stat_numberOfFlowGroups == 1) { // first flow group
firstActivity = fg_start;
latestActivity = fg_end;
endOfLastFlowGroup = fg_end;
} else {
if (fg_end > latestActivity)
latestActivity = fg_end;
userThinkTimePerFlowGroup.addValue(fg_start - endOfLastFlowGroup);
userThinkTimes.add((int) (fg_start - endOfLastFlowGroup));
endOfLastFlowGroup = fg_end;
}
durationPerFlowGroup.addValue(fg_end - fg_start);
flowsPerFlowGroup.addValue(fg_numberOfFlows);
assert (fg_end - fg_start) >= 0;
h.stat_numberOfFlows += fg_numberOfFlows;
}
// aggregate results:
h.stat_onlineTime = (int)(latestActivity - firstActivity);
h.firstAction = firstActivity;
h.lastAction = latestActivity;
h.stat_requestBytesTransferred = Math.round(requestBytesPerFlow.getSum());
h.stat_replyBytesTransferred = Math.round(replyBytesPerFlow.getSum());
if (h.stat_onlineTime > 0) { // a host that sent only one packet will have a online time of 0 ms as we need at least two packets for an interval -> ignore those hosts (-> otherwise results will be strongly biased by those hosts -> "infinity")
h.stat_avgRequestBytesPerSec = requestBytesPerFlow.getAvg() / ((double)h.stat_onlineTime/1000d);
h.stat_avgReplyBytesPerSec = replyBytesPerFlow.getAvg() / ((double)h.stat_onlineTime/1000d);
h.stat_avgNewFlowsPerSec = (double)h.stat_numberOfFlows / ((double)h.stat_onlineTime/1000d);
}
h.stat_avgFlowsPerFlowGroup = flowsPerFlowGroup.getAvg();
h.stat_minFlowsPerFlowGroup = (int) flowsPerFlowGroup.getMin();
h.stat_maxFlowsPerFlowGroup = (int) flowsPerFlowGroup.getMax();
h.stat_avgRequestBytesPerFlow = (int) Math.round(requestBytesPerFlow.getAvg());
h.stat_minRequestBytesPerFlow = (int) requestBytesPerFlow.getMin();
h.stat_maxRequestBytesPerFlow = (int) requestBytesPerFlow.getMax();
h.stat_avgReplyBytesPerFlow = (int) Math.round(replyBytesPerFlow.getAvg());
h.stat_minReplyBytesPerFlow = (int) replyBytesPerFlow.getMin();
h.stat_maxReplyBytesPerFlow = (int) replyBytesPerFlow.getMax();
if (h.stat_numberOfFlowGroups > 1) {
h.stat_avgUserThinkTime = (int) Math.round(userThinkTimePerFlowGroup.getAvg());
h.stat_minUserThinkTime = (int) Math.round(userThinkTimePerFlowGroup.getMin());
h.stat_maxUserThinkTime = (int) Math.round(userThinkTimePerFlowGroup.getMax());
h.stat_userThinkTimes = Util.toIntArray(userThinkTimes);
}
h.stat_avgFlowDuration = (int) Math.round(durationPerFlow.getAvg());
h.stat_minFlowDuration = (int) Math.round(durationPerFlow.getMin());
h.stat_maxFlowDuration = (int) Math.round(durationPerFlow.getMax());
h.stat_avgFlowGroupDuration = (int) Math.round(durationPerFlowGroup.getAvg());
h.stat_minFlowGroupDuration = (int) Math.round(durationPerFlowGroup.getMin());
h.stat_maxFlowGroupDuration = (int) Math.round(durationPerFlowGroup.getMax());
//h.hostId = h.flowGroups.get(0).senderId;
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("could not read " +source);
}
}
/* public static void calculateStatistics(Host h) {
h.stat_numberOfFlows = 0;
h.stat_avgUserThinkTime = Util.NOT_SET;
h.stat_minUserThinkTime = Util.NOT_SET;
h.stat_maxUserThinkTime = Util.NOT_SET;
h.stat_protocolDistributionPerFlow = new int[Protocol.values().length];
Stat userThinkTimePerFlowGroup = new Stat();
Stat durationPerFlowGroup = new Stat();
Stat flowsPerFlowGroup = new Stat();
Stat requestBytesPerFlow = new Stat();
Stat replyBytesPerFlow = new Stat();
Stat durationPerFlow = new Stat();
h.stat_numberOfFlowGroups = h.flowGroups.size();
long firstActivity = 0;
long latestActivity = 0;
for (int i=0; i<h.flowGroups.size(); i++) { // for each flow group
FlowGroup flowGroup = h.flowGroups.get(i);
if (i == 0) {
firstActivity = flowGroup.start;
latestActivity = flowGroup.end;
} else {
if (flowGroup.end > latestActivity)
latestActivity = flowGroup.end;
userThinkTimePerFlowGroup.addValue(flowGroup.startDelay);
}
durationPerFlowGroup.addValue(flowGroup.end - flowGroup.start);
flowsPerFlowGroup.addValue(flowGroup.flows.size());
assert (flowGroup.end - flowGroup.start) >= 0;
h.stat_numberOfFlows += flowGroup.flows.size();
for (Flow flow: flowGroup.flows) { // for each flow of the current flow group
requestBytesPerFlow.addValue(flow.requestSize);
replyBytesPerFlow.addValue(flow.replySize);
durationPerFlow.addValue(flow.endOfFlow - flow.startOfFlow);
assert (flow.endOfFlow - flow.startOfFlow) >= 0;
h.stat_protocolDistributionPerFlow[flow.layer4protocol.ordinal()]++;
}
}
// aggregate results:
h.stat_onlineTime = (int)(latestActivity - firstActivity);
h.firstAction = firstActivity;
h.lastAction = latestActivity;
h.stat_requestBytesTransferred = Math.round(requestBytesPerFlow.getSum());
h.stat_replyBytesTransferred = Math.round(replyBytesPerFlow.getSum());
if (h.stat_onlineTime > 0) { // a host that sent only one packet will have a online time of 0 ms as we need at least two packets for an interval -> ignore those hosts (-> otherwise results will be strongly biased by those hosts -> "infinity")
h.stat_avgRequestBytesPerSec = requestBytesPerFlow.getAvg() / ((double)h.stat_onlineTime/1000d);
h.stat_avgReplyBytesPerSec = replyBytesPerFlow.getAvg() / ((double)h.stat_onlineTime/1000d);
h.stat_avgNewFlowsPerSec = (double)h.stat_numberOfFlows / ((double)h.stat_onlineTime/1000d);
}
h.stat_avgFlowsPerFlowGroup = flowsPerFlowGroup.getAvg();
h.stat_minFlowsPerFlowGroup = (int) flowsPerFlowGroup.getMin();
h.stat_maxFlowsPerFlowGroup = (int) flowsPerFlowGroup.getMax();
h.stat_avgRequestBytesPerFlow = (int) Math.round(requestBytesPerFlow.getAvg());
h.stat_minRequestBytesPerFlow = (int) requestBytesPerFlow.getMin();
h.stat_maxRequestBytesPerFlow = (int) requestBytesPerFlow.getMax();
h.stat_avgReplyBytesPerFlow = (int) Math.round(replyBytesPerFlow.getAvg());
h.stat_minReplyBytesPerFlow = (int) replyBytesPerFlow.getMin();
h.stat_maxReplyBytesPerFlow = (int) replyBytesPerFlow.getMax();
if (h.flowGroups.size() > 1) {
h.stat_avgUserThinkTime = (int) Math.round(userThinkTimePerFlowGroup.getAvg());
h.stat_minUserThinkTime = (int) Math.round(userThinkTimePerFlowGroup.getMin());
h.stat_maxUserThinkTime = (int) Math.round(userThinkTimePerFlowGroup.getMax());
h.stat_userThinkTimes = new int[h.flowGroups.size()-1];
for (int i=0; i<h.stat_userThinkTimes.length; i++)
h.stat_userThinkTimes[i] = (int)h.flowGroups.get(i+1).startDelay;
}
h.stat_avgFlowDuration = (int) Math.round(durationPerFlow.getAvg());
h.stat_minFlowDuration = (int) Math.round(durationPerFlow.getMin());
h.stat_maxFlowDuration = (int) Math.round(durationPerFlow.getMax());
h.stat_avgFlowGroupDuration = (int) Math.round(durationPerFlowGroup.getAvg());
h.stat_minFlowGroupDuration = (int) Math.round(durationPerFlowGroup.getMin());
h.stat_maxFlowGroupDuration = (int) Math.round(durationPerFlowGroup.getMax());
h.hostId = h.flowGroups.get(0).senderId;
}*/
}