- Cleanups
    - Remove some locking
    - Change some longs to ints to save space
    - Remove static logs
This commit is contained in:
zzz
2012-01-14 17:44:50 +00:00
parent fc07065413
commit 07957409cb
6 changed files with 92 additions and 49 deletions

View File

@ -19,8 +19,8 @@ import net.i2p.util.Log;
* be instantiated - see StatManager.
*/
public class BufferedStatLog implements StatLog {
private I2PAppContext _context;
private Log _log;
private final I2PAppContext _context;
private final Log _log;
private final StatEvent _events[];
private int _eventNext;
private int _lastWrite;

View File

@ -18,7 +18,6 @@ public class Frequency {
private long _lastEvent;
private final long _start = now();
private long _count;
private final Object _lock = this; // new Object(); // in case we want to do fancy sync later
/** @param period ms */
public Frequency(long period) {
@ -37,9 +36,7 @@ public class Frequency {
* @deprecated unused
*/
public long getLastEvent() {
synchronized (_lock) {
return _lastEvent;
}
}
/**
@ -48,9 +45,7 @@ public class Frequency {
* @return milliseconds; returns period + 1 if no events in previous period
*/
public double getAverageInterval() {
synchronized (_lock) {
return _avgInterval;
}
}
/**
@ -59,9 +54,7 @@ public class Frequency {
* @deprecated unused
*/
public double getMinAverageInterval() {
synchronized (_lock) {
return _minAverageInterval;
}
}
/**
@ -69,7 +62,7 @@ public class Frequency {
* Use getStrictAverageInterval() for the real lifetime average.
*/
public double getAverageEventsPerPeriod() {
synchronized (_lock) {
synchronized (this) {
if (_avgInterval > 0) return _period / _avgInterval;
return 0;
@ -81,7 +74,7 @@ public class Frequency {
* Use getStrictAverageEventsPerPeriod() for the real lifetime average.
*/
public double getMaxAverageEventsPerPeriod() {
synchronized (_lock) {
synchronized (this) {
if (_minAverageInterval > 0 && _minAverageInterval <= _period) return _period / _minAverageInterval;
return 0;
@ -93,12 +86,9 @@ public class Frequency {
* @return milliseconds; returns Double.MAX_VALUE if no events ever
*/
public double getStrictAverageInterval() {
synchronized (_lock) {
long duration = now() - _start;
if ((duration <= 0) || (_count <= 0)) return Double.MAX_VALUE;
return duration / (double) _count;
}
}
/** using the strict average interval, how many events occur within an average period? */
@ -110,9 +100,7 @@ public class Frequency {
/** how many events have occurred within the lifetime of this stat? */
public long getEventCount() {
synchronized (_lock) {
return _count;
}
}
/**
@ -135,7 +123,7 @@ public class Frequency {
* Recalculate, but only update the lastEvent if eventOccurred
*/
private void recalculate(boolean eventOccurred) {
synchronized (_lock) {
synchronized (this) {
// This calculates something of a rolling average interval.
long now = now();
long interval = now - _lastEvent;

View File

@ -3,6 +3,7 @@ package net.i2p.stat;
import java.util.Date;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
@ -12,7 +13,6 @@ import net.i2p.util.Log;
* must be compatible.
*/
class PersistenceHelper {
private final static Log _log = new Log(PersistenceHelper.class);
private final static String NL = System.getProperty("line.separator");
public final static void add(StringBuilder buf, String prefix, String name, String description, double value) {
@ -33,37 +33,62 @@ class PersistenceHelper {
add(buf, prefix, name, description + ' ' + when, value);
}
/** @param value non-negative */
public final static void add(StringBuilder buf, String prefix, String name, String description, long value) {
buf.append("# ").append(prefix).append(name).append(NL);
buf.append("# ").append(description).append(NL);
buf.append(prefix).append(name).append('=').append(value).append(NL).append(NL);
}
/**
* @return non-negative, returns 0 on error
*/
public final static long getLong(Properties props, String prefix, String name) {
String val = props.getProperty(prefix + name);
if (val != null) {
try {
return Long.parseLong(val);
long rv = Long.parseLong(val);
return rv >= 0 ? rv : 0;
} catch (NumberFormatException nfe) {
_log.warn("Error formatting " + val + " into a long", nfe);
Log log = I2PAppContext.getGlobalContext().logManager().getLog(PersistenceHelper.class);
log.warn("Error formatting " + val, nfe);
}
} else {
_log.warn("Key " + prefix + name + " does not exist");
}
return 0;
}
/**
* @return 0 on error
*/
public final static double getDouble(Properties props, String prefix, String name) {
String val = props.getProperty(prefix + name);
if (val != null) {
try {
return Double.parseDouble(val);
} catch (NumberFormatException nfe) {
_log.warn("Error formatting " + val + " into a double", nfe);
Log log = I2PAppContext.getGlobalContext().logManager().getLog(PersistenceHelper.class);
log.warn("Error formatting " + val, nfe);
}
} else {
_log.warn("Key " + prefix + name + " does not exist");
}
return 0;
}
/**
* @return non-negative, returns 0 on error
* @since 0.8.13
*/
public final static int getInt(Properties props, String prefix, String name) {
String val = props.getProperty(prefix + name);
if (val != null) {
try {
int rv = Integer.parseInt(val);
return rv >= 0 ? rv : 0;
} catch (NumberFormatException nfe) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(PersistenceHelper.class);
log.warn("Error formatting " + val, nfe);
}
}
return 0;
}
}

View File

@ -16,13 +16,16 @@ import net.i2p.util.Log;
public class Rate {
//private final static Log _log = new Log(Rate.class);
private volatile double _currentTotalValue;
private volatile long _currentEventCount;
// was long, save space
private volatile int _currentEventCount;
private volatile long _currentTotalEventTime;
private volatile double _lastTotalValue;
private volatile long _lastEventCount;
// was long, save space
private volatile int _lastEventCount;
private volatile long _lastTotalEventTime;
private volatile double _extremeTotalValue;
private volatile long _extremeEventCount;
// was long, save space
private volatile int _extremeEventCount;
private volatile long _extremeTotalEventTime;
private volatile double _lifetimeTotalValue;
private volatile long _lifetimeEventCount;
@ -32,7 +35,8 @@ public class Rate {
private volatile long _lastCoalesceDate;
private long _creationDate;
private long _period;
// was long, save space
private int _period;
/** locked during coalesce and addData */
// private final Object _lock = new Object();
@ -121,15 +125,16 @@ public class Rate {
/**
* A rate with period shorter than Router.COALESCE_TIME = 50*1000 has to
* be manually coalesced before values are fetched from it.
* @param period number of milliseconds in the period this rate deals with
* @throws IllegalArgumentException if the period is not greater than 0
* @param period number of milliseconds in the period this rate deals with, min 1, max Integer.MAX_VALUE
* @throws IllegalArgumentException if the period is invalid
*/
public Rate(long period) throws IllegalArgumentException {
if (period <= 0) throw new IllegalArgumentException("The period must be strictly positive");
if (period <= 0 || period > Integer.MAX_VALUE)
throw new IllegalArgumentException();
_creationDate = now();
_lastCoalesceDate = _creationDate;
_period = period;
_period = (int) period;
}
/**
@ -229,7 +234,7 @@ public class Rate {
// how much were we off by? (so that we can sample down the measured values)
double periodFactor = measuredPeriod / (double)_period;
_lastTotalValue = _currentTotalValue / periodFactor;
_lastEventCount = (long) (0.499999 + (_currentEventCount / periodFactor));
_lastEventCount = (int) (0.499999 + (_currentEventCount / periodFactor));
_lastTotalEventTime = (long) (_currentTotalEventTime / periodFactor);
_lastCoalesceDate = now;
if (_currentEventCount == 0)
@ -255,10 +260,15 @@ public class Rate {
public void setSummaryListener(RateSummaryListener listener) { _summaryListener = listener; }
public RateSummaryListener getSummaryListener() { return _summaryListener; }
/** what was the average value across the events in the last period? */
/**
* What was the average value across the events in the last period?
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*/
public double getAverageValue() {
if ((_lastTotalValue != 0) && (_lastEventCount > 0))
return _lastTotalValue / _lastEventCount;
int lec = _lastEventCount; // avoid race NPE
if ((_lastTotalValue != 0) && (lec > 0))
return _lastTotalValue / lec;
return 0.0D;
}
@ -266,6 +276,8 @@ public class Rate {
/**
* During the extreme period (i.e. the period with the highest total value),
* what was the average value?
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*/
public double getExtremeAverageValue() {
if ((_extremeTotalValue != 0) && (_extremeEventCount > 0))
@ -274,7 +286,11 @@ public class Rate {
return 0.0D;
}
/** what was the average value across the events since the stat was created? */
/**
* What was the average value across the events since the stat was created?
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*/
public double getLifetimeAverageValue() {
if ((_lifetimeTotalValue != 0) && (_lifetimeEventCount > 0))
return _lifetimeTotalValue / _lifetimeEventCount;
@ -306,6 +322,8 @@ public class Rate {
* how much of the time was spent actually processing events
* in proportion to how many events could have occurred if there were no intervals?
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*
* @return ratio, or 0 if the statistic doesn't use event times
*/
public double getExtremeEventSaturation() {
@ -321,6 +339,8 @@ public class Rate {
* During the lifetime of this stat, how much of the time was spent actually processing events in proportion
* to how many events could have occurred if there were no intervals?
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*
* @return ratio, or 0 if event times aren't used
*/
public double getLifetimeEventSaturation() {
@ -345,6 +365,8 @@ public class Rate {
* using the last period's rate, what is the total value that could have been sent
* if events were constant?
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*
* @return max total value, or 0 if event times aren't used
*/
public double getLastSaturationLimit() {
@ -362,6 +384,8 @@ public class Rate {
* what is the total value that could have been
* sent if events were constant?
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*
* @return event total at saturation, or 0 if no event times are measured
*/
public double getExtremeSaturationLimit() {
@ -379,6 +403,8 @@ public class Rate {
* What was the total value, compared to the total value in
* the extreme period (i.e. the period with the highest total value),
* Warning- returns ratio, not percentage (i.e. it is not multiplied by 100 here)
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*/
public double getPercentageOfExtremeValue() {
if ((_lastTotalValue != 0) && (_extremeTotalValue != 0))
@ -390,6 +416,8 @@ public class Rate {
/**
* How large was the last period's value as compared to the lifetime average value?
* Warning- returns ratio, not percentage (i.e. it is not multiplied by 100 here)
*
* Warning - unsynchronized, might glitch during coalesce, caller may prevent by synchronizing on this.
*/
public double getPercentageOfLifetimeValue() {
if ((_lastTotalValue != 0) && (_lifetimeTotalValue != 0)) {
@ -450,17 +478,17 @@ public class Rate {
* @throws IllegalArgumentException if the data was formatted incorrectly
*/
public void load(Properties props, String prefix, boolean treatAsCurrent) throws IllegalArgumentException {
_period = PersistenceHelper.getLong(props, prefix, ".period");
_period = PersistenceHelper.getInt(props, prefix, ".period");
_creationDate = PersistenceHelper.getLong(props, prefix, ".creationDate");
_lastCoalesceDate = PersistenceHelper.getLong(props, prefix, ".lastCoalesceDate");
_currentTotalValue = PersistenceHelper.getDouble(props, prefix, ".currentTotalValue");
_currentEventCount = PersistenceHelper.getLong(props, prefix, ".currentEventCount");
_currentEventCount = PersistenceHelper.getInt(props, prefix, ".currentEventCount");
_currentTotalEventTime = PersistenceHelper.getLong(props, prefix, ".currentTotalEventTime");
_lastTotalValue = PersistenceHelper.getDouble(props, prefix, ".lastTotalValue");
_lastEventCount = PersistenceHelper.getLong(props, prefix, ".lastEventCount");
_lastEventCount = PersistenceHelper.getInt(props, prefix, ".lastEventCount");
_lastTotalEventTime = PersistenceHelper.getLong(props, prefix, ".lastTotalEventTime");
_extremeTotalValue = PersistenceHelper.getDouble(props, prefix, ".extremeTotalValue");
_extremeEventCount = PersistenceHelper.getLong(props, prefix, ".extremeEventCount");
_extremeEventCount = PersistenceHelper.getInt(props, prefix, ".extremeEventCount");
_extremeTotalEventTime = PersistenceHelper.getLong(props, prefix, ".extremeTotalEventTime");
_lifetimeTotalValue = PersistenceHelper.getDouble(props, prefix, ".lifetimeTotalValue");
_lifetimeEventCount = PersistenceHelper.getLong(props, prefix, ".lifetimeEventCount");

View File

@ -7,12 +7,12 @@ import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
/** coordinate a moving rate over various periods */
public class RateStat {
private final static Log _log = new Log(RateStat.class);
/** unique name of the statistic */
private final String _statName;
/** grouping under which the stat is kept */
@ -223,8 +223,9 @@ public class RateStat {
Rate rate = new Rate(period);
rate.setRateStat(this);
_rates.put(rate.getPeriod(), rate);
if (_log.shouldLog(Log.WARN))
_log.warn("Rate for " + prefix + " is corrupt, reinitializing that period");
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RateStat.class);
if (log.shouldLog(Log.WARN))
log.warn("Rate for " + prefix + " is corrupt, reinitializing that period");
}
}
}

View File

@ -6,6 +6,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
@ -213,18 +214,18 @@ public class StatManager {
}
/** Group name (String) to a Set of stat names, ordered alphabetically */
public Map getStatsByGroup() {
Map groups = new TreeMap(Collator.getInstance());
public Map<String, SortedSet<String>> getStatsByGroup() {
Map<String, SortedSet<String>> groups = new TreeMap(Collator.getInstance());
for (Iterator<FrequencyStat> iter = _frequencyStats.values().iterator(); iter.hasNext();) {
FrequencyStat stat = iter.next();
if (!groups.containsKey(stat.getGroupName())) groups.put(stat.getGroupName(), new TreeSet());
Set names = (Set) groups.get(stat.getGroupName());
Set<String> names = groups.get(stat.getGroupName());
names.add(stat.getName());
}
for (Iterator<RateStat> iter = _rateStats.values().iterator(); iter.hasNext();) {
RateStat stat = iter.next();
if (!groups.containsKey(stat.getGroupName())) groups.put(stat.getGroupName(), new TreeSet());
Set names = (Set) groups.get(stat.getGroupName());
Set<String> names = groups.get(stat.getGroupName());
names.add(stat.getName());
}
return groups;