Package com.asakusafw.compiler.flow.visualizer

Source Code of com.asakusafw.compiler.flow.visualizer.VisualAnalyzer

/**
* Copyright 2011-2014 Asakusa Framework Team.
*
* Licensed 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 com.asakusafw.compiler.flow.visualizer;

import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.asakusafw.compiler.common.Naming;
import com.asakusafw.compiler.common.Precondition;
import com.asakusafw.compiler.flow.plan.FlowBlock;
import com.asakusafw.compiler.flow.plan.FlowGraphUtil;
import com.asakusafw.compiler.flow.plan.StageBlock;
import com.asakusafw.compiler.flow.plan.StageGraph;
import com.asakusafw.utils.collections.Sets;
import com.asakusafw.vocabulary.flow.graph.FlowElement;
import com.asakusafw.vocabulary.flow.graph.FlowElementKind;
import com.asakusafw.vocabulary.flow.graph.FlowGraph;
import com.asakusafw.vocabulary.flow.graph.FlowPartDescription;

/**
* 各種要素を可視化のためのモデルに変換する。
* @since 0.1.0
* @version 0.4.0
*/
public final class VisualAnalyzer {

    static final Logger LOG = LoggerFactory.getLogger(VisualAnalyzer.class);

    private final Set<FlowElement> sawElements = Sets.create();

    private VisualAnalyzer() {
        return;
    }

    /**
     * 演算子グラフを可視化モデルに変換する。
     * @param graph 対象のグラフ
     * @return 変換後のモデル
     * @throws IllegalArgumentException 引数に{@code null}が指定された場合
     */
    public static VisualGraph convertFlowGraph(FlowGraph graph) {
        Precondition.checkMustNotBeNull(graph, "graph"); //$NON-NLS-1$
        LOG.debug("{}の構造を可視化用に分析しています", graph);
        VisualAnalyzer analyzer = new VisualAnalyzer();
        Set<VisualNode> nodes = Sets.create();
        for (FlowElement element : FlowGraphUtil.collectElements(graph)) {
            VisualNode node = analyzer.convertElement(element);
            if (node != null) {
                nodes.add(node);
            }
        }
        return new VisualGraph(null, nodes);
    }

    /**
     * ステージグラフを可視化モデルに変換する。
     * @param graph 対象のグラフ
     * @return 変換後のモデル
     * @throws IllegalArgumentException 引数に{@code null}が指定された場合
     */
    public static VisualGraph convertStageGraph(StageGraph graph) {
        Precondition.checkMustNotBeNull(graph, "graph"); //$NON-NLS-1$
        LOG.debug("{}の構造を可視化用に分析しています", graph);
        VisualAnalyzer analyzer = new VisualAnalyzer();
        Set<VisualNode> nodes = Sets.create();
        nodes.add(analyzer.convertBlock("(source)", graph.getInput()));
        for (StageBlock stage : graph.getStages()) {
            nodes.add(analyzer.convertStage(stage));
        }
        nodes.add(analyzer.convertBlock("(sink)", graph.getOutput()));
        return new VisualGraph(null, nodes);
    }

    /**
     * ステージグラフを可視化モデルに変換する。
     * @param stage 対象のブロック
     * @return 変換後のモデル
     * @throws IllegalArgumentException 引数に{@code null}が指定された場合
     */
    public static VisualGraph convertStageBlock(StageBlock stage) {
        Precondition.checkMustNotBeNull(stage, "stage"); //$NON-NLS-1$
        LOG.debug("{}の構造を可視化用に分析しています", stage);
        VisualAnalyzer analyzer = new VisualAnalyzer();
        Set<VisualNode> nodes = Sets.create();
        for (FlowBlock head : stage.getMapBlocks()) {
            for (FlowBlock.Input input : head.getBlockInputs()) {
                for (FlowBlock.Connection conn : input.getConnections()) {
                    FlowElement element = conn.getUpstream().getElementPort().getOwner();
                    VisualNode node = analyzer.convertElement(element);
                    if (node != null) {
                        nodes.add(node);
                    }
                }
            }
        }
        nodes.add(analyzer.convertStage(stage));
        Set<FlowBlock> tails = stage.hasReduceBlocks() ? stage.getReduceBlocks() : stage.getMapBlocks();
        for (FlowBlock tail : tails) {
            for (FlowBlock.Output output : tail.getBlockOutputs()) {
                for (FlowBlock.Connection conn : output.getConnections()) {
                    FlowElement element = conn.getDownstream().getElementPort().getOwner();
                    VisualNode node = analyzer.convertElement(element);
                    if (node != null) {
                        nodes.add(node);
                    }
                }
            }
        }
        return new VisualGraph(null, nodes);
    }

    /**
     * Converts {@link FlowBlock} into {@link VisualGraph}.
     * @param block target block
     * @return converted graph
     * @throws IllegalArgumentException if some parameters were {@code null}
     * @since 0.4.0
     */
    public static VisualGraph convertFlowBlock(FlowBlock block) {
        Precondition.checkMustNotBeNull(block, "block"); //$NON-NLS-1$
        LOG.debug("Visualizing a flow block: {}", block);
        VisualAnalyzer analyzer = new VisualAnalyzer();
        Set<VisualNode> nodes = Sets.create();
        nodes.add(analyzer.convertBlock("block", block));
        return new VisualGraph(null, nodes);
    }

    private VisualGraph convertStage(StageBlock stage) {
        assert stage != null;
        Set<VisualBlock> nodes = Sets.create();
        for (FlowBlock block : stage.getMapBlocks()) {
            // "cluster"'s bug of dot
            nodes.add(convertBlock(null, block));
        }
        for (FlowBlock block : stage.getReduceBlocks()) {
            nodes.add(convertBlock(null, block));
        }
        return new VisualGraph(
                Naming.getStageName(stage.getStageNumber()),
                nodes);
    }

    private VisualBlock convertBlock(String label, FlowBlock block) {
        assert block != null;
        Set<VisualNode> nodes = Sets.create();
        for (FlowElement element : block.getElements()) {
            VisualNode node = convertElement(element);
            if (node != null) {
                nodes.add(node);
            }
        }
        return new VisualBlock(
                label,
                Sets.from(block.getBlockInputs()),
                Sets.from(block.getBlockOutputs()),
                nodes);
    }

    private VisualNode convertElement(FlowElement element) {
        assert element != null;
        if (sawElements.contains(element)) {
            LOG.debug("Ignored already presented element: {}", element);
            return null;
        }
        sawElements.add(element);
        if (element.getDescription().getKind() == FlowElementKind.FLOW_COMPONENT) {
            FlowPartDescription desc = (FlowPartDescription) element.getDescription();
            Set<VisualNode> nodes = Sets.create();
            for (FlowElement inner : FlowGraphUtil.collectElements(desc.getFlowGraph())) {
                VisualNode node = convertElement(inner);
                if (node != null) {
                    nodes.add(node);
                }
            }
            return new VisualFlowPart(element, nodes);
        }
        return new VisualElement(element);
    }
}
TOP

Related Classes of com.asakusafw.compiler.flow.visualizer.VisualAnalyzer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.