/*
* Copyright 2013 Cloudera Inc.
*
* Licensed 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 org.kitesdk.data.spi.predicates;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.BoundType;
import com.google.common.collect.DiscreteDomain;
import java.util.Set;
public class Ranges {
public static <T> Range<T> open(T lower, T upper) {
return new Range<T>(Range.bound(lower, false), Range.bound(upper, false));
}
public static <T> Range<T> closed(T lower, T upper) {
return new Range<T>(Range.bound(lower, true), Range.bound(upper, true));
}
public static <T> Range<T> closedOpen(T lower, T upper) {
return new Range<T>(Range.bound(lower, true), Range.bound(upper, false));
}
public static <T> Range<T> openClosed(T lower, T upper) {
return new Range<T>(Range.bound(lower, false), Range.bound(upper, true));
}
public static <T> Range<T> greaterThan(T endpoint) {
return new Range<T>(Range.bound(endpoint, false), null);
}
public static <T> Range<T> atLeast(T endpoint) {
return new Range<T>(Range.bound(endpoint, true), null);
}
public static <T> Range<T> lessThan(T endpoint) {
return new Range<T>(null, Range.bound(endpoint, false));
}
public static <T> Range<T> atMost(T endpoint) {
return new Range<T>(null, Range.bound(endpoint, true));
}
public static <T> Range<T> all() {
return new Range<T>(null, null);
}
public static <T> Range<T> singleton(T endpoint) {
return new Range<T>(Range.bound(endpoint, true), Range.bound(endpoint, true));
}
public static <S extends Comparable, T extends Comparable>
Range<T> transformClosed(Range<S> range, Function<? super S, T> function) {
if (range.hasLowerBound()) {
if (range.hasUpperBound()) {
return closed(
function.apply(range.lowerEndpoint()),
function.apply(range.upperEndpoint()));
} else {
return atLeast(function.apply(range.lowerEndpoint()));
}
} else if (range.hasUpperBound()) {
return atMost(function.apply(range.upperEndpoint()));
} else {
return null;
}
}
public static <T extends Comparable>
Range<T> adjustClosed(Range<T> range, DiscreteDomain<T> domain) {
// adjust to a closed range to avoid catching extra keys
if (range.hasLowerBound()) {
T lower = range.lowerEndpoint();
if (range.isLowerBoundOpen()) {
lower = domain.next(lower);
}
if (range.hasUpperBound()) {
T upper = range.upperEndpoint();
if (range.isUpperBoundOpen()) {
upper = domain.previous(upper);
}
return closed(lower, upper);
} else {
return atLeast(lower);
}
} else if (range.hasUpperBound()) {
T upper = range.upperEndpoint();
if (range.isUpperBoundOpen()) {
upper = domain.previous(upper);
}
return atMost(upper);
} else {
throw new IllegalArgumentException("Invalid range: no endpoints");
}
}
public static <C extends Comparable<C>> Set<C> asSet(
Range<C> range, DiscreteDomain<C> domain) {
// cheat and pass this to guava
return asGuavaRange(range).asSet(domain);
}
@VisibleForTesting
static <C extends Comparable<C>> com.google.common.collect.Range<C> asGuavaRange(
Range<C> range) {
if (range.hasLowerBound()) {
if (range.hasUpperBound()) {
return com.google.common.collect.Ranges.range(
range.lowerEndpoint(),
range.isLowerBoundOpen() ? BoundType.OPEN : BoundType.CLOSED,
range.upperEndpoint(),
range.isUpperBoundOpen() ? BoundType.OPEN : BoundType.CLOSED);
} else {
return com.google.common.collect.Ranges.downTo(
range.lowerEndpoint(),
range.isLowerBoundOpen() ? BoundType.OPEN : BoundType.CLOSED);
}
} else if (range.hasUpperBound()) {
return com.google.common.collect.Ranges.upTo(
range.upperEndpoint(),
range.isUpperBoundOpen() ? BoundType.OPEN : BoundType.CLOSED);
} else {
return com.google.common.collect.Ranges.all();
}
}
}