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.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;
|
||||
|
||||
|
@ -60,8 +58,15 @@ public class JodaUtils
|
|||
while (intervalsIter.hasNext()) {
|
||||
Interval next = intervalsIter.next();
|
||||
|
||||
if (currInterval.overlaps(next) || currInterval.abuts(next)) {
|
||||
if (currInterval.abuts(next)) {
|
||||
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 {
|
||||
retVal.add(currInterval);
|
||||
currInterval = next;
|
||||
|
|
|
@ -104,7 +104,11 @@ public class JodaUtilsTest
|
|||
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")
|
||||
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) {
|
||||
|
@ -115,7 +119,9 @@ public class JodaUtilsTest
|
|||
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")
|
||||
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)
|
||||
);
|
||||
|
|
|
@ -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