This provides lifetime, and rolling average, frequency counts. Unlike Rate, it does not support "bucketed" averages. There is no tracking of the event frequency in the current or last bucket. There are no buckets at all.
Depending on what you want, a rolling average might be better than buckets. Or not.
Field Summary
FieldsModifier and TypeFieldDescriptionprivate doubleAverage interval between recent events, in ms.private longEvents counted so far.private longWhen the most recent event happened.private doubleSmallest average interval seen in the period.private final longHow far back events count, in ms.private final longWhen this frequency was created.Constructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescriptionvoidTake note that a new event occurred, recalculating all the averages and frequencies.doubleCalculate how many events would occur in a period given the current (rolling) average.doubleOn average over the last $period, after how many milliseconds are events coming in, as calculated during the last event occurrence?longHow many events have occurred within the lifetime of this stat?doubleCalculate how many events would occur in a period given the maximum rolling average.doubleWhat is the lowest average interval (aka most frequent) we have seen? (ms).longHow long is this frequency averaged over? (ms).doubleUsing the strict average interval, how many events occur within an average period?doubleOver the lifetime of this stat, without any decay or weighting, what was the average interval between events? (ms).private static final longnow()Reads the current time.voidRecalculate the averages.private voidrecalculate(boolean eventOccurred) Recalculate, but only update the lastEvent if eventOccurred(package private) voidstore(StringBuilder dest) Appends the data of this frequency to the specified StringBuilder.
Field Details
_avgInterval
private double _avgIntervalAverage interval between recent events, in ms._minAverageInterval
private double _minAverageIntervalSmallest average interval seen in the period._period
private final long _periodHow far back events count, in ms._lastEvent
private long _lastEventWhen the most recent event happened._start
private final long _startWhen this frequency was created._count
private long _countEvents counted so far.
Constructor Details
Frequency
public Frequency(long period) Creates a new Frequency with the specified period.- Parameters:
period- the length of one period in milliseconds, the window over which events are averaged
Method Details
getPeriod
public long getPeriod()How long is this frequency averaged over? (ms).- Returns:
- the period in ms
getAverageInterval
public double getAverageInterval()On average over the last $period, after how many milliseconds are events coming in, as calculated during the last event occurrence?- Returns:
- milliseconds; returns period + 1 if no events in previous period
getMinAverageInterval
public double getMinAverageInterval()What is the lowest average interval (aka most frequent) we have seen? (ms).- Returns:
- milliseconds; returns period + 1 if no events in previous period
getAverageEventsPerPeriod
public double getAverageEventsPerPeriod()Calculate how many events would occur in a period given the current (rolling) average. UsegetStrictAverageInterval()for the real lifetime average.- Returns:
- the average events per period
getMaxAverageEventsPerPeriod
public double getMaxAverageEventsPerPeriod()Calculate how many events would occur in a period given the maximum rolling average. UsegetStrictAverageEventsPerPeriod()for the real lifetime average.- Returns:
- the max average events per period
getStrictAverageInterval
public double getStrictAverageInterval()Over the lifetime of this stat, without any decay or weighting, what was the average interval between events? (ms).- Returns:
- milliseconds; returns Double.MAX_VALUE if no events ever
getStrictAverageEventsPerPeriod
public double getStrictAverageEventsPerPeriod()Using the strict average interval, how many events occur within an average period?- Returns:
- events per period
getEventCount
public long getEventCount()How many events have occurred within the lifetime of this stat?- Returns:
- event count since this stat was created
eventOccurred
public void eventOccurred()Take note that a new event occurred, recalculating all the averages and frequencies.recalculate
public void recalculate()Recalculate the averages.recalculate
private void recalculate(boolean eventOccurred) Recalculate, but only update the lastEvent if eventOccurredThe clock read is taken before the monitor, not inside it. It is a leaf call - currentTimeMillis is served from the vDSO and takes no Java lock - so holding this monitor across it makes every concurrent event queue behind a syscall rather than behind arithmetic. Hoisting it out cuts the contended cost of
FrequencyStat.eventOccurred()on a three-period stat from 166ns to 145ns per event; uncontended it changes nothing, because the clock read costs the same either way when there is no queue.It is also safe to move.
nowis only ever differenced against_lastEvent, which is still read and written under the monitor, so the only effect is that the thread which loses the race computes its interval from a timestamp a few nanoseconds older. At millisecond resolution, and with the interval already clamped to[1, _period], that is not observable.- Parameters:
eventOccurred- true to record an event: the last-event time is updated and the count incremented; false recalculates the average interval only
now
private static final long now()Reads the current time.- Returns:
- the current time, in ms
store
Appends the data of this frequency to the specified StringBuilder.- Parameters:
dest- to append data to