package mil.nga.giat.geowave.core.index;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/***
* Defines a unit interval on a number line
*
*/
public class ByteArrayRange implements
Comparable<ByteArrayRange>
{
protected ByteArrayId start;
protected ByteArrayId end;
protected boolean singleValue;
/***
*
* @param start
* start of unit interval
* @param end
* end of unit interval
*/
public ByteArrayRange(
final ByteArrayId start,
final ByteArrayId end ) {
this(
start,
end,
false);
}
/***
*
* @param start
* start of unit interval
* @param end
* end of unit interval
*/
public ByteArrayRange(
final ByteArrayId start,
final ByteArrayId end,
boolean singleValue ) {
this.start = start;
this.end = end;
this.singleValue = singleValue;
}
public ByteArrayId getStart() {
return start;
}
public ByteArrayId getEnd() {
return end;
}
public boolean isSingleValue() {
return singleValue;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((end == null) ? 0 : end.hashCode());
result = prime * result + (singleValue ? 1231 : 1237);
result = prime * result + ((start == null) ? 0 : start.hashCode());
return result;
}
@Override
public boolean equals(
Object obj ) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
ByteArrayRange other = (ByteArrayRange) obj;
if (end == null) {
if (other.end != null) return false;
}
else if (!end.equals(other.end)) return false;
if (singleValue != other.singleValue) return false;
if (start == null) {
if (other.start != null) return false;
}
else if (!start.equals(other.start)) return false;
return true;
}
public boolean intersects(
ByteArrayRange other ) {
return ((getStart().compareTo(other.getEnd())) <= 0 && (getEnd().compareTo(other.getStart())) >= 0);
}
public ByteArrayRange intersection(
ByteArrayRange other ) {
return new ByteArrayRange(
this.start.compareTo(other.start) <= 0 ? other.start : this.start,
this.end.compareTo(other.end) >= 0 ? other.end : this.end);
}
public ByteArrayRange union(
ByteArrayRange other ) {
return new ByteArrayRange(
this.start.compareTo(other.start) <= 0 ? this.start : other.start,
this.end.compareTo(other.end) >= 0 ? this.end : other.end);
}
@Override
public int compareTo(
ByteArrayRange other ) {
final int diff = getStart().compareTo(
other.getStart());
return diff != 0 ? diff : getEnd().compareTo(
other.getEnd());
}
public static enum MergeOperation {
UNION,
INTERSECTION
}
public static final List<ByteArrayRange> mergeIntersections(
List<ByteArrayRange> ranges,
MergeOperation op ) {
// sort order so the first range can consume following ranges
Collections.<ByteArrayRange> sort(ranges);
final List<ByteArrayRange> result = new ArrayList<ByteArrayRange>();
for (int i = 0; i < ranges.size();) {
ByteArrayRange r1 = ranges.get(i);
int j = i + 1;
for (; j < ranges.size(); j++) {
final ByteArrayRange r2 = ranges.get(j);
if (r1.intersects(r2)) {
if (op.equals(MergeOperation.UNION)) {
r1 = r1.union(r2);
}
else {
r1 = r1.intersection(r2);
}
}
else {
break;
}
}
i = j;
result.add(r1);
}
return result;
}
}