    001/*
    002 * Copyright (c) 2016 Chris K Wensel <chris@wensel.net>. All Rights Reserved.
    003 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved.
    004 *
    005 * Project and contact information: http://www.cascading.org/
    006 *
    007 * This file is part of the Cascading project.
    008 *
    009 * Licensed under the Apache License, Version 2.0 (the "License");
    010 * you may not use this file except in compliance with the License.
    011 * You may obtain a copy of the License at
    012 *
    013 *     http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing, software
    016 * distributed under the License is distributed on an "AS IS" BASIS,
    017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    018 * See the License for the specific language governing permissions and
    019 * limitations under the License.
    020 */
    021
    022package cascading.flow.planner.iso.subgraph;
    023
    024import java.io.File;
    025import java.util.ArrayList;
    026import java.util.Collections;
    027import java.util.List;
    028import java.util.Map;
    029
    030import cascading.flow.planner.graph.ElementGraph;
    031import cascading.flow.planner.graph.ElementMultiGraph;
    032import cascading.flow.planner.iso.GraphResult;
    033import cascading.flow.planner.iso.expression.ExpressionGraph;
    034import cascading.flow.planner.iso.finder.Match;
    035import cascading.flow.planner.iso.subgraph.partitioner.ExpressionGraphPartitioner;
    036import cascading.flow.planner.rule.RulePartitioner;
    037import cascading.util.EnumMultiMap;
    038
    039/**
    040 *
    041 */
    042public class Partitions extends GraphResult
    043  {
    044  private RulePartitioner rulePartitioner;
    045  private final GraphPartitioner graphPartitioner;
    046  private final ElementGraph beginGraph;
    047  private final Map<ElementGraph, EnumMultiMap> annotatedSubGraphs;
    048  private ElementGraph contractedGraph;
    049  private List<Match> contractedMatches = Collections.emptyList();
    050
    051  public Partitions( GraphPartitioner graphPartitioner, ElementGraph beginGraph, Map<ElementGraph, EnumMultiMap> annotatedSubGraphs )
    052    {
    053    this( graphPartitioner, beginGraph, null, null, annotatedSubGraphs );
    054    }
    055
    056  public Partitions( GraphPartitioner graphPartitioner, ElementGraph beginGraph, ElementGraph contractedGraph, List<Match> contractedMatches, Map<ElementGraph, EnumMultiMap> annotatedSubGraphs )
    057    {
    058    this.graphPartitioner = graphPartitioner;
    059    this.beginGraph = beginGraph;
    060
    061    if( contractedGraph != null )
    062      this.contractedGraph = contractedGraph;
    063
    064    if( contractedMatches != null )
    065      this.contractedMatches = contractedMatches;
    066
    067    this.annotatedSubGraphs = annotatedSubGraphs;
    068    }
    069
    070  public void setRulePartitioner( RulePartitioner rulePartitioner )
    071    {
    072    this.rulePartitioner = rulePartitioner;
    073    }
    074
    075  public String getRuleName()
    076    {
    077    if( rulePartitioner != null )
    078      return rulePartitioner.getRuleName();
    079
    080    return "none";
    081    }
    082
    083  @Override
    084  public ElementGraph getBeginGraph()
    085    {
    086    return beginGraph;
    087    }
    088
    089  @Override
    090  public ElementGraph getEndGraph()
    091    {
    092    return null;
    093    }
    094
    095  public Map<ElementGraph, EnumMultiMap> getAnnotatedSubGraphs()
    096    {
    097    return annotatedSubGraphs;
    098    }
    099
    100  public boolean hasSubGraphs()
    101    {
    102    return !annotatedSubGraphs.isEmpty();
    103    }
    104
    105  public boolean hasContractedMatches()
    106    {
    107    return !contractedMatches.isEmpty();
    108    }
    109
    110  public List<ElementGraph> getSubGraphs()
    111    {
    112    return new ArrayList<>( annotatedSubGraphs.keySet() );
    113    }
    114
    115  @Override
    116  public void writeDOTs( String path )
    117    {
    118    int count = 0;
    119    beginGraph.writeDOT( new File( path, makeFileName( count++, "element-graph" ) ).toString() );
    120
    121    if( graphPartitioner instanceof ExpressionGraphPartitioner )
    122      {
    123      ExpressionGraphPartitioner expressionGraphPartitioner = (ExpressionGraphPartitioner) graphPartitioner;
    124
    125      ExpressionGraph contractionGraph = expressionGraphPartitioner.getContractionGraph();
    126
    127      if( contractionGraph != null )
    128        contractionGraph.writeDOT( new File( path, makeFileName( count++, "contraction-graph", contractionGraph ) ).toString() );
    129
    130      ExpressionGraph expressionGraph = expressionGraphPartitioner.getExpressionGraph();
    131
    132      if( expressionGraph != null )
    133        expressionGraph.writeDOT( new File( path, makeFileName( count++, "expression-graph", expressionGraph ) ).toString() );
    134      }
    135
    136    if( contractedGraph != null )
    137      contractedGraph.writeDOT( new File( path, makeFileName( count++, "contracted-graph" ) ).toString() );
    138
    139    List<ElementGraph> subGraphs = getSubGraphs();
    140
    141    for( int i = 0; i < subGraphs.size(); i++ )
    142      {
    143      ElementGraph subGraph = subGraphs.get( i );
    144
    145      // want to write annotations with elements
    146      new ElementMultiGraph( subGraph, annotatedSubGraphs.get( subGraph ) ).writeDOT( new File( path, makeFileName( count, i, "partition-result-sub-graph" ) ).toString() );
    147
    148      if( i < contractedMatches.size() )
    149        contractedMatches.get( i ).getMatchedGraph().writeDOT( new File( path, makeFileName( count, i, "partition-contracted-graph" ) ).toString() );
    150      }
    151    }
    152
    153  private String makeFileName( int ordinal, String name )
    154    {
    155    return String.format( "%02d-%s.dot", ordinal, name );
    156    }
    157
    158  private String makeFileName( int ordinal, String name, Object type )
    159    {
    160    return String.format( "%02d-%s-%s.dot", ordinal, name, type.getClass().getSimpleName() );
    161    }
    162
    163  private String makeFileName( int order, int ordinal, String name )
    164    {
    165    return String.format( "%02d-%04d-%s.dot", order, ordinal, name );
    166    }
    167  }