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