Ensure ActionFRequency does reset if time ran backwards.

This commit is contained in:
asofold 2014-07-31 10:02:49 +02:00
parent 2f13529a29
commit 24120f306a

View File

@ -10,6 +10,7 @@ public class ActionFrequency {
/** Reference time for filling in. */ /** Reference time for filling in. */
private long time = 0; private long time = 0;
private long lastUpdate = 0;
/** /**
* Buckets to fill weights in, each represents an interval of durBucket duration, * Buckets to fill weights in, each represents an interval of durBucket duration,
@ -45,20 +46,20 @@ public class ActionFrequency {
} }
/** /**
* Update without adding, also updates time. * Update without adding, also updates time. Detects time running backwards.
* @param now * @param now
*/ */
public final void update(final long now) { public final void update(final long now) {
final long diff = now - time; final long diff = now - time;
if (diff < durBucket){ if (now < lastUpdate || diff >= durBucket * buckets.length) {
// No update (first bucket).
return;
}
else if (diff >= durBucket * buckets.length || diff < 0){
// Clear (beyond range). // Clear (beyond range).
clear(now); clear(now);
return; return;
} }
else if (diff < durBucket) {
// No update (first bucket).
return;
}
final int shift = (int) ((float) diff / (float) durBucket); final int shift = (int) ((float) diff / (float) durBucket);
// Update buckets. // Update buckets.
for (int i = 0; i < buckets.length - shift; i++) { for (int i = 0; i < buckets.length - shift; i++) {
@ -69,13 +70,14 @@ public class ActionFrequency {
} }
// Set time according to bucket duration (!). // Set time according to bucket duration (!).
time += durBucket * shift; time += durBucket * shift;
lastUpdate = now;
} }
public final void clear(final long now) { public final void clear(final long now) {
for (int i = 0; i < buckets.length; i++) { for (int i = 0; i < buckets.length; i++) {
buckets[i] = 0f; buckets[i] = 0f;
} }
time = now; time = lastUpdate = now;
} }
/** /**
@ -166,16 +168,25 @@ public class ActionFrequency {
*/ */
public final void setTime(final long time) { public final void setTime(final long time) {
this.time = time; this.time = time;
this.lastUpdate = time;
} }
/** /**
* Get reference time. * Get reference time.
* @return * @return
*/ */
public final long lastAccess(){ public final long lastAccess() { // TODO: Should rename this.
return time; return time;
} }
/**
*
* @return
*/
public final long lastUpdate() {
return lastUpdate;
}
/** /**
* Get the number of buckets. * Get the number of buckets.
* @return * @return
@ -197,6 +208,7 @@ public class ActionFrequency {
* @return * @return
*/ */
public final String toLine() { public final String toLine() {
// TODO: Backwards-compatible lastUpdate ?
final StringBuilder buffer = new StringBuilder(50); final StringBuilder buffer = new StringBuilder(50);
buffer.append(buckets.length + ","+durBucket+","+time); buffer.append(buckets.length + ","+durBucket+","+time);
for (int i = 0; i < buckets.length; i++) { for (int i = 0; i < buckets.length; i++) {
@ -211,6 +223,7 @@ public class ActionFrequency {
* @return * @return
*/ */
public static ActionFrequency fromLine(final String line) { public static ActionFrequency fromLine(final String line) {
// TODO: Backwards-compatible lastUpdate ?
String[] split = line.split(","); String[] split = line.split(",");
if (split.length < 3) throw new RuntimeException("Bad argument length."); // TODO if (split.length < 3) throw new RuntimeException("Bad argument length."); // TODO
final int n = Integer.parseInt(split[0]); final int n = Integer.parseInt(split[0]);