addRateData per flush, so a hot path that samples a level once per message or per 1KB fragment pays one stat lookup and one monitor per rate period instead of one per sample.Which statistics may be batched this way is a semantic question, not a performance one, and this class only answers it for one kind of stat. Rate.addData(long) accumulates a total and an event count per period, and every reader divides them:
- A mean stat — one that samples a level (queue depth, fragments per message, write delay) — is read as
total / eventCount. N samples ofvtherefore report the mean of those samples, and collapsing them into one sample of that mean leaves the reported quantity the same up to the weighting (samples per flush rather than samples per period). That is what this class is for. - An event counter stat —
addRateData(name, 1)per event — cannot be batched here at all: collapsing N events into one sample would make the period's event count report flushes rather than events, andRate.getLastEventCount()feeds adaptive tuning. Such a stat has to resolve aRateStathandle once and calladdDataper event instead.
Safe for concurrent add(long): producers accumulate into LongAdders and only the flushing thread resets them, so a sample can straddle a flush boundary — which for a mean only moves one sample from one period to the next. Both flush methods drain the sample count first, for a reason worth stating: the count is what decides whether there is anything to emit, so resetting it first is what keeps a value sum from outliving its own count. Draining the sums first would let a sample whose count lands in this window but whose value lands in the next one leave a stale value behind with no count to ever flush it, contaminating the mean of some later flush. As written, every value added is consumed by exactly one flush, and a boundary-straddling sample is emitted as a zero for the following flush — an under-report by one sample, which is the direction the truncation contract already accepts.
Constructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescription(package private) voidadd(long value) Sample a level with no event duration.(package private) voidadd(long value, long eventDuration) Sample a level together with an event duration (the weight the rate counts alongside the value).(package private) booleanflush(RouterContext ctx, String name) Emit one sample covering everything accumulated so far and start over.(package private) booleanflushWithEventDuration(RouterContext ctx, String name) Asflush(RouterContext, String), but records the accumulated event durations against the rate as well.(package private) longMean of the durations sampled since the last flush, truncated toward zero.(package private) static longmeanOf(long sum, long count) Divide, guarding the empty batch.(package private) longMean of the values sampled since the last flush, truncated toward zero.(package private) longSamples accumulated since the last flush.(package private) voidreset()Drop everything accumulated so far.
Constructor Details
RateStatMeanBatch
RateStatMeanBatch()Start with no pending samples.
Method Details
add
void add(long value) Sample a level with no event duration.- Parameters:
value- the sampled level
add
void add(long value, long eventDuration) Sample a level together with an event duration (the weight the rate counts alongside the value).- Parameters:
value- the sampled leveleventDuration- weight recorded with the value, 0 for none
pendingCount
long pendingCount()Samples accumulated since the last flush.- Returns:
- the number of unflushed samples
meanValue
long meanValue()Mean of the values sampled since the last flush, truncated toward zero.- Returns:
- the mean sampled value, 0 when nothing is pending
meanEventDuration
long meanEventDuration()Mean of the durations sampled since the last flush, truncated toward zero.- Returns:
- the mean event duration, 0 when nothing is pending
meanOf
static long meanOf(long sum, long count) Divide, guarding the empty batch.Integer division, so a mean is truncated toward zero: the error is always in [0, 1) of a unit. Under one unit, never a unit in the over-reporting direction — on a quantity that was never more precise than its integer samples. Rounding would let a stat claiming to never over-report a queue depth or a write delay do exactly that.
- Parameters:
sum- the accumulated samplescount- how many samples were accumulated- Returns:
- the mean, or 0 when
countis zero
flush
Emit one sample covering everything accumulated so far and start over. Emits nothing when no sample is pending, because a zero-valued sample would still raise the rate's event count and pull its average down.- Parameters:
ctx- the router contextname- the stat to emit into- Returns:
- true if a sample was emitted
flushWithEventDuration
Asflush(RouterContext, String), but records the accumulated event durations against the rate as well. Use only where the call sites being collapsed passed a duration, so the rate's event time keeps the same meaning.- Parameters:
ctx- the router contextname- the stat to emit into- Returns:
- true if a sample was emitted
reset
void reset()Drop everything accumulated so far.