org.javasimon.CounterImpl Maven / Gradle / Ivy
The newest version!
package org.javasimon;
import org.javasimon.utils.SimonUtils;
/**
* Class implements {@link org.javasimon.Counter} interface - see there for how to use Counter.
*
* @author Richard "Virgo" Richter
* @see org.javasimon.Counter
*/
final class CounterImpl extends AbstractSimon implements Counter {
/** An internal counter. */
private long counter;
/** Sum of all increments. */
private long incrementSum;
/** Sum of all decrements. */
private long decrementSum;
/** A maximum tracker. */
private long max = Long.MIN_VALUE;
private long maxTimestamp;
/** A minimum tracker - only negative values. */
private long min = Long.MAX_VALUE;
private long minTimestamp;
/**
* Constructs Counter Simon with a specified name and for the specified manager.
*
* @param name Simon's name
* @param manager owning manager
* @noinspection WeakerAccess (EnabledManager calls this via reflection)
*/
CounterImpl(String name, Manager manager) {
super(name, manager);
}
@Override
public Counter set(long val) {
if (!enabled) {
return this;
}
long now = manager.milliTime();
CounterSample sample;
synchronized (this) {
setPrivate(val, now);
updateIncrementalSimonsSet(val, now);
sample = sampleIfCallbacksNotEmpty();
}
manager.callback().onCounterSet(this, val, sample);
return this;
}
@MustBeInSynchronized
private void setPrivate(long val, long now) {
updateUsages(now);
counter = val;
updateMax();
updateMin();
}
@MustBeInSynchronized
private void updateIncrementalSimonsSet(long val, long now) {
for (Simon simon : incrementalSimons.values()) {
((CounterImpl) simon).setPrivate(val, now);
}
}
private void updateMin() {
if (counter <= min) {
min = counter;
minTimestamp = getLastUsage();
}
}
private void updateMax() {
if (counter >= max) {
max = counter;
maxTimestamp = getLastUsage();
}
}
@Override
public Counter increase() {
return increase(1);
}
@Override
public Counter increase(long inc) {
if (!enabled) {
return this;
}
long now = manager.milliTime();
CounterSample sample;
synchronized (this) {
increasePrivate(inc, now);
updateIncrementalSimonsIncrease(inc, now);
sample = sampleIfCallbacksNotEmpty();
}
manager.callback().onCounterIncrease(this, inc, sample);
return this;
}
private void increasePrivate(long inc, long now) {
updateUsages(now);
incrementSum += inc;
counter += inc;
if (inc > 0) {
updateMax();
} else {
updateMin();
}
}
// must be called from synchronized block (CHECKED)
private void updateIncrementalSimonsIncrease(long inc, long now) {
for (Simon simon : incrementalSimons.values()) {
((CounterImpl) simon).increasePrivate(inc, now);
}
}
@Override
public Counter decrease() {
return decrease(1);
}
@Override
public synchronized Counter decrease(long dec) {
if (!enabled) {
return this;
}
long now = manager.milliTime();
CounterSample sample;
synchronized (this) {
decreasePrivate(dec, now);
sample = sampleIfCallbacksNotEmpty();
updateIncrementalSimonsDecrease(dec, now);
}
manager.callback().onCounterDecrease(this, dec, sample);
return this;
}
private void decreasePrivate(long dec, long now) {
updateUsages(now);
decrementSum += dec;
counter -= dec;
if (dec > 0) {
updateMin();
} else {
updateMax();
}
}
@MustBeInSynchronized
private void updateIncrementalSimonsDecrease(long dec, long now) {
for (Simon simon : incrementalSimons.values()) {
((CounterImpl) simon).decreasePrivate(dec, now);
}
}
private CounterSample sampleIfCallbacksNotEmpty() {
if (!manager.callback().callbacks().isEmpty()) {
return sample();
}
return null;
}
@Override
public synchronized long getCounter() {
return counter;
}
@Override
public synchronized long getMin() {
return min;
}
@Override
public synchronized long getMinTimestamp() {
return minTimestamp;
}
@Override
public synchronized long getMax() {
return max;
}
@Override
public synchronized long getMaxTimestamp() {
return maxTimestamp;
}
@Override
public synchronized long getIncrementSum() {
return incrementSum;
}
@Override
public synchronized long getDecrementSum() {
return decrementSum;
}
@Override
public synchronized CounterSample sample() {
CounterSample sample = new CounterSample();
sample.setCounter(counter);
sample.setMin(min);
sample.setMax(max);
sample.setMinTimestamp(minTimestamp);
sample.setMaxTimestamp(maxTimestamp);
sample.setIncrementSum(incrementSum);
sample.setDecrementSum(decrementSum);
sampleCommon(sample);
return sample;
}
@Override
public CounterSample sampleIncrement(Object key) {
return (CounterSample) sampleIncrementHelper(key, new CounterImpl(null, manager));
}
@Override
public CounterSample sampleIncrementNoReset(Object key) {
return (CounterSample) sampleIncrementNoResetHelper(key);
}
/**
* Returns Simon basic information, counter, max value and min value as a human readable string.
*
* @return basic information, counter, max and min values
* @see AbstractSimon#toString()
*/
@Override
public synchronized String toString() {
return "Simon Counter: counter=" + counter +
", max=" + SimonUtils.presentMinMaxCount(max) +
", min=" + SimonUtils.presentMinMaxCount(min) +
super.toString();
}
}