LongDelta.java 4.26 KB
package se.lil.om;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.logging.Level;
import java.util.logging.Logger;

class LongDelta {
	private final static Logger LOGGER = Logger.getLogger(LongDelta.class.getName());
	private String name = null;
	
	private BigDecimal curValue = null;
	private BigDecimal lastValue = null;
	private BigDecimal last2Value = null;
	
	private Timestamp curFetch = null;
	private Timestamp lastFetch = null;
	private Timestamp last2Fetch = null;
	
	private static BigDecimal bd1000 = new BigDecimal(1000);
	
	private double numMilliSeconds;
	private double delta;
	private double lastGoodDelta = 0;
	private double lastGoodMilliseconds = 0;
	private boolean haveGoodDelta = false;
	
	public LongDelta(String name) {
		this.name = name;
	}
	
	public void update(ResultSet rset) throws Throwable{
		update(rset, 2, false, true);
	}
	public void update(ResultSet rset, boolean convert) throws Throwable{
		update(rset, 2, convert, true);
	}
	public void update(ResultSet rset, int pos, boolean convert) throws Throwable{
		update(rset, pos, convert, true);
	}
	public void update(ResultSet rset, int pos, boolean convert, boolean close) throws Throwable{
		rset.next();
		update(rset.getBigDecimal(pos), rset.getTimestamp(1), convert);
		if(close) rset.close(); 
	}
	
	public boolean matches(String name) {
		if(this.name.equals(name)) return true;
		else return false;
	}
	
	public void update(BigDecimal value, Timestamp timestamp) {
		update(value, timestamp, false);
	}
	
	public void update(BigDecimal value, Timestamp timestamp, boolean convert) {
		if(convert) value = value.divide(bd1000, BigDecimal.ROUND_HALF_UP);
		this.last2Fetch = this.lastFetch;
		this.lastFetch = this.curFetch;
		this.curFetch = timestamp;
		this.last2Value = this.lastValue;
		this.lastValue = this.curValue;
		this.curValue = value;
		this.haveGoodDelta = false;
	}
	
	private void updateDelta() {
		if(this.curValue != null && this.lastValue != null && this.last2Value != null 
				&& this.lastFetch != null && this.last2Fetch != null && this.curFetch != null) {
			
			// We have values, calculate the deltas
			
			// Handle the Oracle Bug (ref needed)
			if(curValue.compareTo(lastValue) >= 0) {
				numMilliSeconds = this.curFetch.getTime() - this.lastFetch.getTime();
				delta = this.curValue.subtract(this.lastValue).doubleValue();
				lastGoodMilliseconds = numMilliSeconds;
				lastGoodDelta = delta;
			} else if(curValue.compareTo(last2Value) >= 0) {
				numMilliSeconds = this.curFetch.getTime() - this.last2Fetch.getTime();
				delta = this.curValue.subtract(this.last2Value).doubleValue();
				lastGoodMilliseconds = numMilliSeconds;
				lastGoodDelta = delta;
			} else if (lastValue.compareTo(last2Value) >= 0) {
				numMilliSeconds = this.lastFetch.getTime() - this.last2Fetch.getTime();
				delta = this.lastValue.subtract(this.last2Value).doubleValue();
				lastGoodMilliseconds = numMilliSeconds;
				lastGoodDelta = delta;
			} else {
				// None of the 2 last measurements give a positive delta. Log this and return the last calculated delta.
				numMilliSeconds = lastGoodMilliseconds;
				delta = lastGoodDelta;
				LOGGER.log(Level.WARNING, "No positive deltas to calculate, returning cached value:["+lastGoodDelta+"]. Name: " 
						+ this.name + " Values:["+curValue+"]["+lastValue+"]["+last2Value+"]");
			}
			
			haveGoodDelta = true;
		}
	}
	
	public double getPerSecondValue() throws Throwable {
		if(haveGoodDelta == false) updateDelta();
		if(haveGoodDelta) {
			double perMilli = delta/numMilliSeconds;
			return perMilli * 1000;
		} else {
			return 0;
		}
	}
	
	public long getCurrentValue() throws Throwable {
		if(this.curValue != null) return this.curValue.longValue();
		else return 0;
	}
	
	public double getSeconds() throws Throwable {
		if(haveGoodDelta == false) updateDelta();
		if(haveGoodDelta) {
			return numMilliSeconds/1000;
		} else {
			return 0;
		}
	}
//	public long getMilliSeconds() throws Throwable {
//		if(this.lastFetch != null && this.curFetch != null) {
//			return this.curFetch.getTime() - this.lastFetch.getTime();
//		}
//		return 0;
//	}
//	public long getDelta() throws Throwable {
//		if(this.lastValue != null && this.curValue != null) {
//			return this.curValue.subtract(this.lastValue).longValue();
//		}
//		return 0;
//	}
}