io.github.sinri.keel.facade.async.FutureForEachParallel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Keel Show documentation
Show all versions of Keel Show documentation
A website framework with VERT.X for ex-PHP-ers, exactly Ark Framework Users.
The newest version!
package io.github.sinri.keel.facade.async;
import io.vertx.core.Future;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
/**
* @since 2.9.4
* @since 3.0.8 Replace `CompositeFuture.XXX` with `Future.XXX`.
*/
public class FutureForEachParallel {
private FutureForEachParallel() {
}
private static List> buildFutureList(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
List> futures = new ArrayList<>();
collection.forEach(item -> {
Future future = Future.succeededFuture().compose(v -> itemProcessor.apply(item));
futures.add(future);
});
return futures;
}
public static Future all(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
List> futures = buildFutureList(collection, itemProcessor);
if (futures.isEmpty()) return Future.succeededFuture();
return Future.all(futures)
.compose(compositeFuture -> Future.succeededFuture());
}
public static Future any(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
List> futures = buildFutureList(collection, itemProcessor);
if (futures.isEmpty()) return Future.succeededFuture();
return Future.any(futures)
.compose(compositeFuture -> Future.succeededFuture());
}
public static Future join(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
List> futures = buildFutureList(collection, itemProcessor);
if (futures.isEmpty()) return Future.succeededFuture();
return Future.join(futures)
.compose(compositeFuture -> Future.succeededFuture());
}
public static Future> call(@Nonnull Iterable collection, @Nonnull Function> itemProcessor) {
// transform iterable to a temp map
AtomicInteger counter = new AtomicInteger(0);
Map map = new HashMap<>();
collection.forEach(item -> {
map.put(counter.get(), item);
counter.getAndIncrement();
});
// init a ParallelResult
ParallelResult parallelResult = new ParallelResult<>();
// each future
List> futures = new ArrayList<>();
map.forEach((i, e) -> {
Future f = Future.succeededFuture()
.compose(v -> itemProcessor.apply(e))
.compose(r -> {
ParallelResultPart rParallelResultPart = new ParallelResultPart<>(r);
parallelResult.addResultPart(i, rParallelResultPart);
return Future.succeededFuture();
}, throwable -> {
ParallelResultPart rParallelResultPart = new ParallelResultPart<>(throwable);
parallelResult.addResultPart(i, rParallelResultPart);
return Future.succeededFuture();
});
futures.add(f);
});
if (futures.isEmpty()) return Future.succeededFuture(parallelResult);
// result
return Future.all(futures)
.compose(c -> Future.succeededFuture(parallelResult));
}
/**
* @param The result type.
* @since 3.0.8 Use a certain type R.
*/
public static class ParallelResult {
private final Map> map;
/**
* @since 3.0.8 map changed to ConcurrentHashMap from HashMap
*/
public ParallelResult() {
this.map = new ConcurrentHashMap<>();
}
public int size() {
return this.map.size();
}
public ParallelResult addResultPart(int i, ParallelResultPart parallelResultPart) {
this.map.put(i, parallelResultPart);
return this;
}
public ParallelResultPart resultAt(int i) {
return this.map.get(i);
}
@Deprecated(since = "3.0.8", forRemoval = true)
public List> results() {
return getResultPartList();
}
/**
* @since 3.0.8
*/
public List> getResultPartList() {
List> results = new ArrayList<>();
for (int i = 0; i < this.size(); i++) {
results.add(resultAt(i));
}
return results;
}
/**
* @param fallback Used as result in list when the part failed.
* @since 3.0.8
*/
public List getResultList(R fallback) {
List list = new ArrayList<>();
getResultPartList().forEach(rp -> list.add(rp.isFailed() ? fallback : rp.getResult()));
return list;
}
/**
* @since 3.0.8
*/
public List getResultList() {
return getResultList(null);
}
/**
* @since 3.0.8
*/
public boolean isAllSuccessful() {
for (var v : this.map.values()) {
if (v.isFailed()) {
return false;
}
}
return true;
}
}
public static class ParallelResultPart {
private final boolean failed;
private final Throwable cause;
private final R result;
public ParallelResultPart(Throwable cause) {
this.failed = true;
this.cause = cause;
this.result = null;
}
public ParallelResultPart(R result) {
this.failed = false;
this.cause = null;
this.result = result;
}
public R getResult() {
return result;
}
public Throwable getCause() {
return cause;
}
public boolean isFailed() {
return failed;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy