📄 stats.java
字号:
/** * simulator/Stats.java */package simulator;import java.io.File;import java.io.FileWriter;import java.io.BufferedWriter;import java.io.IOException;import java.util.HashMap;import java.util.Map.Entry;import java.util.Iterator;import java.util.ArrayList;import java.util.Set;import util.CommandStatus;/** * */public class Stats extends CommandParser{ public static Message.Header MSG_CREATE_PRED_DELAY = new Message.Header(); public static Message.Header MSG_SEND_PRED_DELAY = new Message.Header(); public static Message.Header MSG_SEND_TIME = new Message.Header(); public static final int STAT_TYPE_MSG = 0; public static final int STAT_TYPE_CNT = 1; public static final int MSG_CREATED = 101; public static final int MSG_DELIVERED = 102; public static final int MSG_DROPPED_OOBUF = 103; public static final int MSG_ACKED = 104; public static final int CNT_MSG_SENT = 201; private ArrayList<HashMap<Object, ArrayList<StatEntry>>> statData = new ArrayList<HashMap<Object, ArrayList<StatEntry>>>(); private OutputDesc outputDesc = null; private HashMap<String, String> vars = new HashMap<String, String>(); private HashMap<String, StatFilter> knownFilters = null; private HashMap<String, StatFieldInterpreter> knownFields = null; private ArrayList<StatFilter> filtersToUse = null; private ArrayList<StatFilter> globalFiltersToUse = null; private StatVals currentStatVals = null; public Stats(Network n) { super(n); knownFilters = new HashMap<String, StatFilter>(1); knownFilters.put("time", new StatTimeFilter()); knownFilters.put("final_history", new FinalHistoryFilter()); } public boolean shouldInclude(int type, Object groupID, ArrayList<StatEntry> entries, StatEntry entry) { if (filtersToUse != null) { Iterator<StatFilter> it = filtersToUse.iterator(); while (it.hasNext()) { if (!it.next().include(this, type, groupID, entries, entry)) return false; } } if (globalFiltersToUse != null) { Iterator<StatFilter> it = globalFiltersToUse.iterator(); while (it.hasNext()) { if (!it.next().include(this, type, groupID, entries, entry)) return false; } } return true; } public void notify(StatEntry entry) { if (!shouldInclude(entry.type, entry.groupID, null, entry)) return; entry = entry.clone(); statData.ensureCapacity(entry.type + 1); while (statData.size() <= entry.type) { statData.add(null); } HashMap<Object, ArrayList<StatEntry>> map = statData.get(entry.type); if (map == null) { map = new HashMap<Object, ArrayList<StatEntry>>(); statData.set(entry.type, map); } ArrayList<StatEntry> arr = map.get(entry.groupID); if (arr == null) { arr = new ArrayList<StatEntry>(); map.put(entry.groupID, arr); } arr.add(entry); } public HashMap<Object, ArrayList<StatEntry>> getData(int type) { if (statData.size() <= type) return null; HashMap<Object, ArrayList<StatEntry>> map = statData.get(type); return map; } public ArrayList<StatEntry> getDataContext(int type, Object contextOb) { HashMap<Object, ArrayList<StatEntry>> map = getData(type); if (map == null) return null; ArrayList<StatEntry> arr = map.get(contextOb); if (arr == null) return null; if (!shouldInclude(type, contextOb, arr, null)) return null; return arr; } public ArrayList<StatEntry> getDataContextMap(int type, HashMap<Object, Object> contextMap) { Object cOb = contextMap.get(type); if (cOb == null) return null; return getDataContext(type, cOb); } private StatVals getStatVals() { if (currentStatVals != null) return currentStatVals; StatVals statVals = new StatVals(); double totalTime = 0; double totalACKTime = 0; Iterator<Entry<Object, ArrayList<StatEntry>>> it = null; HashMap<Object, ArrayList<StatEntry>> map = getData(STAT_TYPE_MSG); if (map != null) { Set<Entry<Object, ArrayList<StatEntry>>> set = map.entrySet(); if (set != null) it = set.iterator(); } while (it != null && it.hasNext()) { Entry<Object, ArrayList<StatEntry>> entry = it.next(); int idx = (Integer) entry.getKey(); double creationTime = -1; ArrayList<StatEntry> arr = entry.getValue(); assert arr != null : "Message ID = " + idx + " was issued, but such a message was not reported as created!"; if (!shouldInclude(STAT_TYPE_MSG, entry.getKey(), arr, null)) continue; Iterator<StatEntry> jt = arr.iterator(); boolean wasDelivered = false; while (jt.hasNext()) { StatMsgEntry e = (StatMsgEntry) jt.next(); if (!shouldInclude(STAT_TYPE_MSG, entry.getKey(), arr, e)) continue; if (e.event == MSG_CREATED) { if (wasDelivered) continue; if (creationTime < 0) { creationTime = e.time; } else { throw new RuntimeException("Double message creation events: " + e.msg); } ++statVals.msgsCreated; statVals.msgsCreatedDataSize += e.msg.getDataLength(); statVals.msgsCreatedProtoSize += e.msg.getProtocolLength(); } else if (e.event == MSG_DELIVERED) { if (wasDelivered) continue; if (creationTime < 0) { throw new RuntimeException("Message delivery event without message creation event: " + e.msg); } ++statVals.msgsDelivered; totalTime += (e.time - creationTime); statVals.msgsDeliveredDataSize += e.msg.getDataLength(); statVals.msgsDeliveredProtoSize += e.msg.getProtocolLength(); wasDelivered = true; } else if (e.event == MSG_DROPPED_OOBUF) { if (wasDelivered) continue; ++statVals.msgsDroppedOOBuf; } else if (e.event == MSG_ACKED) { if (creationTime < 0) { throw new RuntimeException("Message ACKed event without message creation event: " + e.msg); } ++statVals.msgsACKed; totalACKTime += (e.time - creationTime); statVals.msgsACKedDataSize += e.msg.getDataLength(); statVals.msgsACKedProtoSize += e.msg.getProtocolLength(); } else { throw new RuntimeException("Unknown stats event: " + e.event); } } } it = null; map = getData(STAT_TYPE_CNT); if (map != null) { Set<Entry<Object, ArrayList<StatEntry>>> set = map.entrySet(); if (set != null) it = set.iterator(); } while (it != null && it.hasNext()) { Entry<Object, ArrayList<StatEntry>> entry = it.next(); ArrayList<StatEntry> arr = entry.getValue(); if (!shouldInclude(STAT_TYPE_CNT, entry.getKey(), arr, null)) continue; ++statVals.cntUsed; Iterator<StatEntry> jt = arr.iterator(); while (jt.hasNext()) { StatCntEntry e = (StatCntEntry) jt.next(); if (!shouldInclude(STAT_TYPE_CNT, entry.getKey(), arr, e)) continue; if (e.event == CNT_MSG_SENT) { if (e.routing) { ++(statVals.routingTransNum); } else { ++(statVals.dataTransNum); } statVals.dataSize += e.dataSize; statVals.protoSize += e.protoSize; } else { throw new RuntimeException("Unknown stats event: " + e.event); } } } if (statVals.cntUsed > 0) { statVals.avgDataSize = statVals.dataSize / statVals.cntUsed; statVals.avgProtoSize = statVals.protoSize / statVals.cntUsed; statVals.protoOverhead = statVals.avgProtoSize / statVals.avgDataSize; } if (statVals.msgsCreated > 0) { statVals.delivRatio = ((double) statVals.msgsDelivered) / ((double) statVals.msgsCreated); statVals.ACKRatio = ((double) statVals.msgsACKed) / ((double) statVals.msgsCreated); } else { statVals.delivRatio = Double.NaN; statVals.ACKRatio = Double.NaN; } if (statVals.msgsDelivered > 0) statVals.avgDelivTime = totalTime / statVals.msgsDelivered; else statVals.avgDelivTime = Double.NaN; if (statVals.msgsACKed > 0) statVals.avgACKTime = totalTime / statVals.msgsACKed; else statVals.avgACKTime = Double.NaN; currentStatVals = statVals; return statVals; } private String getVar(String var) { String ret = vars.get(var); if (ret != null) return ret; return var; } public CommandStatus parseCommandPart(ArrayList<String> part, String path) { String param = part.get(0); CommandStatus ok = new CommandStatus(CommandStatus.COMMAND_OK); if (param.equals("filter")) { if (part.size() < 2) return null; StatFilter f = knownFilters.get(part.get(1)); if (f == null) return new CommandStatus("Unknown stats filter '" + part.get(1) + "'!"); try { if (filtersToUse == null) filtersToUse = new ArrayList<StatFilter>(1); filtersToUse.add(f.createFilter(part)); } catch (IllegalArgumentException e) { return new CommandStatus("Error loading filter: " + e); } return ok; } if (part.size() < 2 || part.size() > 3) return null; if (param.equals("file") || param.equals("outfile")) { if (part.size() != 2) return null; outputDesc.fileName = getVar(part.get(1)); return ok; } else if (param.equals("data") || param.equals("field")) { if (part.size() == 3) { outputDesc.headers.add(getVar(part.get(1))); outputDesc.fields.add(getVar(part.get(2))); } else { outputDesc.fields.add(getVar(part.get(1))); } return ok; } else if (param.equals("format")) { if (part.size() != 2) return null; outputDesc.fileFormat = getVar(part.get(1)); return ok; } return null; } public boolean splitResults(Stats stat, BufferedWriter output, ArrayList<String> outFields, ArrayList<String> inFields, int fieldNum, HashMap<Object, Object> context, int type) throws IOException { if (context.get(type) == null) { HashMap<Object, ArrayList<StatEntry>> map = getData(type); if (map == null) return false; Iterator<Entry<Object, ArrayList<StatEntry>>> it = map.entrySet().iterator(); boolean ret = false; while (it.hasNext()) { Entry<Object, ArrayList<StatEntry>> entry = it.next(); if (!shouldInclude(type, entry.getKey(), entry.getValue(), null)) continue; context.put(type, entry.getKey()); // The same inField!!! ret |= writeStatsField(stat, output, outFields, inFields, fieldNum, context); } context.remove(type); return ret; } throw new RuntimeException("Split results called for present context type: " + type); } private boolean writeMsgStatus(Stats stat, BufferedWriter output, ArrayList<String> outFields, ArrayList<String> inFields, int fieldNum, HashMap<Object, Object> context) throws IOException { if (context.get(STAT_TYPE_MSG) == null) { return splitResults(stat, output, outFields, inFields, fieldNum, context, STAT_TYPE_MSG); } String out = null; ArrayList<StatEntry> arr = getDataContextMap(STAT_TYPE_MSG, context); if (arr == null) return false; boolean sh = inFields.get(fieldNum).equals("%msg_short_status"); Iterator<StatEntry> jt = arr.iterator(); double time = -1; double creationTime = -1; int how = -1; Message msg = null; while (jt.hasNext()) { StatMsgEntry e = (StatMsgEntry) jt.next(); if (!shouldInclude(STAT_TYPE_MSG, context.get(STAT_TYPE_MSG), arr, e)) continue; msg = e.msg; time = e.time; if (e.event == MSG_CREATED) { how = MSG_CREATED; creationTime = e.time; } else if (e.event == MSG_DELIVERED) { how = MSG_DELIVERED; break; // while (jt.hasNext()) loop } else if (e.event == MSG_DROPPED_OOBUF) { how = MSG_DROPPED_OOBUF; } else { throw new RuntimeException("Unknown Messsage Event: " + e.event); } } if (msg == null) { return false; } if (how == MSG_DELIVERED) { double delay = time - creationTime; if (sh) out = msg.toString() + "D"; else out = msg.toString() + " DELIV: " + time + " (delay: " + delay + ")"; } else if (how == MSG_DROPPED_OOBUF) { if (sh) out = msg.toString() + "B"; else out = msg.toString() + " OOBDROP: " + time; } else if (how == MSG_CREATED) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -