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 019package org.apache.hadoop.mapreduce; 020 021import java.io.DataInput; 022import java.io.DataOutput; 023import java.io.IOException; 024import java.text.NumberFormat; 025import java.util.EnumMap; 026import java.util.HashMap; 027import java.util.Map; 028import java.util.regex.Matcher; 029import java.util.regex.Pattern; 030 031import org.apache.hadoop.classification.InterfaceAudience; 032import org.apache.hadoop.classification.InterfaceStability; 033import org.apache.hadoop.io.WritableUtils; 034 035 036/** 037 * TaskID represents the immutable and unique identifier for 038 * a Map or Reduce Task. Each TaskID encompasses multiple attempts made to 039 * execute the Map or Reduce Task, each of which are uniquely indentified by 040 * their TaskAttemptID. 041 * 042 * TaskID consists of 3 parts. First part is the {@link JobID}, that this 043 * TaskInProgress belongs to. Second part of the TaskID is either 'm' or 'r' 044 * representing whether the task is a map task or a reduce task. 045 * And the third part is the task number. <br> 046 * An example TaskID is : 047 * <code>task_200707121733_0003_m_000005</code> , which represents the 048 * fifth map task in the third job running at the jobtracker 049 * started at <code>200707121733</code>. 050 * <p> 051 * Applications should never construct or parse TaskID strings 052 * , but rather use appropriate constructors or {@link #forName(String)} 053 * method. 054 * 055 * @see JobID 056 * @see TaskAttemptID 057 */ 058@InterfaceAudience.Public 059@InterfaceStability.Stable 060public class TaskID extends org.apache.hadoop.mapred.ID { 061 protected static final String TASK = "task"; 062 protected static final NumberFormat idFormat = NumberFormat.getInstance(); 063 public static final String TASK_ID_REGEX = TASK + "_(\\d+)_(\\d+)_" + 064 CharTaskTypeMaps.allTaskTypes + "_(\\d+)"; 065 public static final Pattern taskIdPattern = Pattern.compile(TASK_ID_REGEX); 066 static { 067 idFormat.setGroupingUsed(false); 068 idFormat.setMinimumIntegerDigits(6); 069 } 070 071 private JobID jobId; 072 private TaskType type; 073 074 /** 075 * Constructs a TaskID object from given {@link JobID}. 076 * @param jobId JobID that this tip belongs to 077 * @param type the {@link TaskType} of the task 078 * @param id the tip number 079 */ 080 public TaskID(JobID jobId, TaskType type, int id) { 081 super(id); 082 if(jobId == null) { 083 throw new IllegalArgumentException("jobId cannot be null"); 084 } 085 this.jobId = jobId; 086 this.type = type; 087 } 088 089 /** 090 * Constructs a TaskInProgressId object from given parts. 091 * @param jtIdentifier jobTracker identifier 092 * @param jobId job number 093 * @param type the TaskType 094 * @param id the tip number 095 */ 096 public TaskID(String jtIdentifier, int jobId, TaskType type, int id) { 097 this(new JobID(jtIdentifier, jobId), type, id); 098 } 099 100 /** 101 * Constructs a TaskID object from given {@link JobID}. 102 * @param jobId JobID that this tip belongs to 103 * @param isMap whether the tip is a map 104 * @param id the tip number 105 */ 106 @Deprecated 107 public TaskID(JobID jobId, boolean isMap, int id) { 108 this(jobId, isMap ? TaskType.MAP : TaskType.REDUCE, id); 109 } 110 111 /** 112 * Constructs a TaskInProgressId object from given parts. 113 * @param jtIdentifier jobTracker identifier 114 * @param jobId job number 115 * @param isMap whether the tip is a map 116 * @param id the tip number 117 */ 118 @Deprecated 119 public TaskID(String jtIdentifier, int jobId, boolean isMap, int id) { 120 this(new JobID(jtIdentifier, jobId), isMap, id); 121 } 122 123 public TaskID() { 124 jobId = new JobID(); 125 } 126 127 /** Returns the {@link JobID} object that this tip belongs to */ 128 public JobID getJobID() { 129 return jobId; 130 } 131 132 /**Returns whether this TaskID is a map ID */ 133 @Deprecated 134 public boolean isMap() { 135 return type == TaskType.MAP; 136 } 137 138 /** 139 * Get the type of the task 140 */ 141 public TaskType getTaskType() { 142 return type; 143 } 144 145 @Override 146 public boolean equals(Object o) { 147 if (!super.equals(o)) 148 return false; 149 150 TaskID that = (TaskID)o; 151 return this.type == that.type && this.jobId.equals(that.jobId); 152 } 153 154 /**Compare TaskInProgressIds by first jobIds, then by tip numbers. Reduces are 155 * defined as greater then maps.*/ 156 @Override 157 public int compareTo(ID o) { 158 TaskID that = (TaskID)o; 159 int jobComp = this.jobId.compareTo(that.jobId); 160 if(jobComp == 0) { 161 if(this.type == that.type) { 162 return this.id - that.id; 163 } 164 else { 165 return this.type.compareTo(that.type); 166 } 167 } 168 else return jobComp; 169 } 170 @Override 171 public String toString() { 172 return appendTo(new StringBuilder(TASK)).toString(); 173 } 174 175 /** 176 * Add the unique string to the given builder. 177 * @param builder the builder to append to 178 * @return the builder that was passed in 179 */ 180 protected StringBuilder appendTo(StringBuilder builder) { 181 return jobId.appendTo(builder). 182 append(SEPARATOR). 183 append(CharTaskTypeMaps.getRepresentingCharacter(type)). 184 append(SEPARATOR). 185 append(idFormat.format(id)); 186 } 187 188 @Override 189 public int hashCode() { 190 return jobId.hashCode() * 524287 + id; 191 } 192 193 @Override 194 public void readFields(DataInput in) throws IOException { 195 super.readFields(in); 196 jobId.readFields(in); 197 type = WritableUtils.readEnum(in, TaskType.class); 198 } 199 200 @Override 201 public void write(DataOutput out) throws IOException { 202 super.write(out); 203 jobId.write(out); 204 WritableUtils.writeEnum(out, type); 205 } 206 207 /** Construct a TaskID object from given string 208 * @return constructed TaskID object or null if the given String is null 209 * @throws IllegalArgumentException if the given string is malformed 210 */ 211 public static TaskID forName(String str) 212 throws IllegalArgumentException { 213 if(str == null) 214 return null; 215 Matcher m = taskIdPattern.matcher(str); 216 if (m.matches()) { 217 return new org.apache.hadoop.mapred.TaskID(m.group(1), 218 Integer.parseInt(m.group(2)), 219 CharTaskTypeMaps.getTaskType(m.group(3).charAt(0)), 220 Integer.parseInt(m.group(4))); 221 } 222 String exceptionMsg = "TaskId string : " + str + " is not properly formed" + 223 "\nReason: " + m.toString(); 224 throw new IllegalArgumentException(exceptionMsg); 225 } 226 /** 227 * Gets the character representing the {@link TaskType} 228 * @param type the TaskType 229 * @return the character 230 */ 231 public static char getRepresentingCharacter(TaskType type) { 232 return CharTaskTypeMaps.getRepresentingCharacter(type); 233 } 234 /** 235 * Gets the {@link TaskType} corresponding to the character 236 * @param c the character 237 * @return the TaskType 238 */ 239 public static TaskType getTaskType(char c) { 240 return CharTaskTypeMaps.getTaskType(c); 241 } 242 243 public static String getAllTaskTypes() { 244 return CharTaskTypeMaps.allTaskTypes; 245 } 246 247 /** 248 * Maintains the mapping from the character representation of a task type to 249 * the enum class TaskType constants 250 */ 251 static class CharTaskTypeMaps { 252 private static EnumMap<TaskType, Character> typeToCharMap = 253 new EnumMap<TaskType,Character>(TaskType.class); 254 private static Map<Character, TaskType> charToTypeMap = 255 new HashMap<Character, TaskType>(); 256 static String allTaskTypes = "(m|r|s|c|t)"; 257 static { 258 setupTaskTypeToCharMapping(); 259 setupCharToTaskTypeMapping(); 260 } 261 262 private static void setupTaskTypeToCharMapping() { 263 typeToCharMap.put(TaskType.MAP, 'm'); 264 typeToCharMap.put(TaskType.REDUCE, 'r'); 265 typeToCharMap.put(TaskType.JOB_SETUP, 's'); 266 typeToCharMap.put(TaskType.JOB_CLEANUP, 'c'); 267 typeToCharMap.put(TaskType.TASK_CLEANUP, 't'); 268 } 269 270 private static void setupCharToTaskTypeMapping() { 271 charToTypeMap.put('m', TaskType.MAP); 272 charToTypeMap.put('r', TaskType.REDUCE); 273 charToTypeMap.put('s', TaskType.JOB_SETUP); 274 charToTypeMap.put('c', TaskType.JOB_CLEANUP); 275 charToTypeMap.put('t', TaskType.TASK_CLEANUP); 276 } 277 278 static char getRepresentingCharacter(TaskType type) { 279 return typeToCharMap.get(type); 280 } 281 static TaskType getTaskType(char c) { 282 return charToTypeMap.get(c); 283 } 284 } 285 286}