package com.mathieubolla.guava;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
public abstract class FluentParallelIterable<E> implements Iterable<E> {
private final FluentIterable<E> delegate;
private final int threads;
private final ExecutorService executorService;
private boolean parallel = true;
private FluentParallelIterable(Iterable<E> delegate, int threads,
ExecutorService executorService) {
this.delegate = FluentIterable.from(delegate);
this.threads = threads;
this.executorService = executorService;
}
public static <E> FluentParallelIterable<E> from(final Iterable<E> source) {
int threads = Runtime.getRuntime().availableProcessors();
return from(source, threads, Executors.newFixedThreadPool(threads));
}
public static <E> FluentParallelIterable<E> from(final Iterable<E> source,
int threads, ExecutorService executorService) {
return source instanceof FluentParallelIterable ? (FluentParallelIterable<E>) source
: new FluentParallelIterable<E>(source, threads,
executorService) {
public Iterator<E> iterator() {
return source.iterator();
}
};
}
public final boolean allMatch(Predicate<? super E> predicate) {
// TODO do check this.parallel
return this.delegate.allMatch(predicate);
}
public final boolean anyMatch(Predicate<? super E> predicate) {
// TODO do check this.parallel
return this.delegate.anyMatch(predicate);
}
public final boolean contains(Object element) {
return this.delegate.contains(element);
}
public final <C extends Collection<? super E>> C copyInto(C arg0) {
return this.delegate.copyInto(arg0);
}
public final FluentParallelIterable<E> cycle() {
return from(this.delegate.cycle(), this.threads, this.executorService);
}
public final <T> FluentParallelIterable<T> filter(Class<T> type) {
return from(this.delegate.filter(type), this.threads,
this.executorService);
}
public final Optional<E> first() {
return this.delegate.first();
}
public final Optional<E> firstMatch(Predicate<? super E> predicate) {
// TODO do check this.parallel
return this.delegate.firstMatch(predicate);
}
public final E get(int position) {
return this.delegate.get(position);
}
public final <K> ImmutableListMultimap<K, E> index(
Function<? super E, K> keyFunction) {
return this.delegate.index(keyFunction);
}
public final boolean isEmpty() {
return this.delegate.isEmpty();
}
public Iterator<E> iterator() {
return this.delegate.iterator();
}
public final Optional<E> last() {
return this.delegate.last();
}
public final FluentParallelIterable<E> limit(int size) {
return from(this.delegate.limit(size), this.threads,
this.executorService);
}
public final int size() {
return this.delegate.size();
}
public final FluentParallelIterable<E> skip(int numberToSkip) {
return from(this.delegate.skip(numberToSkip), this.threads,
this.executorService);
}
public final E[] toArray(Class<E> type) {
return this.delegate.toArray(type);
}
public final ImmutableList<E> toList() {
return this.delegate.toList();
}
public final <V> ImmutableMap<E, V> toMap(
Function<? super E, V> valueFunction) {
return this.delegate.toMap(valueFunction);
}
public final ImmutableSet<E> toSet() {
return this.delegate.toSet();
}
public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) {
return this.delegate.toSortedList(comparator);
}
public final ImmutableSortedSet<E> toSortedSet(
Comparator<? super E> comparator) {
return this.delegate.toSortedSet(comparator);
}
public <T> FluentParallelIterable<T> transformAndConcat(
Function<? super E, ? extends Iterable<T>> function) {
return from(this.delegate.transformAndConcat(function), this.threads,
this.executorService);
}
public final <K> ImmutableMap<K, E> uniqueIndex(
Function<? super E, K> keyFunction) {
return this.delegate.uniqueIndex(keyFunction);
}
// -----------------------------------------------------------------------------------
public FluentParallelIterable<E> parallel() {
this.parallel = true;
return this;
}
public FluentParallelIterable<E> reduce() {
this.parallel = false;
return this;
}
public final <T> FluentParallelIterable<T> transform(
Function<? super E, T> function) {
Iterable<T> source = this.parallel ? ParallelUtils.parallelTransform(
this.delegate, function, this.threads, this.executorService)
: this.delegate.transform(function);
return from(source, this.threads, this.executorService);
}
public final FluentParallelIterable<E> filter(Predicate<? super E> predicate) {
Iterable<E> source = this.parallel ? ParallelUtils.parallelFilter(
this.delegate, predicate, this.threads, this.executorService)
: this.delegate.filter(predicate);
return from(source, this.threads, this.executorService);
}
}