001/*
002 * Copyright (c) 2007-2015 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  }