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

com.lumiomedical.flow.impl.parallel.ParallelCompiler Maven / Gradle / Ivy

package com.lumiomedical.flow.impl.parallel;

import com.lumiomedical.flow.compiler.CompilationException;
import com.lumiomedical.flow.compiler.FlowCompiler;
import com.lumiomedical.flow.impl.parallel.compiler.ParallelIndexes;
import com.lumiomedical.flow.impl.parallel.compiler.pass.RemoveNodesWithUpstreamPass;
import com.lumiomedical.flow.impl.parallel.runtime.executor.ExecutorServiceProvider;
import com.lumiomedical.flow.impl.parallel.runtime.executor.Executors;
import com.lumiomedical.flow.impl.pipeline.PipelineCompiler;
import com.lumiomedical.flow.impl.pipeline.compiler.pass.PipelineCompilerPass;
import com.lumiomedical.flow.impl.pipeline.compiler.pass.TopologicalSortPass;
import com.lumiomedical.flow.io.output.Recipient;
import com.lumiomedical.flow.node.Node;
import com.lumiomedical.flow.stream.StreamGenerator;
import com.lumiomedical.flow.stream.StreamNode;

import java.util.*;

/**
 * @author Pierre Lecerf ([email protected])
 * Created on 2020/03/03
 */
public class ParallelCompiler implements FlowCompiler
{
    private final ExecutorServiceProvider provider;
    private final boolean autoRefresh;
    private final List passes = List.of(
        new TopologicalSortPass(),
        new RemoveNodesWithUpstreamPass()
    );

    /**
     *
     */
    public ParallelCompiler()
    {
        this(Runtime.getRuntime().availableProcessors(), true);
    }

    /**
     *
     * @param threadCount
     * @param autoRefresh
     */
    public ParallelCompiler(int threadCount, boolean autoRefresh)
    {
        this(() -> Executors.newFixedThreadPool(threadCount), autoRefresh);
    }

    /**
     *
     * @param provider
     * @param autoRefresh
     */
    public ParallelCompiler(ExecutorServiceProvider provider, boolean autoRefresh)
    {
        this.provider = provider;
        this.autoRefresh = autoRefresh;
    }

    @Override
    public ParallelRuntime compile(Collection inputNodes) throws CompilationException
    {
        List compiledNodes = PipelineCompiler.compile(inputNodes, this.passes);
        ParallelIndexes indexes = this.computeIndexes(compiledNodes);

        return new ParallelRuntime(
            compiledNodes,
            this.provider,
            this.autoRefresh,
            indexes
        );
    }

    /* Index-related actions */

    private ParallelIndexes computeIndexes(List compiledNodes)
    {
        Map recipients = new HashMap<>();
        Map generatorIndex = new HashMap<>();
        Map> streamNodeIndex = new HashMap<>();

        this.indexStreamNodes(compiledNodes, generatorIndex, streamNodeIndex);

        return new ParallelIndexes(
            generatorIndex,
            streamNodeIndex
        );
    }

    /**
     *
     * @param nodes
     * @param generatorIndex
     * @param nodeIndex
     */
    private void indexStreamNodes(List nodes, Map generatorIndex, Map> nodeIndex)
    {
        for (Node node : nodes)
        {
            if (node instanceof StreamGenerator)
            {
                if (!nodeIndex.containsKey(node))
                    nodeIndex.put((StreamGenerator) node, new HashSet<>());
                indexStreamNodes(node.getDownstream(), (StreamGenerator) node, generatorIndex, nodeIndex);
            }
            else
                indexStreamNodes(node.getDownstream(), generatorIndex, nodeIndex);
        }
    }

    /**
     *
     * @param nodes
     * @param generator
     * @param generatorIndex
     * @param nodeIndex
     */
    private void indexStreamNodes(List nodes, StreamGenerator generator, Map generatorIndex, Map> nodeIndex)
    {
        for (Node node : nodes)
        {
            if (node instanceof StreamNode)
            {
                if (!generatorIndex.containsKey(node))
                {
                    generatorIndex.put(node, generator);
                    indexStreamNodes(node.getDownstream(), generator, generatorIndex, nodeIndex);
                }
                nodeIndex.get(generator).add(node);
            }
            else
                indexStreamNodes(node.getDownstream(), generatorIndex, nodeIndex);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy