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;
025
026import org.apache.hadoop.classification.InterfaceAudience;
027import org.apache.hadoop.classification.InterfaceStability;
028import org.apache.hadoop.io.Text;
029
030/**
031 * JobID represents the immutable and unique identifier for 
032 * the job. JobID consists of two parts. First part 
033 * represents the jobtracker identifier, so that jobID to jobtracker map 
034 * is defined. For cluster setup this string is the jobtracker 
035 * start time, for local setting, it is "local" and a random number.
036 * Second part of the JobID is the job number. <br> 
037 * An example JobID is : 
038 * <code>job_200707121733_0003</code> , which represents the third job 
039 * running at the jobtracker started at <code>200707121733</code>. 
040 * <p>
041 * Applications should never construct or parse JobID strings, but rather 
042 * use appropriate constructors or {@link #forName(String)} method. 
043 * 
044 * @see TaskID
045 * @see TaskAttemptID
046 */
047@InterfaceAudience.Public
048@InterfaceStability.Stable
049public class JobID extends org.apache.hadoop.mapred.ID 
050                   implements Comparable<ID> {
051  public static final String JOB = "job";
052  
053  // Jobid regex for various tools and framework components
054  public static final String JOBID_REGEX = 
055    JOB + SEPARATOR + "[0-9]+" + SEPARATOR + "[0-9]+";
056  
057  private final Text jtIdentifier;
058  
059  protected static final NumberFormat idFormat = NumberFormat.getInstance();
060  static {
061    idFormat.setGroupingUsed(false);
062    idFormat.setMinimumIntegerDigits(4);
063  }
064  
065  /**
066   * Constructs a JobID object 
067   * @param jtIdentifier jobTracker identifier
068   * @param id job number
069   */
070  public JobID(String jtIdentifier, int id) {
071    super(id);
072    this.jtIdentifier = new Text(jtIdentifier);
073  }
074  
075  public JobID() { 
076    jtIdentifier = new Text();
077  }
078  
079  public String getJtIdentifier() {
080    return jtIdentifier.toString();
081  }
082  
083  @Override
084  public boolean equals(Object o) {
085    if (!super.equals(o))
086      return false;
087
088    JobID that = (JobID)o;
089    return this.jtIdentifier.equals(that.jtIdentifier);
090  }
091  
092  /**Compare JobIds by first jtIdentifiers, then by job numbers*/
093  @Override
094  public int compareTo(ID o) {
095    JobID that = (JobID)o;
096    int jtComp = this.jtIdentifier.compareTo(that.jtIdentifier);
097    if(jtComp == 0) {
098      return this.id - that.id;
099    }
100    else return jtComp;
101  }
102  
103  /**
104   * Add the stuff after the "job" prefix to the given builder. This is useful,
105   * because the sub-ids use this substring at the start of their string.
106   * @param builder the builder to append to
107   * @return the builder that was passed in
108   */
109  public StringBuilder appendTo(StringBuilder builder) {
110    builder.append(SEPARATOR);
111    builder.append(jtIdentifier);
112    builder.append(SEPARATOR);
113    builder.append(idFormat.format(id));
114    return builder;
115  }
116
117  @Override
118  public int hashCode() {
119    return jtIdentifier.hashCode() + id;
120  }
121
122  @Override
123  public String toString() {
124    return appendTo(new StringBuilder(JOB)).toString();
125  }
126
127  @Override
128  public void readFields(DataInput in) throws IOException {
129    super.readFields(in);
130    this.jtIdentifier.readFields(in);
131  }
132
133  @Override
134  public void write(DataOutput out) throws IOException {
135    super.write(out);
136    jtIdentifier.write(out);
137  }
138  
139  /** Construct a JobId object from given string 
140   * @return constructed JobId object or null if the given String is null
141   * @throws IllegalArgumentException if the given string is malformed
142   */
143  public static JobID forName(String str) throws IllegalArgumentException {
144    if(str == null)
145      return null;
146    try {
147      String[] parts = str.split("_");
148      if(parts.length == 3) {
149        if(parts[0].equals(JOB)) {
150          return new org.apache.hadoop.mapred.JobID(parts[1], 
151                                                    Integer.parseInt(parts[2]));
152        }
153      }
154    }catch (Exception ex) {//fall below
155    }
156    throw new IllegalArgumentException("JobId string : " + str 
157        + " is not properly formed");
158  }
159  
160}