Skip to content

Instantly share code, notes, and snippets.

@henrikw
Created February 14, 2014 10:37
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save henrikw/8999028 to your computer and use it in GitHub Desktop.
package com.example.testphone.node.generator;
import java.util.ArrayList;
/**
* @author Henrik Warne
*/
public class ScalingValue {
ArrayList<Value> valueList;
private boolean timeAnchorsSet;
class Value {
Value(long anchorTimeStamp, int scalePercentage) {
this.anchorTimeStamp = anchorTimeStamp;
this.scalePercentage = scalePercentage;
}
long anchorTimeStamp;
int scalePercentage; // 0 to 100
}
ScalingValue(ArrayList<Integer> input) {
valueList = new ArrayList<>();
for (Integer intValue : input) {
valueList.add(new Value(-1, intValue));
}
if (valueList.size() == 0) {
// Need a beginning value, so set to 100%.
valueList.add(new Value(-1, 100));
}
if (valueList.size() == 1) {
// Need an end value, so duplicate the value.
valueList.add(new Value(-1, valueList.get(0).scalePercentage));
}
}
// Set time-values from start to finish time, equally spaced for the elements of the valueList.
void setTimeAnchors(long now, long duration) {
long step = duration / (valueList.size() - 1);
for (int i=0; i<valueList.size(); i++) {
valueList.get(i).anchorTimeStamp = now + i * step;
}
timeAnchorsSet = true;
}
/**
* Find the scaled rate based on the previous and next scale values. For example, if for
* timestamp 0 the scale value is 100% and for timestamp 400 the scale value is 80%, then
* for time stamp 0 you get 100% of the maxRate, for time stamp 400 you get 80% of the maxRate,
* for time stamp 200 you get 90% etc (linear).
*
* @param now Current time stamp (milliseconds)
* @param maxRate Nominal (i.e. maximum) rate (events per second)
* @return The scaled rate value at this time
*/
public double getCurrentRate(long now, double maxRate) {
if (!timeAnchorsSet) throw new IllegalArgumentException("Time anchors have not been set.");
long begin = valueList.get(0).anchorTimeStamp;
if (now <= begin) return maxRate;
long end = valueList.get(valueList.size() - 1).anchorTimeStamp;
if (now >= end) return maxRate;
int nextIndex = getNextIndex(now);
Value next = valueList.get(nextIndex);
int previousIndex = nextIndex - 1;
if (previousIndex < 0) previousIndex = 0;
Value previous = valueList.get(previousIndex);
double scalingFactor = getScalingFactor(previous, next, now);
return scalingFactor * maxRate;
}
double getScalingFactor(Value prev, Value next, long now) {
double scale = (double)(now - prev.anchorTimeStamp) / (next.anchorTimeStamp - prev.anchorTimeStamp);
return (prev.scalePercentage + scale * (next.scalePercentage - prev.scalePercentage)) / 100.0;
}
// Index of first value in list where the anchorTimeStamp is greater than now
int getNextIndex(long now) {
int i;
for (i=0; i<valueList.size(); i++) {
long current = valueList.get(i).anchorTimeStamp;
if (current > now) break;
}
if (i >= valueList.size()) i = valueList.size() - 1;
return i;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment