private static Pair<DimFilter, RangeSet<Long>> extractConvertibleTimeBounds(final DimFilter filter)
  {
    if (filter instanceof AndDimFilter) {
      final List<DimFilter> children = ((AndDimFilter) filter).getFields();
      final List<DimFilter> newChildren = new ArrayList<>();
      final List<RangeSet<Long>> rangeSets = new ArrayList<>();

      for (DimFilter child : children) {
        final Pair<DimFilter, RangeSet<Long>> pair = extractConvertibleTimeBounds(child);
        if (pair.lhs != null) {
          newChildren.add(pair.lhs);
        }
        if (pair.rhs != null) {
          rangeSets.add(pair.rhs);
        }
      }

      final DimFilter newFilter;
      if (newChildren.size() == 0) {
        newFilter = null;
      } else if (newChildren.size() == 1) {
        newFilter = newChildren.get(0);
      } else {
        newFilter = new AndDimFilter(newChildren);
      }

      return Pair.of(
          newFilter,
          rangeSets.isEmpty() ? null : RangeSets.intersectRangeSets(rangeSets)
      );
    } else if (filter instanceof OrDimFilter) {
      final List<DimFilter> children = ((OrDimFilter) filter).getFields();
      final List<RangeSet<Long>> rangeSets = new ArrayList<>();

      boolean allCompletelyConverted = true;
      boolean allHadIntervals = true;
      for (DimFilter child : children) {
        final Pair<DimFilter, RangeSet<Long>> pair = extractConvertibleTimeBounds(child);
        if (pair.lhs != null) {
          allCompletelyConverted = false;
        }
        if (pair.rhs != null) {
          rangeSets.add(pair.rhs);
        } else {
          allHadIntervals = false;
        }
      }

      if (allCompletelyConverted) {
        return Pair.of(null, RangeSets.unionRangeSets(rangeSets));
      } else {
        return Pair.of(filter, allHadIntervals ? RangeSets.unionRangeSets(rangeSets) : null);
      }
    } else if (filter instanceof NotDimFilter) {
      final DimFilter child = ((NotDimFilter) filter).getField();
      final Pair<DimFilter, RangeSet<Long>> pair = extractConvertibleTimeBounds(child);
      if (pair.rhs != null && pair.lhs == null) {
        return Pair.of(null, pair.rhs.complement());
      } else {
        return Pair.of(filter, null);
      }
    } else if (filter instanceof BoundDimFilter) {
      final BoundDimFilter bound = (BoundDimFilter) filter;
      if (BoundRefKey.from(bound).equals(TIME_BOUND_REF_KEY)) {
        return Pair.of(null, RangeSets.of(toLongRange(Bounds.toRange(bound))));
      } else {
        return Pair.of(filter, null);
      }
    } else {
      return Pair.of(filter, null);
    }
  }
private static Pair < DimFilter , RangeSet < Long > > extractConvertibleTimeBounds ( final DimFilter filter ) { if ( filter instanceof AndDimFilter ) { final List < DimFilter > children = ( ( AndDimFilter ) filter ) . getFields ( ) ; final List < DimFilter > newChildren = new ArrayList < > ( ) ; final List < RangeSet < Long > > rangeSets = new ArrayList < > ( ) ; for ( DimFilter child : children ) { final Pair < DimFilter , RangeSet < Long > > pair = extractConvertibleTimeBounds ( child ) ; if ( pair . lhs != null ) { newChildren . add ( pair . lhs ) ; } if ( pair . rhs != null ) { rangeSets . add ( pair . rhs ) ; } } final DimFilter newFilter ; if ( newChildren . size ( ) == 0 ) { newFilter = null ; } else if ( newChildren . size ( ) == 1 ) { newFilter = newChildren . get ( 0 ) ; } else { newFilter = new AndDimFilter ( newChildren ) ; } return Pair . of ( newFilter , rangeSets . isEmpty ( ) ? null : RangeSets . intersectRangeSets ( rangeSets ) ) ; } else if ( filter instanceof OrDimFilter ) { final List < DimFilter > children = ( ( OrDimFilter ) filter ) . getFields ( ) ; final List < RangeSet < Long > > rangeSets = new ArrayList < > ( ) ; boolean allCompletelyConverted = true ; boolean allHadIntervals = true ; for ( DimFilter child : children ) { final Pair < DimFilter , RangeSet < Long > > pair = extractConvertibleTimeBounds ( child ) ; if ( pair . lhs != null ) { allCompletelyConverted = false ; } if ( pair . rhs != null ) { rangeSets . add ( pair . rhs ) ; } else { allHadIntervals = false ; } } if ( allCompletelyConverted ) { return Pair . of ( null , RangeSets . unionRangeSets ( rangeSets ) ) ; } else { return Pair . of ( filter , allHadIntervals ? RangeSets . unionRangeSets ( rangeSets ) : null ) ; } } else if ( filter instanceof NotDimFilter ) { final DimFilter child = ( ( NotDimFilter ) filter ) . getField ( ) ; final Pair < DimFilter , RangeSet < Long > > pair = extractConvertibleTimeBounds ( child ) ; if ( pair . rhs != null && pair . lhs == null ) { return Pair . of ( null , pair . rhs . complement ( ) ) ; } else { return Pair . of ( filter , null ) ; } } else if ( filter instanceof BoundDimFilter ) { final BoundDimFilter bound = ( BoundDimFilter ) filter ; if ( BoundRefKey . from ( bound ) . equals ( TIME_BOUND_REF_KEY ) ) { return Pair . of ( null , RangeSets . of ( toLongRange ( Bounds . toRange ( bound ) ) ) ) ; } else { return Pair . of ( filter , null ) ; } } else { return Pair . of ( filter , null ) ; } }
Extract bound filters on __time that can be converted to query-level "intervals".

@return pair of new dimFilter + RangeSet of __time that should be ANDed together. Either can be null but not both.