PageRenderTime 50ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/release-0.0.0-rc0/hive/external/ql/src/java/org/apache/hadoop/hive/ql/lib/TaskGraphWalker.java

#
Java | 204 lines | 120 code | 23 blank | 61 comment | 25 complexity | 82eea22664343523cedf347f1c91eb72 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, JSON, CPL-1.0
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.hive.ql.lib;
  19. import java.io.Serializable;
  20. import java.util.ArrayList;
  21. import java.util.Collection;
  22. import java.util.HashMap;
  23. import java.util.HashSet;
  24. import java.util.List;
  25. import java.util.Set;
  26. import java.util.Stack;
  27. import org.apache.hadoop.hive.ql.exec.ConditionalTask;
  28. import org.apache.hadoop.hive.ql.exec.Task;
  29. import org.apache.hadoop.hive.ql.parse.SemanticException;
  30. /**
  31. * base class for operator graph walker this class takes list of starting ops
  32. * and walks them one by one. it maintains list of walked operators
  33. * (dispatchedList) and a list of operators that are discovered but not yet
  34. * dispatched
  35. */
  36. public class TaskGraphWalker implements GraphWalker {
  37. public class TaskGraphWalkerContext{
  38. private final HashMap<Node, Object> reMap;
  39. public TaskGraphWalkerContext(HashMap<Node, Object> reMap){
  40. this.reMap = reMap;
  41. }
  42. public void addToDispatchList(Node dispatchedObj){
  43. if(dispatchedObj != null) {
  44. retMap.put(dispatchedObj, null);
  45. }
  46. }
  47. }
  48. protected Stack<Node> opStack;
  49. private final List<Node> toWalk = new ArrayList<Node>();
  50. private final HashMap<Node, Object> retMap = new HashMap<Node, Object>();
  51. private final Dispatcher dispatcher;
  52. private final TaskGraphWalkerContext walkerCtx;
  53. /**
  54. * Constructor.
  55. *
  56. * @param disp
  57. * dispatcher to call for each op encountered
  58. */
  59. public TaskGraphWalker(Dispatcher disp) {
  60. dispatcher = disp;
  61. opStack = new Stack<Node>();
  62. walkerCtx = new TaskGraphWalkerContext(retMap);
  63. }
  64. /**
  65. * @return the toWalk
  66. */
  67. public List<Node> getToWalk() {
  68. return toWalk;
  69. }
  70. /**
  71. * @return the doneList
  72. */
  73. public Set<Node> getDispatchedList() {
  74. return retMap.keySet();
  75. }
  76. /**
  77. * Dispatch the current operator.
  78. *
  79. * @param nd
  80. * node being walked
  81. * @param ndStack
  82. * stack of nodes encountered
  83. * @throws SemanticException
  84. */
  85. public void dispatch(Node nd, Stack<Node> ndStack,TaskGraphWalkerContext walkerCtx) throws SemanticException {
  86. Object[] nodeOutputs = null;
  87. if (nd.getChildren() != null) {
  88. nodeOutputs = new Object[nd.getChildren().size()+1];
  89. nodeOutputs[0] = walkerCtx;
  90. int i = 1;
  91. for (Node child : nd.getChildren()) {
  92. nodeOutputs[i++] = retMap.get(child);
  93. }
  94. }else{
  95. nodeOutputs = new Object[1];
  96. nodeOutputs[0] = walkerCtx;
  97. }
  98. Object retVal = dispatcher.dispatch(nd, ndStack, nodeOutputs);
  99. retMap.put(nd, retVal);
  100. }
  101. public void dispatch(Node nd, Stack<Node> ndStack) throws SemanticException {
  102. Object[] nodeOutputs = null;
  103. if (nd.getChildren() != null) {
  104. nodeOutputs = new Object[nd.getChildren().size()];
  105. int i = 1;
  106. for (Node child : nd.getChildren()) {
  107. nodeOutputs[i++] = retMap.get(child);
  108. }
  109. }
  110. Object retVal = dispatcher.dispatch(nd, ndStack, nodeOutputs);
  111. retMap.put(nd, retVal);
  112. }
  113. /**
  114. * starting point for walking.
  115. *
  116. * @throws SemanticException
  117. */
  118. public void startWalking(Collection<Node> startNodes,
  119. HashMap<Node, Object> nodeOutput) throws SemanticException {
  120. toWalk.addAll(startNodes);
  121. while (toWalk.size() > 0) {
  122. Node nd = toWalk.remove(0);
  123. walk(nd);
  124. if (nodeOutput != null) {
  125. nodeOutput.put(nd, retMap.get(nd));
  126. }
  127. }
  128. }
  129. /**
  130. * walk the current operator and its descendants.
  131. *
  132. * @param nd
  133. * current operator in the graph
  134. * @throws SemanticException
  135. */
  136. public void walk(Node nd) throws SemanticException {
  137. if(!(nd instanceof Task)){
  138. throw new SemanticException("Task Graph Walker only walks for Task Graph");
  139. }
  140. if (getDispatchedList().contains(nd)) {
  141. return;
  142. }
  143. if (opStack.empty() || nd != opStack.peek()) {
  144. opStack.push(nd);
  145. }
  146. List<Task<? extends Serializable>> nextTaskList = null;
  147. Set<Task<? extends Serializable>> nextTaskSet = new HashSet<Task<? extends Serializable>>();
  148. List<Task<? extends Serializable>> taskListInConditionalTask = null;
  149. if(nd instanceof ConditionalTask ){
  150. //for conditional task, next task list should return the children tasks of each task, which
  151. //is contained in the conditional task.
  152. taskListInConditionalTask = ((ConditionalTask) nd).getListTasks();
  153. for(Task<? extends Serializable> tsk: taskListInConditionalTask){
  154. List<Task<? extends Serializable>> childTask = tsk.getChildTasks();
  155. if(childTask != null){
  156. nextTaskSet.addAll(tsk.getChildTasks());
  157. }
  158. }
  159. //convert the set into list
  160. if(nextTaskSet.size()>0){
  161. nextTaskList = new ArrayList<Task<? extends Serializable>>();
  162. for(Task<? extends Serializable> tsk:nextTaskSet ){
  163. nextTaskList.add(tsk);
  164. }
  165. }
  166. }else{
  167. //for other tasks, just return its children tasks
  168. nextTaskList = ((Task<? extends Serializable>)nd).getChildTasks();
  169. }
  170. if ((nextTaskList == null)
  171. || getDispatchedList().containsAll(nextTaskList)) {
  172. dispatch(nd, opStack,this.walkerCtx);
  173. opStack.pop();
  174. return;
  175. }
  176. // add children, self to the front of the queue in that order
  177. getToWalk().add(0, nd);
  178. getToWalk().removeAll(nextTaskList);
  179. getToWalk().addAll(0, nextTaskList);
  180. }
  181. }