Issue #1501 Fix broken required latency calculations
Change-Id: If91a567b2a215ec039f5649b4a77939a8fd9b45a Former-commit-id:e64e36ecf2
[formerlyf361f5a6a1
] [formerly5830a98a51
[formerly 9788de6b75f727ea1c2d7c178081eeec16078362]] Former-commit-id:5830a98a51
Former-commit-id:d7077690d8
This commit is contained in:
parent
28535058f9
commit
0185add187
3 changed files with 89 additions and 91 deletions
|
@ -98,7 +98,7 @@ import com.raytheon.uf.edex.event.EventBus;
|
|||
* Dec 12, 2012 1286 djohnson Remove shutdown hook and finalize().
|
||||
* Jan 25, 2013 1528 djohnson Compare priorities as primitive ints.
|
||||
* Jan 28, 2013 1530 djohnson Unschedule all allocations for a subscription that does not fully schedule.
|
||||
*
|
||||
* Jan 30, 2013 1501 djohnson Fix broken calculations for determining required latency.
|
||||
* </pre>
|
||||
*
|
||||
* @author dhladky
|
||||
|
@ -1160,8 +1160,7 @@ abstract class BandwidthManager extends
|
|||
* @return the graph data
|
||||
*/
|
||||
private BandwidthGraphData getBandwidthGraphData() {
|
||||
return new BandwidthGraphDataAdapter(retrievalManager)
|
||||
.get();
|
||||
return new BandwidthGraphDataAdapter(retrievalManager).get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1544,95 +1543,86 @@ abstract class BandwidthManager extends
|
|||
* @return the required latency, in minutes
|
||||
*/
|
||||
@VisibleForTesting
|
||||
int determineRequiredLatency(Subscription subscription) {
|
||||
int determineRequiredLatency(final Subscription subscription) {
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
timer.start();
|
||||
try {
|
||||
final Subscription clone = BandwidthUtil.cheapClone(
|
||||
Subscription.class, subscription);
|
||||
|
||||
if (clone.getLatencyInMinutes() < 1) {
|
||||
clone.setLatencyInMinutes(1);
|
||||
}
|
||||
|
||||
boolean foundLatency = false;
|
||||
int latency = clone.getLatencyInMinutes();
|
||||
int previousLatency = latency;
|
||||
do {
|
||||
// Double the latency until we have two values we can binary
|
||||
// search between...
|
||||
previousLatency = latency;
|
||||
latency *= 2;
|
||||
clone.setLatencyInMinutes(latency);
|
||||
foundLatency = isSchedulableWithoutConflict(clone);
|
||||
} while (!foundLatency);
|
||||
|
||||
SortedSet<Integer> possibleLatencies = new TreeSet<Integer>();
|
||||
for (int i = previousLatency; i < (latency + 1); i++) {
|
||||
possibleLatencies.add(Integer.valueOf(i));
|
||||
}
|
||||
|
||||
IBinarySearchResponse<Integer> response = AlgorithmUtil
|
||||
.binarySearch(possibleLatencies, new Comparable<Integer>() {
|
||||
@Override
|
||||
public int compareTo(Integer valueToCheck) {
|
||||
clone.setLatencyInMinutes(valueToCheck);
|
||||
|
||||
boolean latencyWouldWork = isSchedulableWithoutConflict(clone);
|
||||
|
||||
// Check if one value less would not work, if so
|
||||
// then this is the required latency, otherwise keep
|
||||
// searching
|
||||
if (latencyWouldWork) {
|
||||
clone.setLatencyInMinutes(clone
|
||||
.getLatencyInMinutes() - 1);
|
||||
|
||||
return (isSchedulableWithoutConflict(clone)) ? 1
|
||||
: 0;
|
||||
} else {
|
||||
// Still too low, stuff would be unscheduled
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Integer binarySearchedLatency = response.getItem();
|
||||
if (binarySearchedLatency != null) {
|
||||
latency = binarySearchedLatency.intValue();
|
||||
|
||||
if (statusHandler.isPriorityEnabled(Priority.DEBUG)) {
|
||||
statusHandler
|
||||
.debug(String
|
||||
.format("Found required latency of [%s] in [%s] iterations",
|
||||
binarySearchedLatency,
|
||||
response.getIterations()));
|
||||
}
|
||||
} else {
|
||||
statusHandler
|
||||
.warn(String
|
||||
.format("Unable to find the required latency with a binary search, using required latency [%s]",
|
||||
latency));
|
||||
}
|
||||
|
||||
timer.stop();
|
||||
|
||||
int bufferRoomInMinutes = retrievalManager.getPlan(
|
||||
subscription.getRoute()).getBucketMinutes();
|
||||
|
||||
final String logMsg = String
|
||||
.format("Determined required latency of [%s] in [%s] ms. Adding buffer room of [%s] minutes",
|
||||
latency, timer.getElapsedTime(),
|
||||
bufferRoomInMinutes);
|
||||
statusHandler.info(logMsg);
|
||||
|
||||
latency += bufferRoomInMinutes;
|
||||
|
||||
return latency;
|
||||
} catch (SerializationException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Unable to serialize a Subscription", e);
|
||||
return -1;
|
||||
boolean foundLatency = false;
|
||||
int latency = subscription.getLatencyInMinutes();
|
||||
if (latency < 1) {
|
||||
latency = 1;
|
||||
}
|
||||
int previousLatency = latency;
|
||||
do {
|
||||
// Double the latency until we have two values we can binary
|
||||
// search between...
|
||||
previousLatency = latency;
|
||||
latency *= 2;
|
||||
|
||||
Subscription clone = new Subscription(subscription);
|
||||
clone.setLatencyInMinutes(latency);
|
||||
foundLatency = isSchedulableWithoutConflict(clone);
|
||||
} while (!foundLatency);
|
||||
|
||||
SortedSet<Integer> possibleLatencies = new TreeSet<Integer>();
|
||||
for (int i = previousLatency; i < (latency + 1); i++) {
|
||||
possibleLatencies.add(Integer.valueOf(i));
|
||||
}
|
||||
|
||||
IBinarySearchResponse<Integer> response = AlgorithmUtil.binarySearch(
|
||||
possibleLatencies, new Comparable<Integer>() {
|
||||
@Override
|
||||
public int compareTo(Integer valueToCheck) {
|
||||
Subscription clone = new Subscription(subscription);
|
||||
clone.setLatencyInMinutes(valueToCheck);
|
||||
|
||||
boolean latencyWouldWork = isSchedulableWithoutConflict(clone);
|
||||
|
||||
// Check if one value less would not work, if so
|
||||
// then this is the required latency, otherwise keep
|
||||
// searching
|
||||
if (latencyWouldWork) {
|
||||
clone.setLatencyInMinutes(clone
|
||||
.getLatencyInMinutes() - 1);
|
||||
|
||||
return (isSchedulableWithoutConflict(clone)) ? 1
|
||||
: 0;
|
||||
} else {
|
||||
// Still too low, stuff would be unscheduled
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Integer binarySearchedLatency = response.getItem();
|
||||
if (binarySearchedLatency != null) {
|
||||
latency = binarySearchedLatency.intValue();
|
||||
|
||||
if (statusHandler.isPriorityEnabled(Priority.DEBUG)) {
|
||||
statusHandler.debug(String.format(
|
||||
"Found required latency of [%s] in [%s] iterations",
|
||||
binarySearchedLatency, response.getIterations()));
|
||||
}
|
||||
} else {
|
||||
statusHandler
|
||||
.warn(String
|
||||
.format("Unable to find the required latency with a binary search, using required latency [%s]",
|
||||
latency));
|
||||
}
|
||||
|
||||
timer.stop();
|
||||
|
||||
int bufferRoomInMinutes = retrievalManager.getPlan(
|
||||
subscription.getRoute()).getBucketMinutes();
|
||||
|
||||
final String logMsg = String
|
||||
.format("Determined required latency of [%s] in [%s] ms. Adding buffer room of [%s] minutes",
|
||||
latency, timer.getElapsedTime(), bufferRoomInMinutes);
|
||||
statusHandler.info(logMsg);
|
||||
|
||||
latency += bufferRoomInMinutes;
|
||||
|
||||
return latency;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -151,7 +151,15 @@ public abstract class AbstractBandwidthManagerIntTest {
|
|||
*/
|
||||
protected Subscription createSubscriptionThatFillsUpABucket() {
|
||||
return createSubscriptionWithDataSetSizeInBytes(fullBucketSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a subscription the fills up ten buckets.
|
||||
*
|
||||
* @return the subscription
|
||||
*/
|
||||
protected Subscription createSubscriptionThatFillsUpTenBuckets() {
|
||||
return createSubscriptionWithDataSetSizeInBytes(fullBucketSize * 10);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -87,6 +87,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.RetrievalManagerNotifyEvent;
|
|||
* Dec 11, 2012 1286 djohnson Add test verifying fulfilled retrievals won't cause NPEs when the subscription is updated.
|
||||
* Jan 25, 2013 1528 djohnson Compare priorities as primitive ints.
|
||||
* Jan 28, 2013 1530 djohnson Test that all allocations are unscheduled for subscription that doesn't fully schedule.
|
||||
* Jan 30, 2013 1501 djohnson Fix broken calculations for determining required latency.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -490,15 +491,14 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest {
|
|||
public void testDetermineRequiredLatencyReturnsNecessaryLatency()
|
||||
throws SerializationException {
|
||||
|
||||
// Subscription starts out too big
|
||||
Subscription subscription = createSubscriptionThatFillsUpTwoBuckets();
|
||||
Subscription subscription = createSubscriptionThatFillsUpTenBuckets();
|
||||
subscription.getTime().setCycleTimes(Arrays.asList(Integer.valueOf(0)));
|
||||
subscription.setLatencyInMinutes(0);
|
||||
|
||||
int requiredLatency = bandwidthManager
|
||||
.determineRequiredLatency(subscription);
|
||||
|
||||
assertEquals("The required latency was calculated incorrectly", 7,
|
||||
assertEquals("The required latency was calculated incorrectly", 30,
|
||||
requiredLatency);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue