package mil.nga.giat.geowave.core.store.index.temporal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.index.ByteArrayRange;
import mil.nga.giat.geowave.core.store.filter.DistributableQueryFilter;
import mil.nga.giat.geowave.core.store.index.FilterableConstraints;
/**
* A class based on FilterableConstraints that uses temporal values and includes
* a start date and end date
*
* @author geowave
*
*/
public class TemporalQueryConstraint implements
FilterableConstraints
{
protected final ByteArrayId fieldId;
protected final Date start;
protected final Date end;
protected boolean inclusiveLow;
protected boolean inclusiveHigh;
public TemporalQueryConstraint(
final ByteArrayId fieldId,
final Date start,
final Date end ) {
this(
fieldId,
start,
end,
false,
false);
}
@Override
public ByteArrayId getFieldId() {
return fieldId;
}
public TemporalQueryConstraint(
final ByteArrayId fieldId,
final Date start,
final Date end,
boolean inclusiveLow,
boolean inclusiveHigh ) {
super();
this.fieldId = fieldId;
this.start = start;
this.end = end;
this.inclusiveHigh = inclusiveHigh;
this.inclusiveLow = inclusiveLow;
}
@Override
public int getDimensionCount() {
return 1;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public DistributableQueryFilter getFilter() {
return new DateRangeFilter(
fieldId,
start,
end,
inclusiveLow,
inclusiveHigh);
}
/**
* Creates a collection of range values based on start and end times for
* this constraint
*
* @return
*/
public List<ByteArrayRange> getRange() {
return Collections.singletonList(new ByteArrayRange(
new ByteArrayId(
TemporalIndexStrategy.toIndexByte(start)),
new ByteArrayId(
TemporalIndexStrategy.toIndexByte(end))));
}
/**
*
* Returns an FilterableConstraints object that is the intersection of the
* start and end times of this object and object passed in.
* <p>
* This method returns an object with the latest start and earliest end of
* the two objects
*
* @param otherConstraint
* object whose constraints are 'intersected' with existing
* constraints
* @return new {@link FilterableConstraints}
*/
@Override
public FilterableConstraints intersect(
FilterableConstraints constraints ) {
if (constraints instanceof TemporalQueryConstraint) {
TemporalQueryConstraint filterConstraints = (TemporalQueryConstraint) constraints;
if (fieldId.equals(filterConstraints.fieldId)) {
Date newStart = start.compareTo(filterConstraints.start) < 0 ? filterConstraints.start : start;
Date newEnd = end.compareTo(filterConstraints.end) > 0 ? filterConstraints.end : end;
final boolean lowEquals = start.equals(filterConstraints.start);
final boolean upperEquals = end.equals(filterConstraints.end);
final boolean replaceMin = start.compareTo(filterConstraints.start) < 0;
final boolean replaceMax = end.compareTo(filterConstraints.end) > 0;
boolean newInclusiveLow = lowEquals ? filterConstraints.inclusiveLow & inclusiveLow
: (replaceMin ? filterConstraints.inclusiveLow : inclusiveLow);
boolean newInclusiveHigh = upperEquals ? filterConstraints.inclusiveHigh & inclusiveHigh
: (replaceMax ? filterConstraints.inclusiveHigh : inclusiveHigh);
return new TemporalQueryConstraint(
fieldId,
newStart,
newEnd,
newInclusiveLow,
newInclusiveHigh);
}
}
return this;
}
/**
*
* Returns an FilterableConstraints object that is the union of the start
* and end times of this object and object passed in.
* <p>
* This method returns an object with the earliest start and latest end time
* of the two objects
*
* @param otherConstraint
* object whose constraints are 'unioned' with existing
* constraints
* @return new {@link FilterableConstraints}
*/
@Override
public FilterableConstraints union(
FilterableConstraints constraints ) {
if (constraints instanceof TemporalQueryConstraint) {
TemporalQueryConstraint filterConstraints = (TemporalQueryConstraint) constraints;
if (fieldId.equals(filterConstraints.fieldId)) {
Date newStart = start.compareTo(filterConstraints.start) > 0 ? filterConstraints.start : start;
Date newEnd = end.compareTo(filterConstraints.end) < 0 ? filterConstraints.end : end;
final boolean lowEquals = start.equals(filterConstraints.start);
final boolean upperEquals = end.equals(filterConstraints.end);
final boolean replaceMin = start.compareTo(filterConstraints.start) > 0;
final boolean replaceMax = end.compareTo(filterConstraints.end) < 0;
boolean newInclusiveLow = lowEquals ? filterConstraints.inclusiveLow | inclusiveLow
: (replaceMin ? filterConstraints.inclusiveLow : inclusiveLow);
boolean newInclusiveHigh = upperEquals ? filterConstraints.inclusiveHigh | inclusiveHigh
: (replaceMax ? filterConstraints.inclusiveHigh : inclusiveHigh);
return new TemporalQueryConstraint(
fieldId,
newStart,
newEnd,
newInclusiveLow,
newInclusiveHigh);
}
}
return this;
}
}