001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.hadoop.mapreduce; 020 021 import java.io.DataInput; 022 import java.io.DataOutput; 023 import java.io.IOException; 024 import java.text.NumberFormat; 025 import java.util.EnumMap; 026 import java.util.HashMap; 027 import java.util.Map; 028 029 import org.apache.hadoop.classification.InterfaceAudience; 030 import org.apache.hadoop.classification.InterfaceStability; 031 import org.apache.hadoop.io.WritableUtils; 032 033 034 /** 035 * TaskID represents the immutable and unique identifier for 036 * a Map or Reduce Task. Each TaskID encompasses multiple attempts made to 037 * execute the Map or Reduce Task, each of which are uniquely indentified by 038 * their TaskAttemptID. 039 * 040 * TaskID consists of 3 parts. First part is the {@link JobID}, that this 041 * TaskInProgress belongs to. Second part of the TaskID is either 'm' or 'r' 042 * representing whether the task is a map task or a reduce task. 043 * And the third part is the task number. <br> 044 * An example TaskID is : 045 * <code>task_200707121733_0003_m_000005</code> , which represents the 046 * fifth map task in the third job running at the jobtracker 047 * started at <code>200707121733</code>. 048 * <p> 049 * Applications should never construct or parse TaskID strings 050 * , but rather use appropriate constructors or {@link #forName(String)} 051 * method. 052 * 053 * @see JobID 054 * @see TaskAttemptID 055 */ 056 @InterfaceAudience.Public 057 @InterfaceStability.Stable 058 public class TaskID extends org.apache.hadoop.mapred.ID { 059 protected static final String TASK = "task"; 060 protected static final NumberFormat idFormat = NumberFormat.getInstance(); 061 static { 062 idFormat.setGroupingUsed(false); 063 idFormat.setMinimumIntegerDigits(6); 064 } 065 066 private JobID jobId; 067 private TaskType type; 068 069 /** 070 * Constructs a TaskID object from given {@link JobID}. 071 * @param jobId JobID that this tip belongs to 072 * @param type the {@link TaskType} of the task 073 * @param id the tip number 074 */ 075 public TaskID(JobID jobId, TaskType type, int id) { 076 super(id); 077 if(jobId == null) { 078 throw new IllegalArgumentException("jobId cannot be null"); 079 } 080 this.jobId = jobId; 081 this.type = type; 082 } 083 084 /** 085 * Constructs a TaskInProgressId object from given parts. 086 * @param jtIdentifier jobTracker identifier 087 * @param jobId job number 088 * @param type the TaskType 089 * @param id the tip number 090 */ 091 public TaskID(String jtIdentifier, int jobId, TaskType type, int id) { 092 this(new JobID(jtIdentifier, jobId), type, id); 093 } 094 095 public TaskID() { 096 jobId = new JobID(); 097 } 098 099 /** Returns the {@link JobID} object that this tip belongs to */ 100 public JobID getJobID() { 101 return jobId; 102 } 103 104 /** 105 * Get the type of the task 106 */ 107 public TaskType getTaskType() { 108 return type; 109 } 110 111 @Override 112 public boolean equals(Object o) { 113 if (!super.equals(o)) 114 return false; 115 116 TaskID that = (TaskID)o; 117 return this.type == that.type && this.jobId.equals(that.jobId); 118 } 119 120 /**Compare TaskInProgressIds by first jobIds, then by tip numbers. Reduces are 121 * defined as greater then maps.*/ 122 @Override 123 public int compareTo(ID o) { 124 TaskID that = (TaskID)o; 125 int jobComp = this.jobId.compareTo(that.jobId); 126 if(jobComp == 0) { 127 if(this.type == that.type) { 128 return this.id - that.id; 129 } 130 else { 131 return this.type.compareTo(that.type); 132 } 133 } 134 else return jobComp; 135 } 136 @Override 137 public String toString() { 138 return appendTo(new StringBuilder(TASK)).toString(); 139 } 140 141 /** 142 * Add the unique string to the given builder. 143 * @param builder the builder to append to 144 * @return the builder that was passed in 145 */ 146 protected StringBuilder appendTo(StringBuilder builder) { 147 return jobId.appendTo(builder). 148 append(SEPARATOR). 149 append(CharTaskTypeMaps.getRepresentingCharacter(type)). 150 append(SEPARATOR). 151 append(idFormat.format(id)); 152 } 153 154 @Override 155 public int hashCode() { 156 return jobId.hashCode() * 524287 + id; 157 } 158 159 @Override 160 public void readFields(DataInput in) throws IOException { 161 super.readFields(in); 162 jobId.readFields(in); 163 type = WritableUtils.readEnum(in, TaskType.class); 164 } 165 166 @Override 167 public void write(DataOutput out) throws IOException { 168 super.write(out); 169 jobId.write(out); 170 WritableUtils.writeEnum(out, type); 171 } 172 173 /** Construct a TaskID object from given string 174 * @return constructed TaskID object or null if the given String is null 175 * @throws IllegalArgumentException if the given string is malformed 176 */ 177 public static TaskID forName(String str) 178 throws IllegalArgumentException { 179 if(str == null) 180 return null; 181 try { 182 String[] parts = str.split("_"); 183 if(parts.length == 5) { 184 if(parts[0].equals(TASK)) { 185 String type = parts[3]; 186 TaskType t = CharTaskTypeMaps.getTaskType(type.charAt(0)); 187 if(t != null) { 188 189 return new org.apache.hadoop.mapred.TaskID(parts[1], 190 Integer.parseInt(parts[2]), 191 t, 192 Integer.parseInt(parts[4])); 193 } else throw new Exception(); 194 } 195 } 196 }catch (Exception ex) {//fall below 197 } 198 throw new IllegalArgumentException("TaskId string : " + str 199 + " is not properly formed"); 200 } 201 /** 202 * Gets the character representing the {@link TaskType} 203 * @param type the TaskType 204 * @return the character 205 */ 206 public static char getRepresentingCharacter(TaskType type) { 207 return CharTaskTypeMaps.getRepresentingCharacter(type); 208 } 209 /** 210 * Gets the {@link TaskType} corresponding to the character 211 * @param c the character 212 * @return the TaskType 213 */ 214 public static TaskType getTaskType(char c) { 215 return CharTaskTypeMaps.getTaskType(c); 216 } 217 218 public static String getAllTaskTypes() { 219 return CharTaskTypeMaps.allTaskTypes; 220 } 221 222 /** 223 * Maintains the mapping from the character representation of a task type to 224 * the enum class TaskType constants 225 */ 226 static class CharTaskTypeMaps { 227 private static EnumMap<TaskType, Character> typeToCharMap = 228 new EnumMap<TaskType,Character>(TaskType.class); 229 private static Map<Character, TaskType> charToTypeMap = 230 new HashMap<Character, TaskType>(); 231 static String allTaskTypes = "(m|r|s|c|t)"; 232 static { 233 setupTaskTypeToCharMapping(); 234 setupCharToTaskTypeMapping(); 235 } 236 237 private static void setupTaskTypeToCharMapping() { 238 typeToCharMap.put(TaskType.MAP, 'm'); 239 typeToCharMap.put(TaskType.REDUCE, 'r'); 240 typeToCharMap.put(TaskType.JOB_SETUP, 's'); 241 typeToCharMap.put(TaskType.JOB_CLEANUP, 'c'); 242 typeToCharMap.put(TaskType.TASK_CLEANUP, 't'); 243 } 244 245 private static void setupCharToTaskTypeMapping() { 246 charToTypeMap.put('m', TaskType.MAP); 247 charToTypeMap.put('r', TaskType.REDUCE); 248 charToTypeMap.put('s', TaskType.JOB_SETUP); 249 charToTypeMap.put('c', TaskType.JOB_CLEANUP); 250 charToTypeMap.put('t', TaskType.TASK_CLEANUP); 251 } 252 253 static char getRepresentingCharacter(TaskType type) { 254 return typeToCharMap.get(type); 255 } 256 static TaskType getTaskType(char c) { 257 return charToTypeMap.get(c); 258 } 259 } 260 261 }