All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.calcite.linq4j.Linq4j Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 org.apache.calcite.linq4j;
import org.apache.calcite.linq4j.function.Function1;
import com.google.common.collect.Lists;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
/**
* Utility and factory methods for Linq4j.
*/
public abstract class Linq4j {
private Linq4j() {}
private static final Object DUMMY = new Object();
public static Method getMethod(String className, String methodName,
Class... parameterTypes) {
try {
return Class.forName(className).getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
/**
* Query provider that simply executes a {@link Queryable} by calling its
* enumerator method; does not attempt optimization.
*/
public static final QueryProvider DEFAULT_PROVIDER = new QueryProviderImpl() {
public Enumerator executeQuery(Queryable queryable) {
return queryable.enumerator();
}
};
private static final Enumerator EMPTY_ENUMERATOR =
new Enumerator() {
public Object current() {
throw new NoSuchElementException();
}
public boolean moveNext() {
return false;
}
public void reset() {
}
public void close() {
}
};
public static final Enumerable> EMPTY_ENUMERABLE =
new AbstractEnumerable() {
public Enumerator enumerator() {
return EMPTY_ENUMERATOR;
}
};
/**
* Adapter that converts an enumerator into an iterator.
*
* WARNING : The iterator returned by this method does not call
* {@link org.apache.calcite.linq4j.Enumerator#close()}, so it is not safe to
* use with an enumerator that allocates resources.
*
* @param enumerator Enumerator
* @param Element type
*
* @return Iterator
*/
public static Iterator enumeratorIterator(Enumerator enumerator) {
return new EnumeratorIterator<>(enumerator);
}
/**
* Adapter that converts an iterable into an enumerator.
*
* @param iterable Iterable
* @param Element type
*
* @return enumerator
*/
public static Enumerator iterableEnumerator(
final Iterable extends T> iterable) {
if (iterable instanceof Enumerable) {
@SuppressWarnings("unchecked") final Enumerable enumerable =
(Enumerable) iterable;
return enumerable.enumerator();
}
return new IterableEnumerator<>(iterable);
}
/**
* Adapter that converts an {@link List} into an {@link Enumerable}.
*
* @param list List
* @param Element type
*
* @return enumerable
*/
public static Enumerable asEnumerable(final List list) {
return new ListEnumerable<>(list);
}
/**
* Adapter that converts an {@link Collection} into an {@link Enumerable}.
*
* It uses more efficient implementations if the iterable happens to
* be a {@link List}.
*
* @param collection Collection
* @param Element type
*
* @return enumerable
*/
public static Enumerable asEnumerable(final Collection collection) {
if (collection instanceof List) {
//noinspection unchecked
return asEnumerable((List) collection);
}
return new CollectionEnumerable<>(collection);
}
/**
* Adapter that converts an {@link Iterable} into an {@link Enumerable}.
*
* It uses more efficient implementations if the iterable happens to
* be a {@link Collection} or a {@link List}.
*
* @param iterable Iterable
* @param Element type
*
* @return enumerable
*/
public static Enumerable asEnumerable(final Iterable iterable) {
if (iterable instanceof Collection) {
//noinspection unchecked
return asEnumerable((Collection) iterable);
}
return new IterableEnumerable<>(iterable);
}
/**
* Adapter that converts an array into an enumerable.
*
* @param ts Array
* @param Element type
*
* @return enumerable
*/
public static Enumerable asEnumerable(final T[] ts) {
return new ListEnumerable<>(Arrays.asList(ts));
}
/**
* Adapter that converts a collection into an enumerator.
*
* @param values Collection
* @param Element type
*
* @return Enumerator over the collection
*/
public static Enumerator enumerator(Collection extends V> values) {
if (values instanceof List && values instanceof RandomAccess) {
//noinspection unchecked
return listEnumerator((List) values);
}
return iterableEnumerator(values);
}
private static Enumerator listEnumerator(List extends V> list) {
return new ListEnumerator<>(list);
}
/** Applies a function to each element of an Enumerator.
*
* @param enumerator Backing enumerator
* @param func Transform function
* @param Backing element type
* @param Element type
* @return Enumerator
*/
public static Enumerator transform(Enumerator enumerator,
final Function1 func) {
return new TransformedEnumerator(enumerator) {
protected E transform(F from) {
return func.apply(from);
}
};
}
/**
* Converts the elements of a given Iterable to the specified type.
*
* This method is implemented by using deferred execution. The immediate
* return value is an object that stores all the information that is
* required to perform the action. The query represented by this method is
* not executed until the object is enumerated either by calling its
* {@link Enumerable#enumerator} method directly or by using
* {@code for (... in ...)}.
*
*
Since standard Java {@link Collection} objects implement the
* {@link Iterable} interface, the {@code cast} method enables the standard
* query operators to be invoked on collections
* (including {@link java.util.List} and {@link java.util.Set}) by supplying
* the necessary type information. For example, {@link ArrayList} does not
* implement {@link Enumerable}<F>, but you can invoke
*
*
Linq4j.cast(list, Integer.class)
*
* to convert the list of an enumerable that can be queried using the
* standard query operators.
*
* If an element cannot be cast to type <TResult>, this method will
* throw a {@link ClassCastException}. To obtain only those elements that
* can be cast to type TResult, use the {@link #ofType} method instead.
*
* @see Enumerable#cast(Class)
* @see #ofType
* @see #asEnumerable(Iterable)
*/
public static Enumerable cast(
Iterable source, Class clazz) {
return asEnumerable(source).cast(clazz);
}
/**
* Returns elements of a given {@link Iterable} that are of the specified
* type.
*
* This method is implemented by using deferred execution. The immediate
* return value is an object that stores all the information that is
* required to perform the action. The query represented by this method is
* not executed until the object is enumerated either by calling its
* {@link Enumerable#enumerator} method directly or by using
* {@code for (... in ...)}.
*
*
The {@code ofType} method returns only those elements in source that
* can be cast to type TResult. To instead receive an exception if an
* element cannot be cast to type TResult, use
* {@link #cast(Iterable, Class)}.
*
* Since standard Java {@link Collection} objects implement the
* {@link Iterable} interface, the {@code cast} method enables the standard
* query operators to be invoked on collections
* (including {@link java.util.List} and {@link java.util.Set}) by supplying
* the necessary type information. For example, {@link ArrayList} does not
* implement {@link Enumerable}<F>, but you can invoke
*
*
Linq4j.ofType(list, Integer.class)
*
* to convert the list of an enumerable that can be queried using the
* standard query operators.
*
* @see Enumerable#cast(Class)
* @see #cast
*/
public static Enumerable ofType(
Iterable source, Class clazz) {
return asEnumerable(source).ofType(clazz);
}
/**
* Returns an {@link Enumerable} that has one element.
*
* @param Element type
*
* @return Singleton enumerable
*/
public static Enumerable singletonEnumerable(final T element) {
return new AbstractEnumerable() {
public Enumerator enumerator() {
return singletonEnumerator(element);
}
};
}
/**
* Returns an {@link Enumerator} that has one element.
*
* @param Element type
*
* @return Singleton enumerator
*/
public static Enumerator singletonEnumerator(T element) {
return new SingletonEnumerator<>(element);
}
/**
* Returns an {@link Enumerator} that has one null element.
*
* @param Element type
*
* @return Singleton enumerator
*/
public static Enumerator singletonNullEnumerator() {
return new SingletonNullEnumerator<>();
}
/**
* Returns an {@link Enumerable} that has no elements.
*
* @param Element type
*
* @return Empty enumerable
*/
public static Enumerable emptyEnumerable() {
//noinspection unchecked
return (Enumerable) EMPTY_ENUMERABLE;
}
/**
* Returns an {@link Enumerator} that has no elements.
*
* @param Element type
*
* @return Empty enumerator
*/
public static Enumerator emptyEnumerator() {
//noinspection unchecked
return (Enumerator) EMPTY_ENUMERATOR;
}
/**
* Concatenates two or more {@link Enumerable}s to form a composite
* enumerable that contains the union of their elements.
*
* @param enumerableList List of enumerable objects
* @param Element type
*
* @return Composite enumerator
*/
public static Enumerable concat(
final List> enumerableList) {
return new CompositeEnumerable<>(enumerableList);
}
/**
* Returns an enumerator that is the cartesian product of the given
* enumerators.
*
* For example, given enumerator A that returns {"a", "b", "c"} and
* enumerator B that returns {"x", "y"}, product(List(A, B)) will return
* {List("a", "x"), List("a", "y"),
* List("b", "x"), List("b", "y"),
* List("c", "x"), List("c", "y")}.
*
* Notice that the cardinality of the result is the product of the
* cardinality of the inputs. The enumerators A and B have 3 and 2
* elements respectively, and the result has 3 * 2 = 6 elements.
* This is always the case. In
* particular, if any of the enumerators is empty, the result is empty.
*
* @param enumerators List of enumerators
* @param Element type
*
* @return Enumerator over the cartesian product
*/
public static Enumerator> product(
List> enumerators) {
return new CartesianProductListEnumerator<>(enumerators);
}
/** Returns the cartesian product of an iterable of iterables. */
public static Iterable> product(
final Iterable extends Iterable> iterables) {
return new Iterable>() {
public Iterator> iterator() {
final List> enumerators = Lists.newArrayList();
for (Iterable iterable : iterables) {
enumerators.add(iterableEnumerator(iterable));
}
return enumeratorIterator(
new CartesianProductListEnumerator<>(enumerators));
}
};
}
/**
* Returns whether the arguments are equal to each other.
*
* Equivalent to {@link java.util.Objects#equals} in JDK 1.7 and above.
*/
@Deprecated // to be removed before 2.0
public static boolean equals(T t0, T t1) {
return t0 == t1 || t0 != null && t0.equals(t1);
}
/**
* Throws {@link NullPointerException} if argument is null, otherwise
* returns argument.
*
* Equivalent to {@link java.util.Objects#requireNonNull} in JDK 1.7 and
* above.
*/
@Deprecated // to be removed before 2.0
public static T requireNonNull(T o) {
if (o == null) {
throw new NullPointerException();
}
return o;
}
/** Closes an iterator, if it can be closed. */
private static void closeIterator(Iterator iterator) {
if (iterator instanceof AutoCloseable) {
try {
((AutoCloseable) iterator).close();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/** Iterable enumerator. */
@SuppressWarnings("unchecked")
static class IterableEnumerator implements Enumerator {
private final Iterable extends T> iterable;
Iterator extends T> iterator;
T current;
IterableEnumerator(Iterable extends T> iterable) {
this.iterable = iterable;
iterator = iterable.iterator();
current = (T) DUMMY;
}
public T current() {
if (current == DUMMY) {
throw new NoSuchElementException();
}
return current;
}
public boolean moveNext() {
if (iterator.hasNext()) {
current = iterator.next();
return true;
}
current = (T) DUMMY;
return false;
}
public void reset() {
iterator = iterable.iterator();
current = (T) DUMMY;
}
public void close() {
final Iterator extends T> iterator1 = this.iterator;
this.iterator = null;
closeIterator(iterator1);
}
}
/** Composite enumerable. */
static class CompositeEnumerable extends AbstractEnumerable {
private final Enumerator> enumerableEnumerator;
CompositeEnumerable(List> enumerableList) {
enumerableEnumerator = iterableEnumerator(enumerableList);
}
public Enumerator enumerator() {
return new Enumerator() {
// Never null.
Enumerator current = emptyEnumerator();
public E current() {
return current.current();
}
public boolean moveNext() {
for (;;) {
if (current.moveNext()) {
return true;
}
current.close();
if (!enumerableEnumerator.moveNext()) {
current = emptyEnumerator();
return false;
}
current = enumerableEnumerator.current().enumerator();
}
}
public void reset() {
enumerableEnumerator.reset();
current = emptyEnumerator();
}
public void close() {
current.close();
current = emptyEnumerator();
}
};
}
}
/** Iterable enumerable. */
static class IterableEnumerable extends AbstractEnumerable2 {
protected final Iterable iterable;
IterableEnumerable(Iterable iterable) {
this.iterable = iterable;
}
public Iterator iterator() {
return iterable.iterator();
}
@Override public boolean any() {
return iterable.iterator().hasNext();
}
}
/** Collection enumerable. */
static class CollectionEnumerable extends IterableEnumerable {
CollectionEnumerable(Collection iterable) {
super(iterable);
}
protected Collection getCollection() {
return (Collection) iterable;
}
@Override public int count() {
return getCollection().size();
}
@Override public long longCount() {
return getCollection().size();
}
@Override public boolean contains(T element) {
return getCollection().contains(element);
}
@Override public boolean any() {
return !getCollection().isEmpty();
}
}
/** List enumerable. */
static class ListEnumerable extends CollectionEnumerable {
ListEnumerable(List list) {
super(list);
}
@Override public Enumerator enumerator() {
if (iterable instanceof RandomAccess) {
//noinspection unchecked
return new ListEnumerator<>((List) iterable);
}
return super.enumerator();
}
@Override public List toList() {
return (List) iterable;
}
@Override public Enumerable skip(int count) {
final List list = toList();
if (count >= list.size()) {
return Linq4j.emptyEnumerable();
}
return new ListEnumerable<>(list.subList(count, list.size()));
}
@Override public Enumerable take(int count) {
final List list = toList();
if (count >= list.size()) {
return this;
}
return new ListEnumerable<>(list.subList(0, count));
}
@Override public T elementAt(int index) {
return toList().get(index);
}
}
/** Enumerator that returns one element. */
private static class SingletonEnumerator implements Enumerator {
final E e;
int i = 0;
SingletonEnumerator(E e) {
this.e = e;
}
public E current() {
return e;
}
public boolean moveNext() {
return i++ == 0;
}
public void reset() {
i = 0;
}
public void close() {
}
}
/** Enumerator that returns one null element. */
private static class SingletonNullEnumerator implements Enumerator {
int i = 0;
public E current() {
return null;
}
public boolean moveNext() {
return i++ == 0;
}
public void reset() {
i = 0;
}
public void close() {
}
}
/** Iterator that reads from an underlying {@link Enumerator}. */
private static class EnumeratorIterator
implements Iterator, AutoCloseable {
private final Enumerator enumerator;
boolean hasNext;
EnumeratorIterator(Enumerator enumerator) {
this.enumerator = enumerator;
hasNext = enumerator.moveNext();
}
public boolean hasNext() {
return hasNext;
}
public T next() {
T t = enumerator.current();
hasNext = enumerator.moveNext();
return t;
}
public void remove() {
throw new UnsupportedOperationException();
}
public void close() {
enumerator.close();
}
}
/** Enumerator optimized for random-access list. */
private static class ListEnumerator implements Enumerator {
private final List extends V> list;
int i = -1;
ListEnumerator(List extends V> list) {
this.list = list;
}
public V current() {
return list.get(i);
}
public boolean moveNext() {
return ++i < list.size();
}
public void reset() {
i = -1;
}
public void close() {
}
}
/** Enumerates over the cartesian product of the given lists, returning
* a list for each row. */
private static class CartesianProductListEnumerator
extends CartesianProductEnumerator> {
CartesianProductListEnumerator(List> enumerators) {
super(enumerators);
}
public List current() {
return Arrays.asList(elements.clone());
}
}
}
// End Linq4j.java