📄 stats.java
字号:
try { output = new BufferedWriter(new FileWriter(outputFile, true)); } catch (IOException e) { return new CommandStatus("Error opening file '" + outputFile + "' for writing/appending: " + e); } try { if (writeHeaders) { Iterator<String> it = outputDesc.headers.iterator(); while (it.hasNext()) { output.append(it.next()); if (it.hasNext()) output.append(";\t"); else output.newLine(); } } writeStats(outputDesc, output); if (filtersToUse != null) filtersToUse.clear(); } catch (IOException e) { return new CommandStatus("Error writing to file '" + outputFile + "': " + e); } try { output.close(); } catch (IOException e) { return new CommandStatus("Error closing file '" + outputFile + "' after writing/appending: " + e); } return ret; } else if (first.get(0).equals("register")) { Iterator<ArrayList<String>> it = args.iterator(); while (it.hasNext()) { ArrayList<String> arg = it.next(); if (arg.size() != 2 || arg.get(0).length() < 1 || arg.get(1).length() < 1) { return new CommandStatus("Wrong parameter for stats.register command: " + arg); } String name = arg.get(0); if (name.charAt(0) != '%') { return new CommandStatus("Wrong parameter for stats.register command: " + arg + "; Registered names must begin with '%' sign."); } vars.put(arg.get(0), arg.get(1)); } return new CommandStatus(CommandStatus.COMMAND_OK); } else if (first.get(0).equals("global")) { int i, s = args.size(); CommandStatus ok = new CommandStatus(CommandStatus.COMMAND_OK); ret = null; for (i = 0; i < s; ++i) { if (args.get(i).size() < 2) { return new CommandStatus("Strange global command"); } ArrayList<String> part = args.get(i); if (part.get(0).equals("filter")) { StatFilter f = knownFilters.get(part.get(1)); if (f == null) return new CommandStatus("Unknown stats filter '" + part.get(1) + "'!"); try { if (globalFiltersToUse == null) globalFiltersToUse = new ArrayList<StatFilter>(1); globalFiltersToUse.add(f.createFilter(part)); } catch (IllegalArgumentException e) { return new CommandStatus("Error loading filter: " + e); } ret = ok; } else { return new CommandStatus("Unknown global command: " + part.get(0)); } } } return new CommandStatus("Unknown stats command: " + first.get(0)); } public void registerFilter(String name, StatFilter filter) { knownFilters.put(name, filter); } public void unregisterFilter(String name) { knownFilters.remove(name); } public void registerFieldInterpreter(String handle, StatFieldInterpreter interp) { if (knownFields == null) knownFields = new HashMap<String, StatFieldInterpreter>(); knownFields.put(handle, interp); } public void unregisterFieldInterpreter(String handle) { if (knownFields != null) knownFields.remove(handle); } private class OutputDesc { public String fileName = null; public String fileFormat = null; public ArrayList<String> headers = null; public ArrayList<String> fields = null; public OutputDesc() { fileName = null; fileFormat = "csv"; headers = new ArrayList<String>(); fields = new ArrayList<String>(); } } public class StatVals { public double delivRatio = -1; public double ACKRatio = -1; public double avgDelivTime = -1; public double avgACKTime = -1; public long msgsCreated = 0; public long msgsCreatedDataSize = 0; public long msgsCreatedProtoSize = 0; public long msgsDelivered = 0; public long msgsDeliveredDataSize = 0; public long msgsDeliveredProtoSize = 0; public long msgsACKed = 0; public long msgsACKedDataSize = 0; public long msgsACKedProtoSize = 0; public long msgsDroppedOOBuf = 0; public long cntUsed = 0; public long dataTransNum = 0; public long routingTransNum = 0; public long dataSize = 0; public long protoSize = 0; public double avgDataSize = -1; public double avgProtoSize = -1; public double protoOverhead = -1; } public static abstract class StatEntry { public double time = -1; public int event = -1; public int type = -1; public Object groupID = null; public StatEntry() { } public StatEntry(StatEntry org) { event = org.event; time = org.time; } public void setup(double t, int e) { event = e; time = t; } public abstract StatEntry clone(); } public static class StatMsgEntry extends StatEntry { public Message msg = null; public StatMsgEntry() { type = STAT_TYPE_MSG; } public StatMsgEntry(StatMsgEntry org) { super(org); msg = org.msg; groupID = org.groupID; type = STAT_TYPE_MSG; } public StatEntry clone() { return new StatMsgEntry(this); } public void setup(Message m, double t, int e) { super.setup(t, e); msg = m; groupID = msg.getId(); } } public static class StatCntEntry extends StatEntry { public Contact contact = null; public Message msg = null; public int protoSize = 0; public int dataSize = 0; public boolean routing = false; public StatCntEntry() { type = STAT_TYPE_CNT; } public StatCntEntry(StatCntEntry org) { super(org); contact = org.contact; msg = org.msg; protoSize = org.protoSize; dataSize = org.dataSize; routing = org.routing; type = STAT_TYPE_CNT; } public StatEntry clone() { return new StatCntEntry(this); } public void setup(double t, int e, Contact ct, Message m) { super.setup(t, e); contact = ct; routing = m.isRoutingMessage(); groupID = ct; if (!routing) { msg = m; } else { msg = null; } dataSize = m.getDataLength(); protoSize = m.getProtocolLength(); // TODO - I don't know now how statistics for data messages with // protocol data should work. // So let's make sure there are no such messages :) assert routing || protoSize == 0; } } public static interface StatFilter { public boolean include(Stats stat, int type, Object groupID, ArrayList<StatEntry> entries, StatEntry entry); public StatFilter createFilter(ArrayList<String> args); } public static interface StatFieldInterpreter { public boolean writeStatsField(Stats stat, BufferedWriter output, ArrayList<String> outFields, ArrayList<String> inFields, int fieldNum, HashMap<Object, Object> context) throws IOException; } public static class FinalHistoryFilter implements StatFilter { public boolean include(Stats stat, int type, Object groupID, ArrayList<StatEntry> entries, StatEntry e) { if (type != STAT_TYPE_MSG) return true; if (entries == null) return true; if (e == null) return true; StatMsgEntry entry = (StatMsgEntry) e; if (entry.event == MSG_DELIVERED) return true; // We have entry which is not final-delivery entry Iterator<StatEntry> it = entries.iterator(); while (it.hasNext()) { StatMsgEntry en = (StatMsgEntry) it.next(); // We have found an entry, which is not 'MSG_CREATED' entry if (en.event != MSG_CREATED) { // But we are asked to say if we want to include MSG_CREATED // entry - we have found other entry, so we don't want // MSG_CREATED entry to be included if (entry.event == MSG_CREATED) return false; // We have found entry which is 'DELIVERED' entry. We are // asked about entry which is not DELIVERED (it was checked // before), so we don't want this entry to be included. if (en.event == MSG_DELIVERED) return false; } } // We want MSG_CREATED entry if there are no other entries, or other // entry if there are no delivery entries. return true; } public StatFilter createFilter(ArrayList<String> args) { FinalHistoryFilter ret = new FinalHistoryFilter(); // Args[0] = filter // Args[1] = final_history if (args.size() != 2) { throw new IllegalArgumentException( "Illegal 'final_history' filter command! It doesn't accept any parameters!"); } return ret; } } public static class StatTimeFilter implements StatFilter { private double tFrom = -1; private double tTo = Double.POSITIVE_INFINITY; public boolean include(Stats stat, int type, Object groupID, ArrayList<StatEntry> entries, StatEntry entry) { switch (type) { case STAT_TYPE_MSG: return includeMsg((StatMsgEntry) entry); case STAT_TYPE_CNT: return includeCnt(entries, (StatCntEntry) entry); } return true; } public boolean includeMsg(StatMsgEntry entry) { if (entry == null) return true; if (entry.msg.getCreationTime() < tFrom || entry.msg.getCreationTime() > tTo) { return false; } return true; } private boolean shouldCount(StatCntEntry e) { // Protocol message - We count only protocol transfers inside time // window. if (e.routing) { assert e.msg == null; if (e.time >= tFrom && e.time <= tTo) { return true; } return false; } // Data message. We count all data transfer of messages CREATED // during time interval whether or not those transfers occur inside // time interval. else { assert e.msg != null; double t = e.msg.getCreationTime(); if (t >= tFrom && t <= tTo) { return true; } return false; } } public boolean includeCnt(ArrayList<StatEntry> entries, StatCntEntry entry) { if (entry == null) { if (entries == null) return true; Iterator<StatEntry> it = entries.iterator(); while (it.hasNext()) { StatCntEntry e = (StatCntEntry) it.next(); if (shouldCount(e)) return true; } return false; } return shouldCount(entry); } public StatFilter createFilter(ArrayList<String> args) { StatTimeFilter ret = new StatTimeFilter(); init(ret, args); return ret; } public void init(StatTimeFilter obj, ArrayList<String> args) { // Args[0] = filter // Args[1] = time // Args[2] = from:to if (args.size() != 3) { throw new IllegalArgumentException( "Illegal 'time' filter command! It should look like this: 'filter=time=time_from:time_to'"); } String desc = args.get(2); int idx = desc.indexOf(":"); if (idx <= 0 || idx >= desc.length()) { throw new IllegalArgumentException( "Illegal 'time' filter command! It should look like this: 'filter=time=time_from:time_to'"); } String a = desc.substring(0, idx); String b = desc.substring(idx + 1); if (a.length() < 1 || b.length() < 1) { throw new IllegalArgumentException( "Illegal 'time' filter command! It should look like this: 'filter=time=time_from:time_to'"); } try { obj.tFrom = Double.parseDouble(a); obj.tTo = Double.parseDouble(b); } catch (NumberFormatException e) { throw new IllegalArgumentException( "Illegal 'time' filter command! It should look like this: 'filter=time=time_from:time_to' - time_from and time_to should be doubles!"); } return; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -