mirror of https://github.com/apache/druid.git
fix JodaUtils.condenseIntervals(..) to correctly take end or current/next interval on overlap (#3793)
* remove unused duplicate JodaUtils.java * fix JodaUtils.condenseIntervals(..) to correctly take end or current/next interval on overlap
This commit is contained in:
parent
fd14997b1d
commit
c5df30d813
|
@ -23,9 +23,7 @@ import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
import io.druid.java.util.common.guava.Comparators;
|
import io.druid.java.util.common.guava.Comparators;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.Interval;
|
import org.joda.time.Interval;
|
||||||
|
|
||||||
|
@ -60,8 +58,15 @@ public class JodaUtils
|
||||||
while (intervalsIter.hasNext()) {
|
while (intervalsIter.hasNext()) {
|
||||||
Interval next = intervalsIter.next();
|
Interval next = intervalsIter.next();
|
||||||
|
|
||||||
if (currInterval.overlaps(next) || currInterval.abuts(next)) {
|
if (currInterval.abuts(next)) {
|
||||||
currInterval = new Interval(currInterval.getStart(), next.getEnd());
|
currInterval = new Interval(currInterval.getStart(), next.getEnd());
|
||||||
|
} else if(currInterval.overlaps(next)) {
|
||||||
|
DateTime nextEnd = next.getEnd();
|
||||||
|
DateTime currEnd = currInterval.getEnd();
|
||||||
|
currInterval = new Interval(
|
||||||
|
currInterval.getStart(),
|
||||||
|
nextEnd.isAfter(currEnd) ? nextEnd : currEnd
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
retVal.add(currInterval);
|
retVal.add(currInterval);
|
||||||
currInterval = next;
|
currInterval = next;
|
||||||
|
|
|
@ -104,7 +104,11 @@ public class JodaUtilsTest
|
||||||
new Interval("2011-02-03/2011-02-08"),
|
new Interval("2011-02-03/2011-02-08"),
|
||||||
new Interval("2011-03-01/2011-03-02"),
|
new Interval("2011-03-01/2011-03-02"),
|
||||||
new Interval("2011-03-03/2011-03-04"),
|
new Interval("2011-03-03/2011-03-04"),
|
||||||
new Interval("2011-03-05/2011-03-06")
|
new Interval("2011-03-05/2011-03-06"),
|
||||||
|
new Interval("2011-04-01/2011-04-05"),
|
||||||
|
new Interval("2011-04-02/2011-04-03"),
|
||||||
|
new Interval("2011-05-01/2011-05-05"),
|
||||||
|
new Interval("2011-05-02/2011-05-07")
|
||||||
);
|
);
|
||||||
|
|
||||||
for (int i = 0; i < 20; ++i) {
|
for (int i = 0; i < 20; ++i) {
|
||||||
|
@ -115,7 +119,9 @@ public class JodaUtilsTest
|
||||||
new Interval("2011-02-01/2011-02-08"),
|
new Interval("2011-02-01/2011-02-08"),
|
||||||
new Interval("2011-03-01/2011-03-02"),
|
new Interval("2011-03-01/2011-03-02"),
|
||||||
new Interval("2011-03-03/2011-03-04"),
|
new Interval("2011-03-03/2011-03-04"),
|
||||||
new Interval("2011-03-05/2011-03-06")
|
new Interval("2011-03-05/2011-03-06"),
|
||||||
|
new Interval("2011-04-01/2011-04-05"),
|
||||||
|
new Interval("2011-05-01/2011-05-07")
|
||||||
),
|
),
|
||||||
JodaUtils.condenseIntervals(intervals)
|
JodaUtils.condenseIntervals(intervals)
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,141 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Metamarkets Group Inc. (Metamarkets) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. Metamarkets licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.druid.java.util.common;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import io.druid.java.util.common.guava.Comparators;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.Interval;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class JodaUtils
|
|
||||||
{
|
|
||||||
public static ArrayList<Interval> condenseIntervals(Iterable<Interval> intervals)
|
|
||||||
{
|
|
||||||
ArrayList<Interval> retVal = Lists.newArrayList();
|
|
||||||
|
|
||||||
TreeSet<Interval> sortedIntervals = Sets.newTreeSet(Comparators.intervalsByStartThenEnd());
|
|
||||||
for (Interval interval : intervals) {
|
|
||||||
sortedIntervals.add(interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sortedIntervals.isEmpty()) {
|
|
||||||
return Lists.newArrayList();
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<Interval> intervalsIter = sortedIntervals.iterator();
|
|
||||||
Interval currInterval = intervalsIter.next();
|
|
||||||
while (intervalsIter.hasNext()) {
|
|
||||||
Interval next = intervalsIter.next();
|
|
||||||
|
|
||||||
if (currInterval.overlaps(next) || currInterval.abuts(next)) {
|
|
||||||
currInterval = new Interval(currInterval.getStart(), next.getEnd());
|
|
||||||
} else {
|
|
||||||
retVal.add(currInterval);
|
|
||||||
currInterval = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
retVal.add(currInterval);
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Interval umbrellaInterval(Iterable<Interval> intervals)
|
|
||||||
{
|
|
||||||
ArrayList<DateTime> startDates = Lists.newArrayList();
|
|
||||||
ArrayList<DateTime> endDates = Lists.newArrayList();
|
|
||||||
|
|
||||||
for (Interval interval : intervals) {
|
|
||||||
startDates.add(interval.getStart());
|
|
||||||
endDates.add(interval.getEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
DateTime minStart = minDateTime(startDates.toArray(new DateTime[]{}));
|
|
||||||
DateTime maxEnd = maxDateTime(endDates.toArray(new DateTime[]{}));
|
|
||||||
|
|
||||||
if (minStart == null || maxEnd == null) {
|
|
||||||
throw new IllegalArgumentException("Empty list of intervals");
|
|
||||||
}
|
|
||||||
return new Interval(minStart, maxEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean overlaps(final Interval i, Iterable<Interval> intervals)
|
|
||||||
{
|
|
||||||
return Iterables.any(
|
|
||||||
intervals, new Predicate<Interval>()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean apply(Interval input)
|
|
||||||
{
|
|
||||||
return input.overlaps(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DateTime minDateTime(DateTime... times)
|
|
||||||
{
|
|
||||||
if (times == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (times.length) {
|
|
||||||
case 0:
|
|
||||||
return null;
|
|
||||||
case 1:
|
|
||||||
return times[0];
|
|
||||||
default:
|
|
||||||
DateTime min = times[0];
|
|
||||||
for (int i = 1; i < times.length; ++i) {
|
|
||||||
min = min.isBefore(times[i]) ? min : times[i];
|
|
||||||
}
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DateTime maxDateTime(DateTime... times)
|
|
||||||
{
|
|
||||||
if (times == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (times.length) {
|
|
||||||
case 0:
|
|
||||||
return null;
|
|
||||||
case 1:
|
|
||||||
return times[0];
|
|
||||||
default:
|
|
||||||
DateTime max = times[0];
|
|
||||||
for (int i = 1; i < times.length; ++i) {
|
|
||||||
max = max.isAfter(times[i]) ? max : times[i];
|
|
||||||
}
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,122 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Metamarkets Group Inc. (Metamarkets) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. Metamarkets licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.druid.java.util.common;
|
|
||||||
|
|
||||||
import org.joda.time.Interval;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class JodaUtilsTest
|
|
||||||
{
|
|
||||||
@Test
|
|
||||||
public void testUmbrellaIntervalsSimple() throws Exception
|
|
||||||
{
|
|
||||||
List<Interval> intervals = Arrays.asList(
|
|
||||||
new Interval("2011-03-03/2011-03-04"),
|
|
||||||
new Interval("2011-01-01/2011-01-02"),
|
|
||||||
new Interval("2011-02-01/2011-02-05"),
|
|
||||||
new Interval("2011-02-03/2011-02-08"),
|
|
||||||
new Interval("2011-01-01/2011-01-03"),
|
|
||||||
new Interval("2011-03-01/2011-03-02"),
|
|
||||||
new Interval("2011-03-05/2011-03-06"),
|
|
||||||
new Interval("2011-02-01/2011-02-02")
|
|
||||||
);
|
|
||||||
|
|
||||||
Assert.assertEquals(
|
|
||||||
new Interval("2011-01-01/2011-03-06"),
|
|
||||||
JodaUtils.umbrellaInterval(intervals)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUmbrellaIntervalsNull() throws Exception
|
|
||||||
{
|
|
||||||
List<Interval> intervals = Arrays.asList();
|
|
||||||
Throwable thrown = null;
|
|
||||||
try {
|
|
||||||
Interval res = JodaUtils.umbrellaInterval(intervals);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e) {
|
|
||||||
thrown = e;
|
|
||||||
}
|
|
||||||
Assert.assertNotNull("Empty list of intervals", thrown);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCondenseIntervalsSimple() throws Exception
|
|
||||||
{
|
|
||||||
List<Interval> intervals = Arrays.asList(
|
|
||||||
new Interval("2011-01-01/2011-01-02"),
|
|
||||||
new Interval("2011-01-02/2011-01-03"),
|
|
||||||
new Interval("2011-02-01/2011-02-05"),
|
|
||||||
new Interval("2011-02-01/2011-02-02"),
|
|
||||||
new Interval("2011-02-03/2011-02-08"),
|
|
||||||
new Interval("2011-03-01/2011-03-02"),
|
|
||||||
new Interval("2011-03-03/2011-03-04"),
|
|
||||||
new Interval("2011-03-05/2011-03-06")
|
|
||||||
);
|
|
||||||
|
|
||||||
Assert.assertEquals(
|
|
||||||
Arrays.asList(
|
|
||||||
new Interval("2011-01-01/2011-01-03"),
|
|
||||||
new Interval("2011-02-01/2011-02-08"),
|
|
||||||
new Interval("2011-03-01/2011-03-02"),
|
|
||||||
new Interval("2011-03-03/2011-03-04"),
|
|
||||||
new Interval("2011-03-05/2011-03-06")
|
|
||||||
),
|
|
||||||
JodaUtils.condenseIntervals(intervals)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCondenseIntervalsMixedUp() throws Exception
|
|
||||||
{
|
|
||||||
List<Interval> intervals = Arrays.asList(
|
|
||||||
new Interval("2011-01-01/2011-01-02"),
|
|
||||||
new Interval("2011-01-02/2011-01-03"),
|
|
||||||
new Interval("2011-02-01/2011-02-05"),
|
|
||||||
new Interval("2011-02-01/2011-02-02"),
|
|
||||||
new Interval("2011-02-03/2011-02-08"),
|
|
||||||
new Interval("2011-03-01/2011-03-02"),
|
|
||||||
new Interval("2011-03-03/2011-03-04"),
|
|
||||||
new Interval("2011-03-05/2011-03-06")
|
|
||||||
);
|
|
||||||
|
|
||||||
for (int i = 0; i < 20; ++i) {
|
|
||||||
Collections.shuffle(intervals);
|
|
||||||
Assert.assertEquals(
|
|
||||||
Arrays.asList(
|
|
||||||
new Interval("2011-01-01/2011-01-03"),
|
|
||||||
new Interval("2011-02-01/2011-02-08"),
|
|
||||||
new Interval("2011-03-01/2011-03-02"),
|
|
||||||
new Interval("2011-03-03/2011-03-04"),
|
|
||||||
new Interval("2011-03-05/2011-03-06")
|
|
||||||
),
|
|
||||||
JodaUtils.condenseIntervals(intervals)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue