/* ************************************************************************
#
# DivConq
#
# http://divconq.com/
#
# Copyright:
# Copyright 2014 eTimeline, LLC. All rights reserved.
#
# License:
# See the license.txt file in the project's top-level directory for details.
#
# Authors:
# * Andy White
#
************************************************************************ */
package divconq.count;
import java.math.BigDecimal;
import java.math.RoundingMode;
import divconq.struct.FieldStruct;
import divconq.struct.RecordStruct;
public class NumberCounterAdv extends Counter {
protected BigDecimal value = null;
protected BigDecimal low = null;
protected BigDecimal high = null;
protected BigDecimal sum = null;
protected long setcount = 0;
public void setValue(long value) {
this.setValue(BigDecimal.valueOf(value));
}
public void setValue(double value) {
this.setValue(BigDecimal.valueOf(value));
}
public void setValue(BigDecimal value) {
try {
this.valuelock.lockInterruptibly();
}
catch (InterruptedException x) {
return; // should only happen under bad conditions, so probably nothing we can do
}
// we are locked during whole set/notify process so be efficient
try {
this.value = value;
if (this.value != null) {
if ((this.high == null) || (this.value.compareTo(this.high) > 0))
this.high = this.value;
if ((this.low == null) || (this.value.compareTo(this.low) < 0))
this.low = this.value;
this.setcount++;
if (this.sum == null)
this.sum = this.value;
else
this.sum = this.sum.add(this.value);
}
this.setChanged();
}
finally {
this.valuelock.unlock();
}
}
public BigDecimal getValue() {
return this.value;
}
public BigDecimal getHigh() {
return this.high;
}
public BigDecimal getLow() {
return this.low;
}
public BigDecimal getSum() {
return this.sum;
}
public long getSetCount() {
return this.setcount;
}
public BigDecimal getAverage() {
if ((this.sum == null) || (this.sum.longValue() == 0))
return null;
return this.sum.divide(new BigDecimal(this.setcount), RoundingMode.HALF_UP);
}
public NumberCounterAdv(String name) {
super(name);
}
public NumberCounterAdv(String name, BigDecimal value) {
this(name);
this.setValue(value);
}
public void increment() {
try {
this.valuelock.lockInterruptibly();
}
catch (InterruptedException x) {
return; // should only happen under bad conditions, so probably nothing we can do
}
// we are locked during whole set/notify process so be efficient
try {
if (this.value == null)
this.setValue(1);
else
this.setValue(this.value.add(BigDecimal.valueOf(1)));
}
finally {
this.valuelock.unlock();
}
}
@Override
public Counter clone() {
NumberCounterAdv clone = new NumberCounterAdv(this.name, this.value);
this.copyToClone(clone);
return clone;
}
@Override
public void copyToClone(Counter clone) {
super.copyToClone(clone);
// caller is doing weird stuff - ignore them
if (!(clone instanceof NumberCounterAdv))
return;
NumberCounterAdv nclone = (NumberCounterAdv)clone;
nclone.low = this.low;
nclone.high = this.high;
nclone.sum = this.sum;
nclone.setcount = this.setcount;
}
@Override
public RecordStruct toRecord() {
return new RecordStruct(new FieldStruct("Name", this.name), new FieldStruct("Value", this.value),
new FieldStruct("High", this.high), new FieldStruct("Low", this.low),
new FieldStruct("Sum", this.sum), new FieldStruct("SetCount", this.setcount),
new FieldStruct("Average", this.getAverage()), new FieldStruct("Object", this.currentObject));
}
@Override
public RecordStruct toCleanRecord() {
return new RecordStruct(new FieldStruct("Name", this.name), new FieldStruct("Value", this.value),
new FieldStruct("High", this.high), new FieldStruct("Low", this.low),
new FieldStruct("Sum", this.sum), new FieldStruct("SetCount", this.setcount),
new FieldStruct("Average", this.getAverage()));
}
@Override
public void reset() {
super.reset();
this.value = null;
this.low = null;
this.high = null;
this.sum = null;
this.setcount = 0;
}
}