55 */
66package org .elasticsearch .xpack .rollup ;
77
8+ import org .elasticsearch .common .rounding .DateTimeUnit ;
89import org .elasticsearch .common .unit .TimeValue ;
910import org .elasticsearch .search .aggregations .AggregationBuilder ;
1011import org .elasticsearch .search .aggregations .bucket .histogram .DateHistogramAggregationBuilder ;
12+ import org .elasticsearch .search .aggregations .bucket .histogram .DateHistogramInterval ;
1113import org .elasticsearch .search .aggregations .bucket .histogram .HistogramAggregationBuilder ;
1214import org .elasticsearch .search .aggregations .bucket .terms .TermsAggregationBuilder ;
1315import org .elasticsearch .search .aggregations .support .ValuesSourceAggregationBuilder ;
3032 */
3133public class RollupJobIdentifierUtils {
3234
33- private static final Comparator <RollupJobCaps > COMPARATOR = RollupJobIdentifierUtils .getComparator ();
35+ static final Comparator <RollupJobCaps > COMPARATOR = RollupJobIdentifierUtils .getComparator ();
3436
3537 /**
3638 * Given the aggregation tree and a list of available job capabilities, this method will return a set
@@ -133,6 +135,57 @@ private static void checkDateHisto(DateHistogramAggregationBuilder source, List<
133135 }
134136 }
135137
138+ private static boolean isCalendarInterval (DateHistogramInterval interval ) {
139+ return DateHistogramAggregationBuilder .DATE_FIELD_UNITS .containsKey (interval .toString ());
140+ }
141+
142+ static boolean validateCalendarInterval (DateHistogramInterval requestInterval ,
143+ DateHistogramInterval configInterval ) {
144+ // Both must be calendar intervals
145+ if (isCalendarInterval (requestInterval ) == false || isCalendarInterval (configInterval ) == false ) {
146+ return false ;
147+ }
148+
149+ // The request must be gte the config. The CALENDAR_ORDERING map values are integers representing
150+ // relative orders between the calendar units
151+ DateTimeUnit requestUnit = DateHistogramAggregationBuilder .DATE_FIELD_UNITS .get (requestInterval .toString ());
152+ long requestOrder = requestUnit .field (DateTimeZone .UTC ).getDurationField ().getUnitMillis ();
153+ DateTimeUnit configUnit = DateHistogramAggregationBuilder .DATE_FIELD_UNITS .get (configInterval .toString ());
154+ long configOrder = configUnit .field (DateTimeZone .UTC ).getDurationField ().getUnitMillis ();
155+
156+ // All calendar units are multiples naturally, so we just care about gte
157+ return requestOrder >= configOrder ;
158+ }
159+
160+ static boolean validateFixedInterval (DateHistogramInterval requestInterval ,
161+ DateHistogramInterval configInterval ) {
162+ // Neither can be calendar intervals
163+ if (isCalendarInterval (requestInterval ) || isCalendarInterval (configInterval )) {
164+ return false ;
165+ }
166+
167+ // Both are fixed, good to convert to millis now
168+ long configIntervalMillis = TimeValue .parseTimeValue (configInterval .toString (),
169+ "date_histo.config.interval" ).getMillis ();
170+ long requestIntervalMillis = TimeValue .parseTimeValue (requestInterval .toString (),
171+ "date_histo.request.interval" ).getMillis ();
172+
173+ // Must be a multiple and gte the config
174+ return requestIntervalMillis >= configIntervalMillis && requestIntervalMillis % configIntervalMillis == 0 ;
175+ }
176+
177+ static boolean validateFixedInterval (long requestInterval , DateHistogramInterval configInterval ) {
178+ // config must not be a calendar interval
179+ if (isCalendarInterval (configInterval )) {
180+ return false ;
181+ }
182+ long configIntervalMillis = TimeValue .parseTimeValue (configInterval .toString (),
183+ "date_histo.config.interval" ).getMillis ();
184+
185+ // Must be a multiple and gte the config
186+ return requestInterval >= configIntervalMillis && requestInterval % configIntervalMillis == 0 ;
187+ }
188+
136189 /**
137190 * Find the set of histo's with the largest interval
138191 */
@@ -247,8 +300,8 @@ private static Comparator<RollupJobCaps> getComparator() {
247300 return 0 ;
248301 }
249302
250- TimeValue thisTime = null ;
251- TimeValue thatTime = null ;
303+ long thisTime = Long . MAX_VALUE ;
304+ long thatTime = Long . MAX_VALUE ;
252305
253306 // histogram intervals are averaged and compared, with the idea that
254307 // a larger average == better, because it will generate fewer documents
@@ -265,7 +318,7 @@ private static Comparator<RollupJobCaps> getComparator() {
265318 for (RollupJobCaps .RollupFieldCaps fieldCaps : o1 .getFieldCaps ().values ()) {
266319 for (Map <String , Object > agg : fieldCaps .getAggs ()) {
267320 if (agg .get (RollupField .AGG ).equals (DateHistogramAggregationBuilder .NAME )) {
268- thisTime = TimeValue . parseTimeValue ((String ) agg .get (RollupField .INTERVAL ), RollupField . INTERVAL );
321+ thisTime = getMillisFixedOrCalendar ((String ) agg .get (RollupField .INTERVAL ));
269322 } else if (agg .get (RollupField .AGG ).equals (HistogramAggregationBuilder .NAME )) {
270323 thisHistoWeights += (long ) agg .get (RollupField .INTERVAL );
271324 counter += 1 ;
@@ -281,7 +334,7 @@ private static Comparator<RollupJobCaps> getComparator() {
281334 for (RollupJobCaps .RollupFieldCaps fieldCaps : o2 .getFieldCaps ().values ()) {
282335 for (Map <String , Object > agg : fieldCaps .getAggs ()) {
283336 if (agg .get (RollupField .AGG ).equals (DateHistogramAggregationBuilder .NAME )) {
284- thatTime = TimeValue . parseTimeValue ((String ) agg .get (RollupField .INTERVAL ), RollupField . INTERVAL );
337+ thatTime = getMillisFixedOrCalendar ((String ) agg .get (RollupField .INTERVAL ));
285338 } else if (agg .get (RollupField .AGG ).equals (HistogramAggregationBuilder .NAME )) {
286339 thatHistoWeights += (long ) agg .get (RollupField .INTERVAL );
287340 counter += 1 ;
@@ -292,13 +345,9 @@ private static Comparator<RollupJobCaps> getComparator() {
292345 }
293346 thatHistoWeights = counter == 0 ? 0 : thatHistoWeights / counter ;
294347
295- // DateHistos are mandatory so these should always be present no matter what
296- assert thisTime != null ;
297- assert thatTime != null ;
298-
299348 // Compare on date interval first
300349 // The "smaller" job is the one with the larger interval
301- int timeCompare = thisTime . compareTo ( thatTime );
350+ int timeCompare = Long . compare ( thisTime , thatTime );
302351 if (timeCompare != 0 ) {
303352 return -timeCompare ;
304353 }
@@ -330,4 +379,14 @@ private static Comparator<RollupJobCaps> getComparator() {
330379 // coverage
331380 };
332381 }
382+
383+ static long getMillisFixedOrCalendar (String value ) {
384+ DateHistogramInterval interval = new DateHistogramInterval (value );
385+ if (isCalendarInterval (interval )) {
386+ DateTimeUnit intervalUnit = DateHistogramAggregationBuilder .DATE_FIELD_UNITS .get (interval .toString ());
387+ return intervalUnit .field (DateTimeZone .UTC ).getDurationField ().getUnitMillis ();
388+ } else {
389+ return TimeValue .parseTimeValue (value , "date_histo.comparator.interval" ).getMillis ();
390+ }
391+ }
333392}
0 commit comments