All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.lucaventuri.fibry.MapReducer Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
package eu.lucaventuri.fibry;

import eu.lucaventuri.common.Exitable;

import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;

/**
 * Map Reducer.
 */
public class MapReducer {
    private final Consumer mapperConsumer;
    private final Exitable exitableMapper;
    private final Actor reducer;

    public MapReducer(Actor mapper, Actor reducer) {
        this.mapperConsumer = mapper;
        this.exitableMapper = mapper;
        this.reducer = reducer;
    }

    public MapReducer(Spawner mapSpawner, Actor reducer) {
        this.mapperConsumer = input -> mapSpawner.spawn().sendMessage(input).sendPoisonPill();
        this.exitableMapper = mapSpawner;
        this.reducer = reducer;
    }


    /**
     * Used to send the data to the actors pool
     *
     * @param input data to process
     */
    public MapReducer map(I input) {
        mapperConsumer.accept(input);

        return this;
    }

    /**
     * Used to send the data to the actors pool
     *
     * @param input data to process
     */
    public MapReducer map(I... input) {
        for (int i = 0; i < input.length; i++)
            map(input[i]);

        return this;
    }


    /**
     * Used to send the data to the actors pool
     *
     * @param input data to process
     */
    public MapReducer  map(Iterable input) {
        for (I data : input)
            mapperConsumer.accept(data);

        return this;
    }


    /**
     * Signal that all the data has been sent. No more data should be sent to the actors, as the behavior is undefined.
     */
    public MapReducer  completed() {
        if (!exitableMapper.isExiting())
            exitableMapper.sendPoisonPill();

        return this;
    }

    /**
     * Returns the result. This is a blocking operation.
     *
     * @param forceComplete True to force complete. Normally you call complete() when ready
     * @return the result of the computation.
     */
    public O get(boolean forceComplete) {
        if (forceComplete)
            completed();

        exitableMapper.waitForExit();
        reducer.sendPoisonPill();
        reducer.waitForExit();

        return reducer.getState();
    }
}