* configstats: Page will now always reflect results of a previous

change, by querying the config instead of StatSummarizer to
   determine if a stat is graphed.
  - Don't append to a string in a loop
  - parseConfig() return a Set instead of List to avoid O(n**2) behavior
    when deteriming config changes
This commit is contained in:
zzz
2013-10-28 21:48:02 +00:00
parent 5bc13c16dc
commit bd0eee6aa9
4 changed files with 37 additions and 19 deletions

View File

@ -50,16 +50,16 @@ public class ConfigStatsHandler extends FormHandler {
public void setGraphList(String stats[]) { public void setGraphList(String stats[]) {
if (stats != null) { if (stats != null) {
String s = ""; StringBuilder s = new StringBuilder(128);
for (int i = 0; i < stats.length; i++) { for (int i = 0; i < stats.length; i++) {
String cur = stats[i].trim(); String cur = stats[i].trim();
if (cur.length() > 0) { if (cur.length() > 0) {
if (s.length() > 0) if (s.length() > 0)
s = s + ","; s.append(",");
s = s + cur; s.append(cur);
} }
} }
_graphs = s; _graphs = s.toString();
} else { } else {
_graphs = ""; _graphs = "";
} }
@ -122,7 +122,7 @@ public class ConfigStatsHandler extends FormHandler {
addFormNotice(_("Restart required to take effect")); addFormNotice(_("Restart required to take effect"));
} }
if (graphsChanged) if (graphsChanged)
addFormNotice(_("Graph list updated, may take up to 60s to be reflected here and on the <a href=\"graphs.jsp\">Graphs Page</a>")); addFormNotice(_("Graph list updated, may take up to 60s to be reflected on the {0}Graphs Page{1}", "<a href=\"graphs\">", "</a>"));
} }
} }

View File

@ -21,9 +21,10 @@ import net.i2p.util.Log;
public class ConfigStatsHelper extends HelperBase { public class ConfigStatsHelper extends HelperBase {
private Log _log; private Log _log;
private String _filter; private String _filter;
private Set<String> _filters; private final Set<String> _filters;
private final Set<String> _graphs;
/** list of names of stats which are remaining, ordered by nested groups */ /** list of names of stats which are remaining, ordered by nested groups */
private List<String> _stats; private final List<String> _stats;
private String _currentStatName; private String _currentStatName;
private String _currentGraphName; private String _currentGraphName;
private String _currentStatDescription; private String _currentStatDescription;
@ -35,6 +36,12 @@ public class ConfigStatsHelper extends HelperBase {
private boolean _currentIsGraphed; private boolean _currentIsGraphed;
private boolean _currentCanBeGraphed; private boolean _currentCanBeGraphed;
public ConfigStatsHelper() {
_stats = new ArrayList();
_filters = new HashSet();
_graphs = new HashSet();
}
/** /**
* Configure this bean to query a particular router context * Configure this bean to query a particular router context
* *
@ -46,7 +53,6 @@ public class ConfigStatsHelper extends HelperBase {
super.setContextId(contextId); super.setContextId(contextId);
_log = _context.logManager().getLog(ConfigStatsHelper.class); _log = _context.logManager().getLog(ConfigStatsHelper.class);
_stats = new ArrayList();
Map<String, SortedSet<String>> unsorted = _context.statManager().getStatsByGroup(); Map<String, SortedSet<String>> unsorted = _context.statManager().getStatsByGroup();
Map<String, Set<String>> groups = new TreeMap(new AlphaComparator()); Map<String, Set<String>> groups = new TreeMap(new AlphaComparator());
groups.putAll(unsorted); groups.putAll(unsorted);
@ -57,10 +63,17 @@ public class ConfigStatsHelper extends HelperBase {
if (_filter == null) if (_filter == null)
_filter = ""; _filter = "";
_filters = new HashSet();
StringTokenizer tok = new StringTokenizer(_filter, ","); StringTokenizer tok = new StringTokenizer(_filter, ",");
while (tok.hasMoreTokens()) while (tok.hasMoreTokens())
_filters.add(tok.nextToken().trim()); _filters.add(tok.nextToken().trim());
// create a local copy of the config. Querying r.getSummaryListener()
// lags behind, as StatSummarizer only runs once a minute.
String specs = _context.getProperty("stat.summaries", StatSummarizer.DEFAULT_DATABASES);
tok = new StringTokenizer(specs, ",");
while (tok.hasMoreTokens()) {
_graphs.add(tok.nextToken().trim());
}
} }
/** /**
@ -100,9 +113,12 @@ public class ConfigStatsHelper extends HelperBase {
if (period <= 10*60*1000) { if (period <= 10*60*1000) {
Rate r = rs.getRate(period); Rate r = rs.getRate(period);
_currentCanBeGraphed = r != null; _currentCanBeGraphed = r != null;
if (_currentCanBeGraphed) if (_currentCanBeGraphed) {
_currentIsGraphed = r.getSummaryListener() != null; // see above
//_currentIsGraphed = r.getSummaryListener() != null;
_currentGraphName = _currentStatName + "." + period; _currentGraphName = _currentStatName + "." + period;
_currentIsGraphed = _graphs.contains(_currentGraphName);
}
} else { } else {
_currentCanBeGraphed = false; _currentCanBeGraphed = false;
} }

View File

@ -7,6 +7,7 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
@ -220,12 +221,12 @@ public class GraphHelper extends FormHandler {
name = _stat; name = _stat;
displayName = _("Bandwidth usage"); displayName = _("Bandwidth usage");
} else { } else {
List<Rate> rates = StatSummarizer.instance().parseSpecs(_stat); Set<Rate> rates = StatSummarizer.instance().parseSpecs(_stat);
if (rates.size() != 1) { if (rates.size() != 1) {
_out.write("Graphs not enabled for " + _stat); _out.write("Graphs not enabled for " + _stat);
return ""; return "";
} }
Rate r = rates.get(0); Rate r = rates.iterator().next();
period = r.getPeriod(); period = r.getPeriod();
name = r.getRateStat().getName(); name = r.getRateStat().getName();
displayName = name; displayName = name;

View File

@ -3,8 +3,9 @@ package net.i2p.router.web;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
@ -96,7 +97,7 @@ public class StatSummarizer implements Runnable {
/** list of SummaryListener instances */ /** list of SummaryListener instances */
List<SummaryListener> getListeners() { return _listeners; } List<SummaryListener> getListeners() { return _listeners; }
private static final String DEFAULT_DATABASES = "bw.sendRate.60000" + static final String DEFAULT_DATABASES = "bw.sendRate.60000" +
",bw.recvRate.60000" + ",bw.recvRate.60000" +
// ",tunnel.testSuccessTime.60000" + // ",tunnel.testSuccessTime.60000" +
// ",udp.outboundActiveCount.60000" + // ",udp.outboundActiveCount.60000" +
@ -127,8 +128,8 @@ public class StatSummarizer implements Runnable {
( (spec != null) && (oldSpecs != null) && (oldSpecs.equals(spec))) ) ( (spec != null) && (oldSpecs != null) && (oldSpecs.equals(spec))) )
return oldSpecs; return oldSpecs;
List<Rate> old = parseSpecs(oldSpecs); Set<Rate> old = parseSpecs(oldSpecs);
List<Rate> newSpecs = parseSpecs(spec); Set<Rate> newSpecs = parseSpecs(spec);
// remove old ones // remove old ones
for (Rate r : old) { for (Rate r : old) {
@ -307,9 +308,9 @@ public class StatSummarizer implements Runnable {
* @param specs statName.period,statName.period,statName.period * @param specs statName.period,statName.period,statName.period
* @return list of Rate objects * @return list of Rate objects
*/ */
List<Rate> parseSpecs(String specs) { Set<Rate> parseSpecs(String specs) {
StringTokenizer tok = new StringTokenizer(specs, ","); StringTokenizer tok = new StringTokenizer(specs, ",");
List<Rate> rv = new ArrayList(); Set<Rate> rv = new HashSet();
while (tok.hasMoreTokens()) { while (tok.hasMoreTokens()) {
String spec = tok.nextToken(); String spec = tok.nextToken();
int split = spec.lastIndexOf('.'); int split = spec.lastIndexOf('.');