/*******************************************************************************
* 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.BufferedReader;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.nio.channels.Channels;
import java.util.HashSet;
import java.util.Vector;
import staticContent.evaluation.traceParser.engine.Protocol;
import staticContent.evaluation.traceParser.engine.TraceInfo;
import staticContent.evaluation.traceParser.engine.fileReader.FlowGroupReader;
import staticContent.evaluation.traceParser.engine.fileReader.FlowIterator;
import staticContent.evaluation.traceParser.engine.fileReader.FlowReader;
import staticContent.evaluation.traceParser.engine.fileReader.HostIndexCreator;
import staticContent.evaluation.traceParser.engine.fileReader.TransientFlowIterator;
import staticContent.evaluation.traceParser.interfaces.FlowFilter;
import staticContent.framework.util.Util;
public class Host implements Serializable {
private static final long serialVersionUID = 3693971555574677995L;
public int hostId;
public long firstAction = Long.MAX_VALUE; // offset from start of trace (timestamp)
public long lastAction = Long.MIN_VALUE;
public long offsetInTraceFile;
/**
* only available after calling loadFlowGroups() (the Host
* data structure is read from an index file. a subset of flows is supposed
* to be selected from the index (based on the stat_* variables below). to
* access the actual flows of a host, flows must be read from the trace
* file (not the index file)). this read operation is triggered by calling
* loadFlowGroups().
* (to get the index, call getHostIndex())
*/
public transient Vector<FlowGroup> flowGroups = new Vector<FlowGroup>();
private transient boolean flowGroupsLoaded = false;
public transient FlowFilter filter;
// statistics values:
public int stat_numberOfFlows = 0;
public int stat_numberOfFlowGroups = 0;
public int stat_onlineTime = 0;
public long stat_requestBytesTransferred = 0;
public long stat_replyBytesTransferred = 0;
public double stat_avgRequestBytesPerSec = 0d;
public double stat_avgReplyBytesPerSec = 0d;
public double stat_avgNewFlowsPerSec = 0d;
public double stat_avgFlowsPerFlowGroup = 0d;
public int stat_minFlowsPerFlowGroup = 0;
public int stat_maxFlowsPerFlowGroup = 0;
public int stat_avgRequestBytesPerFlow = 0;
public int stat_minRequestBytesPerFlow = 0;
public int stat_maxRequestBytesPerFlow = 0;
public int stat_avgReplyBytesPerFlow = 0;
public int stat_minReplyBytesPerFlow = 0;
public int stat_maxReplyBytesPerFlow = 0;
public int stat_avgUserThinkTime = Util.NOT_SET;
public int stat_minUserThinkTime = Util.NOT_SET;
public int stat_maxUserThinkTime = Util.NOT_SET;
public int[] stat_userThinkTimes;
public int stat_avgFlowDuration = 0;
public int stat_minFlowDuration = 0;
public int stat_maxFlowDuration = 0;
public int stat_avgFlowGroupDuration = 0;
public int stat_minFlowGroupDuration = 0;
public int stat_maxFlowGroupDuration = 0;
public int[] stat_protocolDistributionPerFlow = new int[Protocol.values().length];
public int stat_rank_byNumberOfFlows = Util.NOT_SET;
public int stat_rank_byOnlineTime = Util.NOT_SET;
public int stat_rank_byAvgBytesPerSec = Util.NOT_SET;
public int stat_rank_byAvgRequestBytesPerSec = Util.NOT_SET;
public int stat_rank_byAvgReplyBytesPerSec = Util.NOT_SET;
public int stat_rank_byTotalBytesTransferred = Util.NOT_SET;
public int stat_rank_byRequestBytesTransferred = Util.NOT_SET;
public int stat_rank_byReplyBytesTransferred = Util.NOT_SET;
public int stat_rank_byAvgNewFlowsPerSec = Util.NOT_SET;
public Host(FlowFilter filter) {
this.filter = filter;
}
/*public void loadFlowGroups(String pathToTraceFolder) {
loadFlowGroups(new TraceInfo(pathToTraceFolder));
}*/
public void loadFlowGroups(String pathToTraceFolder) {
loadFlowGroups(new TraceInfo(pathToTraceFolder));
}
/*public void loadFlowGroups(TraceInfo traceInfo) {
loadFlowGroups(traceInfo, null);
}*/
public void loadFlowGroups(TraceInfo traceInfo) {
String path = Util.removeFileExtension(traceInfo.getPathToTraceFile()) +".gmf";
try {
RandomAccessFile raf = new RandomAccessFile(path, "r");
loadFlowGroups(raf);
raf.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("could not load flow groups from " +path);
}
}
public void loadFlowGroups(RandomAccessFile raf) {
if (flowGroupsLoaded)
return;
try {
raf.seek(offsetInTraceFile);
// use BufferedReader to read line instead of raf.readLine() for performance reasons:
BufferedReader reader = new BufferedReader(Channels.newReader(raf.getChannel(), "ISO-8859-1"));
FlowGroupReader fgReader = new FlowGroupReader(reader, filter);
assert fgReader.peekNextFlowGroup().senderId == hostId: "" +fgReader.peekNextFlowGroup().senderId +" != " +hostId +" (offset: " +offsetInTraceFile +")";
flowGroups = new Vector<FlowGroup>();
while (fgReader.peekNextFlowGroup() != null && fgReader.peekNextFlowGroup().senderId == hostId)
flowGroups.add(fgReader.readFlowGroup());
flowGroupsLoaded = true;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("could not load flow groups from " +raf);
}
}
public FlowReader getFlowReader(String pathToTraceFolder) {
return getFlowReader(new TraceInfo(pathToTraceFolder));
}
public FlowReader getFlowReader(TraceInfo traceInfo) {
FlowReader result = null;
String path = Util.removeFileExtension(traceInfo.getPathToTraceFile()) +".gmf";
try {
RandomAccessFile raf = new RandomAccessFile(path, "r");
result = getFlowReader(raf);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("could not read " +path);
}
return result;
}
public FlowReader getFlowReader(RandomAccessFile raf) {
FlowReader result = null;
try {
raf.seek(offsetInTraceFile);
// use BufferedReader to read line instead of raf.readLine() for performance reasons:
BufferedReader reader = new BufferedReader(Channels.newReader(raf.getChannel(), "ISO-8859-1"));
result = new FlowReader(reader, filter);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("could not read " +raf);
}
return result;
}
public FlowGroupReader getFlowGroupReader(String pathToTraceFolder) {
return getFlowGroupReader(new TraceInfo(pathToTraceFolder));
}
public FlowGroupReader getFlowGroupReader(TraceInfo traceInfo) {
FlowGroupReader result = null;
String path = Util.removeFileExtension(traceInfo.getPathToTraceFile()) +".gmf";
try {
RandomAccessFile raf = new RandomAccessFile(path, "r");
result = getFlowGroupReader(raf);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("could not read " +path);
}
return result;
}
public FlowGroupReader getFlowGroupReader(RandomAccessFile raf) {
FlowGroupReader result = null;
try {
raf.seek(offsetInTraceFile);
// use BufferedReader to read line instead of raf.readLine() for performance reasons:
BufferedReader reader = new BufferedReader(Channels.newReader(raf.getChannel(), "ISO-8859-1"));
result = new FlowGroupReader(reader, filter);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("could not read " +raf);
}
return result;
}
/*public void loadFlowGroups(RandomAccessFile raf) {
try {
raf.seek(offsetInTraceFile);
// use BufferedReader to read line instead of raf.readLine() for performance reasons:
BufferedReader reader = new BufferedReader(Channels.newReader(raf.getChannel(), "ISO-8859-1"));
String line = reader.readLine();
FlowGroup fg = new FlowGroup(line);
flowGroups = new Vector<FlowGroup>();
do {
assert fg.senderId == hostId;
flowGroups.add(fg);
line = reader.readLine();
fg = line == null ? null : new FlowGroup(line);
} while(fg != null && fg.senderId == hostId);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("could not load flow groups from " +raf);
}
}*/
/**
* use this method to create a modifiable host from a real host.
* a modifiable host is a host who's contents (flows) can be modified
* through several methods, e.g. flows can be cut off after x ms with
* cutOffAfter(long).
* most modifiable hosts are based on "real" hosts (i.e., hosts that were
* present in a real trace file and are thus listed in the HostIndex data
* structure (see HostIndexCreator.java)).
* use this method to clone a host from the host index in order to
* modify it.
* hosts in the HostIndex should NEVER be modified directly (the HostIndex
* will be used by several methods to draw random samples. if the hosts of
* the HostIndex are modified, the random samples will be drawn from
* modified hosts which may introduce none-negligible errors).
*/
public ModifiableHost cloneHost() {
return ModifiableHost.cloneHost(this);
}
/*@Override
public boolean equals(Object obj) {
Host h = (Host)obj;
if ( h.hostId == hostId &&
h.firstAction == firstAction &&
h.lastAction == lastAction &&
h.flowGroups.size() == flowGroups.size()
)
return true;
return false;
}
public String visualEquals(Object obj) {
Host h = (Host)obj;
StringBuffer sb = new StringBuffer();
sb.append("\nhostId: " +h.hostId +", h.hostId: " +hostId);
sb.append("\nfirstAction: " +h.firstAction +", h.firstAction: " +firstAction);
sb.append("\nlastAction: " +h.lastAction +", h.lastAction: " +lastAction);
sb.append("\nflowGroups.size(): " +h.flowGroups.size() +", h.flowGroups.size(): " +flowGroups.size());
return sb.toString();
}*/
public FlowIterator getFlowIterator() {
return new TransientFlowIterator(this);
}
public static Host[] applyBlacklist(Host[] hosts, HashSet<Host> blacklist) {
if (blacklist == null || blacklist.size() == 0)
return hosts;
Host[] result = new Host[hosts.length - blacklist.size()];
int index = 0;
for (int i=0; i<hosts.length; i++)
if (!blacklist.contains(hosts[i]))
result[index++] = hosts[i];
return result;
}
/*public static Host[] getHostIndex(String pathToTraceFolder) {
return getHostIndex(new TraceInfo(pathToTraceFolder));
}*/
/*public static Host[] getHostIndex(TraceInfo traceInfo) {
return HostIndexCreator.getHostIndex(traceInfo);
}*/
public static Host[] getHostIndex(String pathToTraceFolder, FlowFilter filter) {
return getHostIndex(new TraceInfo(pathToTraceFolder), filter);
}
public static Host[] getHostIndex(TraceInfo traceInfo, FlowFilter filter) {
return HostIndexCreator.getHostIndex(traceInfo, filter);
}
}