Issue #1519 Fix max latency calculations for adhoc queries

Amend:
  Peer review comments.

Change-Id: Ifa76b145616d8fdcf4ba41cd3744cfc3991b902c

Former-commit-id: 0f7b01795d [formerly 504268f0f3] [formerly 99533e7f4be78460bbd202f0f609a7357cffb683 [formerly 6c1818d544]] [formerly f730422834 [formerly 6c1818d544 [formerly e9d88236907b98f7e461807592e580bdf1ecedb9]]]
Former-commit-id: f730422834
Former-commit-id: 76d8b5641220e657d9123f65878c0ce41da1c8f6 [formerly 516ac1ab9a]
Former-commit-id: 2e09d46fea
This commit is contained in:
Dustin Johnson 2013-01-22 15:11:17 -06:00
parent 998bbc254d
commit 70bce9d505
6 changed files with 143 additions and 53 deletions

View file

@ -19,8 +19,8 @@
**/
package com.raytheon.uf.viz.datadelivery.subscription.subset.presenter;
import java.util.ArrayList;
import java.util.Collections;
import static com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils.getMaxLatency;
import java.util.List;
import com.google.common.annotations.VisibleForTesting;
@ -44,6 +44,7 @@ import com.raytheon.viz.ui.presenter.components.ListConf;
* Sep 27, 2012 1202 bgonzale Set selectionDate to date and cycle.
* Oct 11, 2012 1263 jpiatt Modified for cancel flag.
* Jan 04, 2013 1420 mpduff Add the dataset object.
* Jan 22, 2013 1519 djohnson Use DataDeliveryUtils.getMaxLatency().
*
* </pre>
*
@ -173,7 +174,7 @@ public class GriddedTimingSelectionPresenter {
}
DataDeliveryGUIUtils.latencyValidChk(view.getLatency(),
getMaxLatency());
getMaxLatency(dataSet));
// parse off the date/cycle time selected
String[] parts = selection.split(" - ");
@ -188,29 +189,6 @@ public class GriddedTimingSelectionPresenter {
return true;
}
/**
* Max latency value in minutes.
*
* @return
*/
private int getMaxLatency() {
List<Integer> cycleList = new ArrayList<Integer>(dataSet.getCycles());
Collections.sort(cycleList);
int max = 0;
for (int i = 0; i < cycleList.size(); i++) {
if (i + 1 <= cycleList.size()) {
int tempMax = cycleList.get(i + 1) - cycleList.get(i);
if (tempMax > max) {
max = tempMax;
}
}
}
return max * 60;
}
/**
* This method is called via the "Use Latest Data" checkbox being
* selected/unselected.

View file

@ -32,6 +32,7 @@ import org.eclipse.swt.widgets.Shell;
import com.raytheon.uf.common.datadelivery.registry.Coverage;
import com.raytheon.uf.common.datadelivery.registry.DataLevelType;
import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet;
import com.raytheon.uf.common.datadelivery.registry.Parameter;
import com.raytheon.uf.common.datadelivery.registry.Subscription;
import com.raytheon.uf.common.datadelivery.registry.Time;
@ -57,10 +58,11 @@ import com.vividsolutions.jts.geom.Coordinate;
* Jul 25, 2012 955 djohnson Use List instead of ArrayList, thread-safe access to DecimalFormat.
* Aug 29, 2012 223 mpduff Add cycles to the subscription details.
* Oct 31, 2012 1278 mpduff Moved spatial methods to SpatialUtils.
* Nov 20, 2012 1286 djohnson Add showYesNoMessage.
* Dec 20, 2012 1413 bgonzale Added PendingSubColumnNames.valueOfColumnName(String).
* Jan 10, 2013 1420 mdpuff Added getMaxLatency().
* Nov 20, 2012 1286 djohnson Add showYesNoMessage.
* Dec 20, 2012 1413 bgonzale Added PendingSubColumnNames.valueOfColumnName(String).
* Jan 10, 2013 1420 mdpuff Added getMaxLatency().
* Jan 14, 2013 1286 djohnson Fix IndexOutOfBounds exception from getMaxLatency.
* Jan 22, 2013 1519 djohnson Correct getMaxLatency() calculations.
* </pre>
*
* @author mpduff
@ -69,6 +71,18 @@ import com.vividsolutions.jts.geom.Coordinate;
public class DataDeliveryUtils {
/**
* Default latency applied to hourly datasets.
*/
public static final int HOURLY_DATASET_LATENCY_IN_MINUTES = 40;
/**
* Default latency applied non-hourly datasets.
*/
public static final int NON_HOURLY_DATASET_LATENCY_IN_MINUTES = 75;
private static final int UNSET = -1;
/** Decimal format */
private final static ThreadLocal<DecimalFormat> format = new ThreadLocal<DecimalFormat>() {
@ -551,20 +565,48 @@ public class DataDeliveryUtils {
* @return the maximum latency in minutes
*/
public static int getMaxLatency(Subscription subscription) {
List<Integer> cycles = subscription.getTime().getCycleTimes();
return getMaxLatency(subscription.getTime().getCycleTimes());
}
/**
* Get the maximum latency for the provided cycles. Calculated as the
* maximum cyclic difference.
*
* @param cycles
* The list of cycles
* @return the maximum latency in minutes
*/
public static int getMaxLatency(List<Integer> cycles) {
Collections.sort(cycles);
int max = TimeUtil.HOURS_PER_DAY * TimeUtil.MINUTES_PER_HOUR;
int maximumTimeBetweenCycles = UNSET;
final int size = cycles.size();
for (int i = 0; i < size; i++) {
final int nextIndex = i + 1;
if (nextIndex < size) {
int tempMax = cycles.get(nextIndex) - cycles.get(i);
if (tempMax > max) {
max = tempMax;
}
maximumTimeBetweenCycles = Math.max(maximumTimeBetweenCycles, tempMax);
}
}
return max;
// If there was only one cycle, then default to the number of minutes in
// the day
if (maximumTimeBetweenCycles == UNSET) {
maximumTimeBetweenCycles = TimeUtil.HOURS_PER_DAY;
}
return maximumTimeBetweenCycles * TimeUtil.MINUTES_PER_HOUR;
}
/**
* Get the maximum latency for the provided dataSet. Calculated as the
* maximum cyclic difference.
*
* @param dataSet
* the dataset
* @return the maximum latency in minutes
*/
public static int getMaxLatency(GriddedDataSet dataSet) {
return getMaxLatency(new ArrayList<Integer>(dataSet.getCycles()));
}
}

View file

@ -21,6 +21,8 @@ package com.raytheon.uf.viz.datadelivery.utils;
import java.util.List;
import com.raytheon.uf.common.time.util.TimeUtil;
/**
* Data Set Frequency Enumeration.
*
@ -30,7 +32,8 @@ import java.util.List;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 8, 2013 1420 mpduff Initial creation.
* Jan 08, 2013 1420 mpduff Initial creation.
* Jan 22, 2013 1519 djohnson Correct the non-hourly default latency to match requirements.
*
* </pre>
*
@ -39,8 +42,11 @@ import java.util.List;
*/
public enum DataSetFrequency {
HOURLY(40), SIX_HOURLY(115), TWELVE_HOURLY(115), DAILY(115);
HOURLY(DataDeliveryUtils.HOURLY_DATASET_LATENCY_IN_MINUTES), SIX_HOURLY(
DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES), TWELVE_HOURLY(
DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES), DAILY(
DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES);
private int defaultLatency;
private DataSetFrequency(int defaultLatency) {
@ -49,13 +55,14 @@ public enum DataSetFrequency {
public static DataSetFrequency fromCycleTimes(List<Integer> cycleTimes) {
if (cycleTimes.size() > 1) {
if ((cycleTimes.get(1) - cycleTimes.get(0)) == 1) {
final int hoursBetweenCycles = cycleTimes.get(1) - cycleTimes.get(0);
if (hoursBetweenCycles == 1) {
return DataSetFrequency.HOURLY;
} else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 6) {
} else if (hoursBetweenCycles == TimeUtil.HOURS_PER_QUARTER_DAY) {
return DataSetFrequency.SIX_HOURLY;
} else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 12) {
} else if (hoursBetweenCycles == TimeUtil.HOURS_PER_HALF_DAY) {
return DataSetFrequency.TWELVE_HOURLY;
} else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 24) {
} else if (hoursBetweenCycles == TimeUtil.HOURS_PER_DAY) {
return DataSetFrequency.DAILY;
}
}

View file

@ -45,14 +45,14 @@ import com.raytheon.uf.common.time.domain.api.ITimePoint;
* Nov 21, 2012 728 mpduff Added MILLIS_PER_MONTH.
* Jan 07, 2013 1451 djohnson Add newGmtCalendar() and time constants.
* Jan 22, 2013 1484 mpduff Add HOURS_PER_WEEK.
* Jan 22, 2013 1519 djohnson Add MINUTES_PER_DAY.
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class TimeUtil {
public final class TimeUtil {
/**
* A clock that does not really return the current time. Useful when you
@ -97,6 +97,12 @@ public class TimeUtil {
public static final int HOURS_PER_DAY = 24;
public static final int HOURS_PER_HALF_DAY = HOURS_PER_DAY / 2;
public static final int HOURS_PER_QUARTER_DAY = HOURS_PER_HALF_DAY / 2;
public static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY;
private static final int DAYS_PER_WEEK = 7;
public static final int HOURS_PER_WEEK = HOURS_PER_DAY * DAYS_PER_WEEK;
@ -385,4 +391,10 @@ public class TimeUtil {
}
return calendar;
}
/**
* Disabled constructor.
*/
private TimeUtil() {
}
}

View file

@ -76,6 +76,7 @@ public class OpenDapGriddedDataSetFixture extends
obj.setDataSetName("dataSetName" + seedValue);
obj.setDataSetType(DataType.GRID);
obj.setForecastHours(CollectionUtil.asSet(0));
obj.setTime(TimeFixture.INSTANCE.get(seedValue));
// TODO: ParameterFixture
obj.setParameters(Collections.<String, Parameter> emptyMap());
obj.setProviderName(ProviderFixture.INSTANCE.get(seedValue).getName());

View file

@ -20,17 +20,23 @@
package com.raytheon.uf.viz.datadelivery.utils;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static org.junit.Assert.assertEquals;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSet;
import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSetFixture;
import com.raytheon.uf.common.datadelivery.registry.Subscription;
import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture;
import com.raytheon.uf.common.datadelivery.registry.Time;
/**
* TODO Add Description
* Test {@link DataDeliveryUtils}.
*
* <pre>
*
@ -39,31 +45,75 @@ import com.raytheon.uf.common.datadelivery.registry.Time;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 14, 2013 1286 djohnson Initial creation
* Jan 22, 2013 1519 djohnson Add tests for getMaxLatency calculations.
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
public class DataDeliveryUtilsTest {
/**
* The method was throwing {@link IndexOutOfBoundsException}, this will
* prevent that regression.
*/
// These constants are not using TimeUtil to make sure we get a
// "second opinion" when using TimeUtil in the code under test
private static final long THREE_HOURS_AS_MINUTES = TimeUnit.HOURS
.toMinutes(3);
private static final long MINUTES_PER_DAY = TimeUnit.DAYS.toMinutes(1);
@Test
public void testMaxLatencyDoesntOverrunListIndex() {
public void maxLatencyReturnsMaxCyclicDifferenceForSubscribedToCycles() {
List<Integer> cycleTimes = newArrayList();
cycleTimes.add(0);
cycleTimes.add(1);
cycleTimes.add(2);
cycleTimes.add(4);
Subscription subscription = SubscriptionFixture.INSTANCE.get();
Time subTime = subscription.getTime();
subTime.setCycleTimes(cycleTimes);
DataDeliveryUtils.getMaxLatency(subscription);
assertEquals(THREE_HOURS_AS_MINUTES,
DataDeliveryUtils.getMaxLatency(subscription));
}
@Test
public void maxLatencyDefaultsToOneDayForSubscriptionWithOneCycle() {
List<Integer> cycleTimes = newArrayList();
cycleTimes.add(0);
Subscription subscription = SubscriptionFixture.INSTANCE.get();
Time subTime = subscription.getTime();
subTime.setCycleTimes(cycleTimes);
assertEquals(MINUTES_PER_DAY,
DataDeliveryUtils.getMaxLatency(subscription));
}
@Test
public void maxLatencyForDataSetWithOneCycleDefaultsToOneDay() {
Set<Integer> cycleTimes = newHashSet();
cycleTimes.add(0);
OpenDapGriddedDataSet dataset = OpenDapGriddedDataSetFixture.INSTANCE
.get();
dataset.setCycles(cycleTimes);
assertEquals(MINUTES_PER_DAY, DataDeliveryUtils.getMaxLatency(dataset));
}
@Test
public void maxLatencyForDataSetWithMultipleCyclesReturnsMaxCyclicDifference() {
Set<Integer> cycleTimes = newHashSet();
cycleTimes.add(0);
cycleTimes.add(1);
cycleTimes.add(4);
OpenDapGriddedDataSet dataset = OpenDapGriddedDataSetFixture.INSTANCE
.get();
dataset.setCycles(cycleTimes);
assertEquals(THREE_HOURS_AS_MINUTES,
DataDeliveryUtils.getMaxLatency(dataset));
}
}