LongDelta.java
5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
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 String dbname = 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) {
if(this.dbname == null) this.name = name;
}
public void setDBName(String name) {
this.dbname = 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 && lastValue.compareTo(last2Value) >= 0) {
// All three values are okay, report as normal
numMilliSeconds = this.curFetch.getTime() - this.lastFetch.getTime();
delta = this.curValue.subtract(this.lastValue).doubleValue();
lastGoodMilliseconds = numMilliSeconds;
lastGoodDelta = delta;
} else if(curValue.compareTo(last2Value) >= 0 && last2Value.compareTo(lastValue) >= 0) {
// Current and last2 are okay, report this value
numMilliSeconds = this.curFetch.getTime() - this.last2Fetch.getTime();
delta = this.curValue.subtract(this.last2Value).doubleValue();
lastGoodMilliseconds = numMilliSeconds;
lastGoodDelta = delta;
} else if (lastValue.compareTo(last2Value) >= 0 && lastValue.compareTo(curValue) >= 0) {
// last and last2 value are okay (same as cached previous reported delta)
numMilliSeconds = this.lastFetch.getTime() - this.last2Fetch.getTime();
delta = this.lastValue.subtract(this.last2Value).doubleValue();
lastGoodMilliseconds = numMilliSeconds;
lastGoodDelta = delta;
} else if(last2Value.compareTo(lastValue) >= 0 && last2Value.compareTo(curValue) >= 0 && curValue.compareTo(lastValue) >= 0) {
// There was an incorrect positive measurement (last2value)
numMilliSeconds = this.curFetch.getTime() - this.lastFetch.getTime();
delta = this.curValue.subtract(this.lastValue).doubleValue();
lastGoodMilliseconds = numMilliSeconds;
lastGoodDelta = delta;
LOGGER.log(Level.WARNING, dbname + ": Too high historical value detected. Name: "
+ this.name + " Values:["+curValue+"]["+lastValue+"]["+last2Value+"]");
} else {
// Unhandled situation. Return cached delta.
numMilliSeconds = lastGoodMilliseconds;
delta = lastGoodDelta;
LOGGER.log(Level.WARNING, dbname + ": No 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;
// }
}