Created
June 21, 2013 09:04
-
-
Save delexi/5829907 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package squirrel.util; | |
| import java.util.Arrays; | |
| import java.util.Comparator; | |
| /** | |
| * An instance of this class represents a range between a defined {@code start} | |
| * and {@code end} (both including). It is at all times true that {@code start} | |
| * is less or equal to {@code end}. | |
| */ | |
| public class Range { | |
| public static Comparator<Range> START_COMPARATOR = new StartComparator(); | |
| public static Comparator<Range> END_COMPARATOR = new EndComparator(); | |
| private long start; | |
| private long end; | |
| public Range(long start, long end) { | |
| checkRange(start, end); | |
| this.start = start; | |
| this.end = end; | |
| } | |
| public void setStart(long start) { | |
| checkRange(start, end); | |
| this.start = start; | |
| } | |
| public long getStart() { | |
| return start; | |
| } | |
| public void setEnd(long end) { | |
| checkRange(start, end); | |
| this.end = end; | |
| } | |
| public long getEnd() { | |
| return end; | |
| } | |
| public void setBounds(long start, long end) { | |
| checkRange(start, end); | |
| setStart(start); | |
| setEnd(end); | |
| } | |
| public Range move(long amount) { | |
| return new Range(getStart() + amount, getEnd() + amount); | |
| } | |
| public Range union(Range other) { | |
| if (other == null) throw new IllegalArgumentException("[other] may not be null."); | |
| if (other.equals(this) || this.contains(other)) | |
| return this; | |
| if (other.contains(this)) | |
| return other; | |
| long[] bounds = new long[] { this.getStart(), this.getEnd(), | |
| other.getStart(), other.getEnd()}; | |
| Arrays.sort(bounds); | |
| return new Range(bounds[0], bounds[3]); | |
| } | |
| public boolean contains(Range other) { | |
| if (other == null) throw new IllegalArgumentException("[other] may not be null."); | |
| return this.getStart() <= other.getStart() && other.getEnd() <= this.getEnd(); | |
| } | |
| public boolean contains(long timestamp) { | |
| return start <= timestamp && timestamp <= end; | |
| } | |
| @Override | |
| public boolean equals(Object other) { | |
| if (other == null) | |
| return false; | |
| if (!(other instanceof Range)) | |
| return false; | |
| if (this == other) | |
| return true; | |
| Range r = (Range) other; | |
| return this.start == r.getStart() && this.end == r.getEnd(); | |
| } | |
| @Override | |
| public int hashCode() { | |
| return (int) ((start + end) % Integer.MAX_VALUE); | |
| } | |
| @Override | |
| public String toString() { | |
| return String.format("[%d, %d]", start, end); | |
| } | |
| private void checkRange(long start, long end) { | |
| if (start > end) { | |
| throw new IllegalArgumentException( | |
| String.format("start(=%d) is not <= end(=%d).", start, end)); | |
| } | |
| } | |
| static class StartComparator implements Comparator<Range> { | |
| @Override | |
| public int compare(Range range1, Range range2) { | |
| if (range1.getStart() == range2.getStart()) { | |
| return compareLongs(range1.getEnd(), range2.getEnd()); | |
| } else { | |
| return compareLongs(range1.getStart(), range2.getStart()); | |
| } | |
| } | |
| } | |
| static class EndComparator implements Comparator<Range> { | |
| @Override | |
| public int compare(Range range1, Range range2) { | |
| if (range1.getEnd() == range2.getEnd()) { | |
| return compareLongs(range1.getStart(), range2.getStart()); | |
| } else { | |
| return compareLongs(range1.getEnd(), range2.getEnd()); | |
| } | |
| } | |
| } | |
| private static int compareLongs(long l1, long l2) { | |
| if (l1 == l2) return 0; | |
| return l1 < l2 ? 1 : -1; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment