IntervalPredicate implements Predicate<T> { @Override public boolean test(T x) { long ts = timestampTransformer.apply(x); int pos = Collections.binarySearch(intervals, Range.is(ts), INTERVAL_COMPARATOR); if(pos < 0) { pos = -pos - 1; } Optional<Range<Long>> right = pos >= 0 && pos < intervals.size()?Optional.of(intervals.get(pos)):Optional.empty(); Optional<Range<Long>> left = pos - 1 >= 0 && pos - 1 < intervals.size()?Optional.of(intervals.get(pos - 1)):Optional.empty(); return (right.isPresent()?containsInclusive(right.get(),ts):false) || (left.isPresent()?containsInclusive(left.get(),ts):false); } IntervalPredicate(Function<T, Long> timestampTransformer, List<Range<Long>> intervals, Class<T> clazz); @Override boolean test(T x); static final Comparator<Range<Long>> INTERVAL_COMPARATOR; }
@Test public void testBasicTest() { List<Range<Long>> intervals = new ArrayList<Range<Long>>() {{ add(Range.between(0L, 10L)); add(Range.between(20L, 30L)); add(Range.between(40L, 50L)); }}; IntervalPredicate<Long> predicate = new IntervalPredicate.Identity(intervals); assertTrue(predicate.test(0L)); assertTrue(predicate.test(10L)); assertTrue(predicate.test(5L)); assertFalse(predicate.test(51L)); assertFalse(predicate.test(15L)); }
@Test public void testWithOverlap() { List<Range<Long>> intervals = new ArrayList<Range<Long>>() {{ add(Range.between(0L, 10L)); add(Range.between(5L, 30L)); add(Range.between(40L, 50L)); }}; IntervalPredicate<Long> predicate = new IntervalPredicate.Identity(intervals); assertTrue(predicate.test(0L)); assertTrue(predicate.test(5L)); assertTrue(predicate.test(30L)); assertTrue(predicate.test(10L)); assertFalse(predicate.test(51L)); assertTrue(predicate.test(15L)); assertFalse(predicate.test(31L)); assertTrue(predicate.test(45L)); }
@Test public void testTrivialCase() { List<Range<Long>> intervals = new ArrayList<Range<Long>>() {{ add(Range.between(0L, 10L)); }}; IntervalPredicate<Long> predicate = new IntervalPredicate.Identity(intervals); assertTrue(predicate.test(0L)); assertTrue(predicate.test(5L)); assertTrue(predicate.test(10L)); assertFalse(predicate.test(51L)); assertFalse(predicate.test(15L)); }
@Test public void testDegenerateCase() { List<Range<Long>> intervals = new ArrayList<Range<Long>>() {{ add(Range.between(10L, 10L)); }}; IntervalPredicate<Long> predicate = new IntervalPredicate.Identity(intervals); assertFalse(predicate.test(0L)); assertFalse(predicate.test(5L)); assertTrue(predicate.test(10L)); assertFalse(predicate.test(11L)); }