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  }