Package org.apache.hadoop.vaidya.statistics.job

Source Code of org.apache.hadoop.vaidya.statistics.job.JobStatistics$MapCounterComparator

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.vaidya.statistics.job;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.hadoop.mapred.Counters;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapreduce.TaskID;
import org.apache.hadoop.mapred.TaskStatus;
import org.apache.hadoop.mapreduce.TaskType;
import org.apache.hadoop.mapreduce.jobhistory.JobHistoryParser;
import org.apache.hadoop.mapreduce.jobhistory.JobHistoryParser.JobInfo;
import org.apache.hadoop.mapreduce.jobhistory.JobHistoryParser.TaskAttemptInfo;
import org.apache.hadoop.mapreduce.jobhistory.JobHistoryParser.TaskInfo;

/**
*
*/
public class JobStatistics implements JobStatisticsInterface {
 
 
  /*
   * Pattern for parsing the COUNTERS
   */
  private static final Pattern _pattern = Pattern.compile("[[^,]?]+")//"[[^,]?]+"
 
  /*
   * Job configuration
   */
  private JobConf _jobConf;
 
  /**
   * @param jobConf the jobConf to set
   */
  void setJobConf(JobConf jobConf) {
    this._jobConf = jobConf;
    // TODO: Add job conf to _job array
  }

  /*
   * Aggregated Job level counters
   */
  private JobHistoryParser.JobInfo _jobInfo;
 
  /*
   * Job stats
   */
  private java.util.Hashtable<Enum, String> _job;

  public JobConf getJobConf() {
    return this._jobConf;
  }
 
  /*
   * Get Job Counters of type long
   */
  public long getLongValue(Enum key) {
    if (this._job.get(key) == null) {
      return (long)0;
    }
    else {
      return Long.parseLong(this._job.get(key));
    }
  }
 
  /*
   * Get job Counters of type Double
   */
  public double getDoubleValue(Enum key) {
    if (this._job.get(key) == null) {
      return (double)0;
    } else {
      return Double.parseDouble(this._job.get(key));
    }
  }
 
  /*
   * Get Job Counters of type String
   */
  public String getStringValue(Enum key) {
  if (this._job.get(key) == null) {
    return "";
  } else {
      return this._job.get(key);
  }
  }
 
  /*
   * Set key value of type long
   */
  public void setValue(Enum key, long value) {
    this._job.put(key, Long.toString(value));
  }
 
  /*
   * Set key value of type double
   */
  public void setValue(Enum key, double value) {
    this._job.put(key, Double.toString(value));
  }
 
  /*
   * Set key value of type String
   */
  public void setValue(Enum key, String value) {
    this._job.put(key, value);
  }

  /*
   * Map Task List (Sorted by task id)
   */
  private ArrayList<MapTaskStatistics> _mapTaskList = new ArrayList<MapTaskStatistics>();
 
  /*
   * Reduce Task List (Sorted by task id)
   */
  private ArrayList<ReduceTaskStatistics> _reduceTaskList = new ArrayList<ReduceTaskStatistics>();

 
  /*
   * Ctor:
   */
  public JobStatistics (JobConf jobConf, JobInfo jobInfo) throws ParseException {
    this._jobConf = jobConf;
    this._jobInfo = jobInfo;
    this._job = new Hashtable<Enum, String>();
    populate_Job(this._job, jobInfo)
    populate_MapReduceTaskLists(this._mapTaskList, this._reduceTaskList,
        jobInfo.getAllTasks());

    // Add the Job Type: MAP_REDUCE, MAP_ONLY
    if (getLongValue(JobKeys.TOTAL_REDUCES) == 0) {
      this._job.put(JobKeys.JOBTYPE,"MAP_ONLY");
    } else {
      this._job.put(JobKeys.JOBTYPE,"MAP_REDUCE");
    }
  }
 
  /*
   *
   */
  private void populate_MapReduceTaskLists (ArrayList<MapTaskStatistics> mapTaskList,
                     ArrayList<ReduceTaskStatistics> reduceTaskList,
                     Map<TaskID, TaskInfo> taskMap)
  throws ParseException {
    int num_tasks = taskMap.entrySet().size();
// DO we need these lists?
//    List<TaskAttemptInfo> successfulMapAttemptList =
//      new ArrayList<TaskAttemptInfo>();
//    List<TaskAttemptInfo> successfulReduceAttemptList =
//      new ArrayList<TaskAttemptInfo>();
    for (JobHistoryParser.TaskInfo taskInfo: taskMap.values()) {
      if (taskInfo.getTaskType().equals(TaskType.MAP)) {
        MapTaskStatistics mapT = new MapTaskStatistics();
        TaskAttemptInfo successfulAttempt  = 
          getLastSuccessfulTaskAttempt(taskInfo);
        mapT.setValue(MapTaskKeys.TASK_ID,
            successfulAttempt.getAttemptId().getTaskID().toString());
        mapT.setValue(MapTaskKeys.ATTEMPT_ID,
            successfulAttempt.getAttemptId().toString());
        mapT.setValue(MapTaskKeys.HOSTNAME,
            successfulAttempt.getTrackerName());
        mapT.setValue(MapTaskKeys.TASK_TYPE,
            successfulAttempt.getTaskType().toString());
        mapT.setValue(MapTaskKeys.STATUS,
            successfulAttempt.getTaskStatus().toString());
        mapT.setValue(MapTaskKeys.START_TIME, successfulAttempt.getStartTime());
        mapT.setValue(MapTaskKeys.FINISH_TIME, successfulAttempt.getFinishTime());
        mapT.setValue(MapTaskKeys.SPLITS, taskInfo.getSplitLocations());
        mapT.setValue(MapTaskKeys.TRACKER_NAME, successfulAttempt.getTrackerName());
        mapT.setValue(MapTaskKeys.STATE_STRING, successfulAttempt.getState());
        mapT.setValue(MapTaskKeys.HTTP_PORT, successfulAttempt.getHttpPort());
        mapT.setValue(MapTaskKeys.ERROR, successfulAttempt.getError());
        parseAndAddMapTaskCounters(mapT,
            successfulAttempt.getCounters().toString());
        mapTaskList.add(mapT);

        // Add number of task attempts
        mapT.setValue(MapTaskKeys.NUM_ATTEMPTS,
            (new Integer(taskInfo.getAllTaskAttempts().size())).toString());

        // Add EXECUTION_TIME = FINISH_TIME - START_TIME
        long etime = mapT.getLongValue(MapTaskKeys.FINISH_TIME) -
          mapT.getLongValue(MapTaskKeys.START_TIME);
        mapT.setValue(MapTaskKeys.EXECUTION_TIME, (new Long(etime)).toString());

      }else if (taskInfo.getTaskType().equals(TaskType.REDUCE)) {

        ReduceTaskStatistics reduceT = new ReduceTaskStatistics();
        TaskAttemptInfo successfulAttempt  =
          getLastSuccessfulTaskAttempt(taskInfo);
        reduceT.setValue(ReduceTaskKeys.TASK_ID,
            successfulAttempt.getAttemptId().getTaskID().toString());
        reduceT.setValue(ReduceTaskKeys.ATTEMPT_ID,
            successfulAttempt.getAttemptId().toString());
        reduceT.setValue(ReduceTaskKeys.HOSTNAME,
            successfulAttempt.getTrackerName());
        reduceT.setValue(ReduceTaskKeys.TASK_TYPE,
            successfulAttempt.getTaskType().toString());
        reduceT.setValue(ReduceTaskKeys.STATUS,
            successfulAttempt.getTaskStatus().toString());
        reduceT.setValue(ReduceTaskKeys.START_TIME,
            successfulAttempt.getStartTime());
        reduceT.setValue(ReduceTaskKeys.FINISH_TIME,
            successfulAttempt.getFinishTime());
        reduceT.setValue(ReduceTaskKeys.SHUFFLE_FINISH_TIME,
            successfulAttempt.getShuffleFinishTime());
        reduceT.setValue(ReduceTaskKeys.SORT_FINISH_TIME,
            successfulAttempt.getSortFinishTime());
        reduceT.setValue(ReduceTaskKeys.SPLITS, "");
        reduceT.setValue(ReduceTaskKeys.TRACKER_NAME,
            successfulAttempt.getTrackerName());
        reduceT.setValue(ReduceTaskKeys.STATE_STRING,
            successfulAttempt.getState());
        reduceT.setValue(ReduceTaskKeys.HTTP_PORT,
            successfulAttempt.getHttpPort());
        parseAndAddReduceTaskCounters(reduceT,
            successfulAttempt.getCounters().toString());

        reduceTaskList.add(reduceT);

        // Add number of task attempts
        reduceT.setValue(ReduceTaskKeys.NUM_ATTEMPTS,
            (new Integer(taskInfo.getAllTaskAttempts().size())).toString());

        // Add EXECUTION_TIME = FINISH_TIME - START_TIME
        long etime1 = reduceT.getLongValue(ReduceTaskKeys.FINISH_TIME) -
        reduceT.getLongValue(ReduceTaskKeys.START_TIME);
        reduceT.setValue(ReduceTaskKeys.EXECUTION_TIME,
            (new Long(etime1)).toString());

      } else if (taskInfo.getTaskType().equals(TaskType.JOB_CLEANUP) ||
                 taskInfo.getTaskType().equals(TaskType.JOB_SETUP)) {
        //System.out.println("INFO: IGNORING TASK TYPE : "+task.get(Keys.TASK_TYPE));
      } else {
        System.err.println("UNKNOWN TASK TYPE : "+taskInfo.getTaskType());
      }
    }
  }
 
  /*
   * Get last successful task attempt to be added in the stats
   */
  private TaskAttemptInfo getLastSuccessfulTaskAttempt(TaskInfo task) {
   
    for (TaskAttemptInfo ai: task.getAllTaskAttempts().values()) {
      if (ai.getTaskStatus().equals(TaskStatus.State.SUCCEEDED.toString())) {
        return ai;
      }
    }
    return null;
  }
 
  /*
   * Popuate the job stats
   */
  private void populate_Job (Hashtable<Enum, String> job, JobInfo jobInfo) throws ParseException {
    job.put(JobKeys.FINISH_TIME, String.valueOf(jobInfo.getFinishTime()));
    job.put(JobKeys.JOBID, jobInfo.getJobId().toString());
    job.put(JobKeys.JOBNAME, jobInfo.getJobname());
    job.put(JobKeys.USER, jobInfo.getUsername());
    job.put(JobKeys.JOBCONF, jobInfo.getJobConfPath());
    job.put(JobKeys.SUBMIT_TIME, String.valueOf(jobInfo.getSubmitTime()));
    job.put(JobKeys.LAUNCH_TIME, String.valueOf(jobInfo.getLaunchTime()));
    job.put(JobKeys.TOTAL_MAPS, String.valueOf(jobInfo.getTotalMaps()));
    job.put(JobKeys.TOTAL_REDUCES, String.valueOf(jobInfo.getTotalReduces()));
    job.put(JobKeys.FAILED_MAPS, String.valueOf(jobInfo.getFailedMaps()));
    job.put(JobKeys.FAILED_REDUCES, String.valueOf(jobInfo.getFailedReduces()));
    job.put(JobKeys.FINISHED_MAPS, String.valueOf(jobInfo.getFinishedMaps()));
    job.put(JobKeys.FINISHED_REDUCES,
        String.valueOf(jobInfo.getFinishedReduces()));
    job.put(JobKeys.STATUS, jobInfo.getJobStatus().toString());
    job.put(JobKeys.JOB_PRIORITY, jobInfo.getPriority());
    parseAndAddJobCounters(job, jobInfo.getTotalCounters().toString());
  }
 
 
  /*
   * Parse and add the job counters
   */
  private void parseAndAddJobCounters(Hashtable<Enum, String> job, String counters) throws ParseException {
    Counters cnt = Counters.fromEscapedCompactString(counters);
    for (java.util.Iterator<Counters.Group> grps = cnt.iterator(); grps.hasNext(); ) {
      Counters.Group grp = grps.next();
      //String groupname = "<" + grp.getName() + ">::<" + grp.getDisplayName() + ">";
      for (java.util.Iterator<Counters.Counter> mycounters = grp.iterator(); mycounters.hasNext(); ) {
        Counters.Counter counter = mycounters.next();
        //String countername = "<"+counter.getName()+">::<"+counter.getDisplayName()+">::<"+counter.getValue()+">";
        //System.err.println("groupName:"+groupname+",countername: "+countername);
        String countername = grp.getDisplayName()+"."+counter.getDisplayName();
        String value = (new Long(counter.getValue())).toString();
        String[] parts = {countername,value};
        //System.err.println("part0:<"+parts[0]+">,:part1 <"+parts[1]+">");
        if (parts[0].equals("FileSystemCounters.FILE_BYTES_READ")) {
          job.put(JobKeys.FILE_BYTES_READ, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.FILE_BYTES_WRITTEN")) {
          job.put(JobKeys.FILE_BYTES_WRITTEN, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.HDFS_BYTES_READ")) {
          job.put(JobKeys.HDFS_BYTES_READ, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.HDFS_BYTES_WRITTEN")) {
          job.put(JobKeys.HDFS_BYTES_WRITTEN, parts[1]);
        } else if (parts[0].equals("Job Counters .Launched map tasks")) {
          job.put(JobKeys.LAUNCHED_MAPS, parts[1]);
        } else if (parts[0].equals("Job Counters .Launched reduce tasks")) {
          job.put(JobKeys.LAUNCHED_REDUCES, parts[1]);
        } else if (parts[0].equals("Job Counters .Data-local map tasks")) {
          job.put(JobKeys.DATALOCAL_MAPS, parts[1]);
        } else if (parts[0].equals("Job Counters .Rack-local map tasks")) {
          job.put(JobKeys.RACKLOCAL_MAPS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Map input records")) {
          job.put(JobKeys.MAP_INPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Map output records")) {
          job.put(JobKeys.MAP_OUTPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Map input bytes")) {
          job.put(JobKeys.MAP_INPUT_BYTES, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Map output bytes")) {
          job.put(JobKeys.MAP_OUTPUT_BYTES, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Combine input records")) {
          job.put(JobKeys.COMBINE_INPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Combine output records")) {
          job.put(JobKeys.COMBINE_OUTPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Reduce input groups")) {
          job.put(JobKeys.REDUCE_INPUT_GROUPS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Reduce input records")) {
          job.put(JobKeys.REDUCE_INPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Reduce output records")) {
          job.put(JobKeys.REDUCE_OUTPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Spilled Records")) {
          job.put(JobKeys.SPILLED_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Reduce shuffle bytes")) {
          job.put(JobKeys.SHUFFLE_BYTES, parts[1]);
        } else {
          System.err.println("JobCounterKey:<"+parts[0]+"> ==> NOT INCLUDED IN PERFORMANCE ADVISOR");
        }
      }
    } 
  }
 
  /*
   * Parse and add the Map task counters
   */
  private void parseAndAddMapTaskCounters(MapTaskStatistics mapTask, String counters) throws ParseException {
    Counters cnt = Counters.fromEscapedCompactString(counters);
    for (java.util.Iterator<Counters.Group> grps = cnt.iterator(); grps.hasNext(); ) {
      Counters.Group grp = grps.next();
      //String groupname = "<" + grp.getName() + ">::<" + grp.getDisplayName() + ">";
      for (java.util.Iterator<Counters.Counter> mycounters = grp.iterator(); mycounters.hasNext(); ) {
        Counters.Counter counter = mycounters.next();
        //String countername = "<"+counter.getName()+">::<"+counter.getDisplayName()+">::<"+counter.getValue()+">";
        //System.out.println("groupName:"+groupname+",countername: "+countername);
        String countername = grp.getDisplayName()+"."+counter.getDisplayName();
        String value = (new Long(counter.getValue())).toString();
        String[] parts = {countername,value};
        //System.out.println("part0:"+parts[0]+",:part1 "+parts[1]);
        if (parts[0].equals("FileSystemCounters.FILE_BYTES_READ")) {
          mapTask.setValue(MapTaskKeys.FILE_BYTES_READ, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.FILE_BYTES_WRITTEN")) {
          mapTask.setValue(MapTaskKeys.FILE_BYTES_WRITTEN, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.HDFS_BYTES_READ")) {
          mapTask.setValue(MapTaskKeys.HDFS_BYTES_READ, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.HDFS_BYTES_WRITTEN")) {
          mapTask.setValue(MapTaskKeys.HDFS_BYTES_WRITTEN, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Map input records")) {
          mapTask.setValue(MapTaskKeys.INPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Map output records")) {
          mapTask.setValue(MapTaskKeys.OUTPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Map output bytes")) {
          mapTask.setValue(MapTaskKeys.OUTPUT_BYTES, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Combine input records")) {
          mapTask.setValue(MapTaskKeys.COMBINE_INPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Combine output records")) {
          mapTask.setValue(MapTaskKeys.COMBINE_OUTPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Spilled Records")) {
          mapTask.setValue(MapTaskKeys.SPILLED_RECORDS, parts[1]);
        } else if (parts[0].equals("FileInputFormatCounters.BYTES_READ")) {
          mapTask.setValue(MapTaskKeys.INPUT_BYTES, parts[1]);
        } else {
          System.err.println("MapCounterKey:<"+parts[0]+"> ==> NOT INCLUDED IN PERFORMANCE ADVISOR MAP TASK");
        }
      }   
    }
  }
 
  /*
   * Parse and add the reduce task counters
   */
  private void parseAndAddReduceTaskCounters(ReduceTaskStatistics reduceTask, String counters) throws ParseException {
    Counters cnt = Counters.fromEscapedCompactString(counters);
    for (java.util.Iterator<Counters.Group> grps = cnt.iterator(); grps.hasNext(); ) {
      Counters.Group grp = grps.next();
      //String groupname = "<" + grp.getName() + ">::<" + grp.getDisplayName() + ">";
      for (java.util.Iterator<Counters.Counter> mycounters = grp.iterator(); mycounters.hasNext(); ) {
        Counters.Counter counter = mycounters.next();
        //String countername = "<"+counter.getName()+">::<"+counter.getDisplayName()+">::<"+counter.getValue()+">";
        //System.out.println("groupName:"+groupname+",countername: "+countername);
        String countername = grp.getDisplayName()+"."+counter.getDisplayName();
        String value = (new Long(counter.getValue())).toString();
        String[] parts = {countername,value};
        //System.out.println("part0:"+parts[0]+",:part1 "+parts[1]);
        if (parts[0].equals("FileSystemCounters.FILE_BYTES_READ")) {
          reduceTask.setValue(ReduceTaskKeys.FILE_BYTES_READ, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.FILE_BYTES_WRITTEN")) {
          reduceTask.setValue(ReduceTaskKeys.FILE_BYTES_WRITTEN, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.HDFS_BYTES_READ")) {
          reduceTask.setValue(ReduceTaskKeys.HDFS_BYTES_READ, parts[1]);
        } else if (parts[0].equals("FileSystemCounters.HDFS_BYTES_WRITTEN")) {
          reduceTask.setValue(ReduceTaskKeys.HDFS_BYTES_WRITTEN, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Reduce input records")) {
          reduceTask.setValue(ReduceTaskKeys.INPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Reduce output records")) {
          reduceTask.setValue(ReduceTaskKeys.OUTPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Combine input records")) {
          reduceTask.setValue(ReduceTaskKeys.COMBINE_INPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Combine output records")) {
          reduceTask.setValue(ReduceTaskKeys.COMBINE_OUTPUT_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Reduce input groups")) {
          reduceTask.setValue(ReduceTaskKeys.INPUT_GROUPS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Spilled Records")) {
          reduceTask.setValue(ReduceTaskKeys.SPILLED_RECORDS, parts[1]);
        } else if (parts[0].equals("Map-Reduce Framework.Reduce shuffle bytes")) {
          reduceTask.setValue(ReduceTaskKeys.SHUFFLE_BYTES, parts[1]);
        } else {
          System.err.println("ReduceCounterKey:<"+parts[0]+"> ==> NOT INCLUDED IN PERFORMANCE ADVISOR REDUCE TASK");
        }
      }
    }   
  }
 
  /*
   * Print the Job Execution Statistics
   * TODO: split to pring job, map/reduce task list and individual map/reduce task stats
   */
  public void printJobExecutionStatistics() {
    /*
     * Print Job Counters
     */
    System.out.println("JOB COUNTERS *********************************************");
    int size = this._job.size();
    java.util.Iterator<Map.Entry<Enum, String>> kv = this._job.entrySet().iterator();
    for (int i = 0; i < size; i++)
    {
      Map.Entry<Enum, String> entry = (Map.Entry<Enum, String>) kv.next();
      Enum key = entry.getKey();
      String value = entry.getValue();
      System.out.println("Key:<" + key.name() + ">, value:<"+ value +">");
    }
    /*
     *
     */
    System.out.println("MAP COUNTERS *********************************************");
    int size1 = this._mapTaskList.size();
    for (int i = 0; i < size1; i++)
    {
      System.out.println("MAP TASK *********************************************");
      this._mapTaskList.get(i).printKeys();
    }
    /*
     *
     */
    System.out.println("REDUCE COUNTERS *********************************************");
    int size2 = this._mapTaskList.size();
    for (int i = 0; i < size2; i++)
    {
      System.out.println("REDUCE TASK *********************************************");
      this._reduceTaskList.get(i).printKeys();
    }
  }
 
  /*
   * Hash table keeping sorted lists of map tasks based on the specific map task key
   */
  private Hashtable <Enum, ArrayList<MapTaskStatistics>> _sortedMapTaskListsByKey = new Hashtable<Enum, ArrayList<MapTaskStatistics>>();
 
  /*
   * @return mapTaskList : ArrayList of MapTaskStatistics
   * @param mapTaskSortKey : Specific counter key used for sorting the task list
   * @param datatype : indicates the data type of the counter key used for sorting
   * If sort key is null then by default map tasks are sorted using map task ids.
   */
  public synchronized ArrayList<MapTaskStatistics>
          getMapTaskList(Enum mapTaskSortKey, KeyDataType dataType) {
   
    /*
     * If mapTaskSortKey is null then use the task id as a key.
     */
    if (mapTaskSortKey == null) {
      mapTaskSortKey = MapTaskKeys.TASK_ID;
    }
   
    if (this._sortedMapTaskListsByKey.get(mapTaskSortKey) == null) {
      ArrayList<MapTaskStatistics> newList = (ArrayList<MapTaskStatistics>)this._mapTaskList.clone();
      this._sortedMapTaskListsByKey.put(mapTaskSortKey, this.sortMapTasksByKey(newList, mapTaskSortKey, dataType));
    }
    return this._sortedMapTaskListsByKey.get(mapTaskSortKey);
  }
 
  private ArrayList<MapTaskStatistics> sortMapTasksByKey (ArrayList<MapTaskStatistics> mapTasks,
                         Enum key, Enum dataType) {
    MapCounterComparator mcc = new MapCounterComparator(key, dataType);
    Collections.sort (mapTasks, mcc);
    return mapTasks;
  }
 
  private class MapCounterComparator implements Comparator<MapTaskStatistics> {

    public Enum _sortKey;
    public Enum _dataType;
   
    public MapCounterComparator(Enum key, Enum dataType) {
      this._sortKey = key;
      this._dataType = dataType;
    }
   
    // Comparator interface requires defining compare method.
    public int compare(MapTaskStatistics a, MapTaskStatistics b) {
      if (this._dataType == KeyDataType.LONG) {
        long aa = a.getLongValue(this._sortKey);
        long bb = b.getLongValue(this._sortKey);
        if (aa<bb) return -1; if (aa==bb) return 0; if (aa>bb) return 1;
      } else {
        return a.getStringValue(this._sortKey).compareToIgnoreCase(b.getStringValue(this._sortKey));
      }
     
      return 0;
    }
  }
 
  /*
   * Reduce Array List sorting
   */
    private Hashtable <Enum, ArrayList<ReduceTaskStatistics>> _sortedReduceTaskListsByKey = new Hashtable<Enum,ArrayList<ReduceTaskStatistics>>();
 
    /*
     * @return reduceTaskList : ArrayList of ReduceTaskStatistics
   * @param reduceTaskSortKey : Specific counter key used for sorting the task list
   * @param dataType : indicates the data type of the counter key used for sorting
   * If sort key is null then, by default reduce tasks are sorted using task ids.
     */
  public synchronized ArrayList<ReduceTaskStatistics>
                                getReduceTaskList (Enum reduceTaskSortKey, KeyDataType dataType) {
   
    /*
     * If reduceTaskSortKey is null then use the task id as a key.
     */
    if (reduceTaskSortKey == null) {
      reduceTaskSortKey = ReduceTaskKeys.TASK_ID;
    }
   
    if (this._sortedReduceTaskListsByKey.get(reduceTaskSortKey) == null) {
      ArrayList<ReduceTaskStatistics> newList = (ArrayList<ReduceTaskStatistics>)this._reduceTaskList.clone();
      this._sortedReduceTaskListsByKey.put(reduceTaskSortKey, this.sortReduceTasksByKey(newList, reduceTaskSortKey, dataType));
    }
   
    return this._sortedReduceTaskListsByKey.get(reduceTaskSortKey)
  }
 
  private ArrayList<ReduceTaskStatistics> sortReduceTasksByKey (ArrayList<ReduceTaskStatistics> reduceTasks,
                                Enum key, Enum dataType) {
    ReduceCounterComparator rcc = new ReduceCounterComparator(key, dataType);
    Collections.sort (reduceTasks, rcc);
    return reduceTasks;
  }
 
  private class ReduceCounterComparator implements Comparator<ReduceTaskStatistics> {

    public Enum _sortKey;
    public Enum _dataType;  //either long or string
   
    public ReduceCounterComparator(Enum key, Enum dataType) {
      this._sortKey = key;
      this._dataType = dataType;
    }
   
    // Comparator interface requires defining compare method.
    public int compare(ReduceTaskStatistics a, ReduceTaskStatistics b) {
      if (this._dataType == KeyDataType.LONG) {
        long aa = a.getLongValue(this._sortKey);
        long bb = b.getLongValue(this._sortKey);
        if (aa<bb) return -1; if (aa==bb) return 0; if (aa>bb) return 1;
      } else {
        return a.getStringValue(this._sortKey).compareToIgnoreCase(b.getStringValue(this._sortKey));
      }
     
      return 0;
    }
  }
}
TOP

Related Classes of org.apache.hadoop.vaidya.statistics.job.JobStatistics$MapCounterComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.