Created
February 14, 2014 10:37
-
-
Save henrikw/8999028 to your computer and use it in GitHub Desktop.
ScalingValue.java see http://henrikwarne.com/2014/02/09/unit-testing-private-methods/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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