1616 */
1717package org .apache .calcite .util .graph ;
1818
19+ import org .apache .calcite .plan .hep .HepMatchOrder ;
20+
1921import org .checkerframework .checker .initialization .qual .UnderInitialization ;
2022import org .checkerframework .checker .nullness .qual .RequiresNonNull ;
2123
@@ -38,10 +40,17 @@ public class TopologicalOrderIterator<V, E extends DefaultEdge>
3840 implements Iterator <V > {
3941 final Map <V , int []> countMap = new HashMap <>();
4042 final List <V > empties = new ArrayList <>();
43+ final HepMatchOrder hepMatchOrder ;
4144 private final DefaultDirectedGraph <V , E > graph ;
4245
4346 public TopologicalOrderIterator (DirectedGraph <V , E > graph ) {
47+ this (graph , HepMatchOrder .TOP_DOWN );
48+ }
49+
50+ public TopologicalOrderIterator (DirectedGraph <V , E > graph , HepMatchOrder hepMatchOrder ) {
51+ assert hepMatchOrder == HepMatchOrder .TOP_DOWN || hepMatchOrder == HepMatchOrder .BOTTOM_UP ;
4452 this .graph = (DefaultDirectedGraph <V , E >) graph ;
53+ this .hepMatchOrder = hepMatchOrder ;
4554 populate (countMap , empties );
4655 }
4756
@@ -50,21 +59,40 @@ public static <V, E extends DefaultEdge> Iterable<V> of(
5059 return () -> new TopologicalOrderIterator <>(graph );
5160 }
5261
62+ public static <V , E extends DefaultEdge > Iterable <V > of (
63+ final DirectedGraph <V , E > graph , HepMatchOrder hepMatchOrder ) {
64+ return () -> new TopologicalOrderIterator <>(graph , hepMatchOrder );
65+ }
66+
5367 @ RequiresNonNull ("graph" )
5468 private void populate (
5569 @ UnderInitialization TopologicalOrderIterator <V , E > this ,
5670 Map <V , int []> countMap , List <V > empties ) {
5771 for (V v : graph .vertexMap .keySet ()) {
5872 countMap .put (v , new int [] {0 });
5973 }
60- for (DefaultDirectedGraph .VertexInfo <V , E > info
61- : graph .vertexMap .values ()) {
62- for (E edge : info .outEdges ) {
63- //noinspection SuspiciousMethodCalls
64- final int [] ints =
65- requireNonNull (countMap .get (edge .target ),
66- () -> "no value for " + edge .target );
67- ++ints [0 ];
74+ if (hepMatchOrder == HepMatchOrder .TOP_DOWN ) {
75+ for (DefaultDirectedGraph .VertexInfo <V , E > info
76+ : graph .vertexMap .values ()) {
77+ for (E edge : info .outEdges ) {
78+ //noinspection SuspiciousMethodCalls
79+ final int [] ints =
80+ requireNonNull (countMap .get (edge .target ),
81+ () -> "no value for " + edge .target );
82+ ++ints [0 ];
83+ }
84+ }
85+ }
86+ if (hepMatchOrder == HepMatchOrder .BOTTOM_UP ) {
87+ for (DefaultDirectedGraph .VertexInfo <V , E > info
88+ : graph .vertexMap .values ()) {
89+ for (E edge : info .outEdges ) {
90+ //noinspection SuspiciousMethodCalls
91+ final int [] ints =
92+ requireNonNull (countMap .get (edge .source ),
93+ () -> "no value for " + edge .source );
94+ ++ints [0 ];
95+ }
6896 }
6997 }
7098 for (Map .Entry <V , int []> entry : countMap .entrySet ()) {
@@ -84,15 +112,30 @@ private void populate(
84112 DefaultDirectedGraph .VertexInfo <V , E > vertexInfo =
85113 requireNonNull (graph .vertexMap .get (v ),
86114 () -> "no vertex " + v );
87- for (E o : vertexInfo .outEdges ) {
88- //noinspection unchecked
89- final V target = (V ) o .target ;
90- int [] ints =
91- requireNonNull (countMap .get (target ),
92- () -> "no counts found for target " + target );
93- if (--ints [0 ] == 0 ) {
94- countMap .remove (target );
95- empties .add (target );
115+ if (hepMatchOrder == HepMatchOrder .TOP_DOWN ) {
116+ for (E o : vertexInfo .outEdges ) {
117+ //noinspection unchecked
118+ final V target = (V ) o .target ;
119+ int [] ints =
120+ requireNonNull (countMap .get (target ),
121+ () -> "no counts found for target " + target );
122+ if (--ints [0 ] == 0 ) {
123+ countMap .remove (target );
124+ empties .add (target );
125+ }
126+ }
127+ }
128+ if (hepMatchOrder == HepMatchOrder .BOTTOM_UP ) {
129+ for (E o : vertexInfo .inEdges ) {
130+ //noinspection unchecked
131+ final V source = (V ) o .source ;
132+ int [] ints =
133+ requireNonNull (countMap .get (source ),
134+ () -> "no counts found for source " + source );
135+ if (--ints [0 ] == 0 ) {
136+ countMap .remove (source );
137+ empties .add (source );
138+ }
96139 }
97140 }
98141 return v ;
0 commit comments