/** creates and submits a job, updates file index and job index */
  private void startJob(String jobName, Map<String, Integer> corruptFilePriority, int priority)
      throws IOException, InterruptedException, ClassNotFoundException {
    Path inDir = new Path(WORK_DIR_PREFIX + "/in/" + jobName);
    Path outDir = new Path(WORK_DIR_PREFIX + "/out/" + jobName);
    List<String> filesInJob = createInputFile(jobName, inDir, corruptFilePriority, priority);
    if (filesInJob.isEmpty()) return;

    Configuration jobConf = new Configuration(getConf());
    RaidUtils.parseAndSetOptions(
        jobConf, priority == 1 ? HIGH_PRI_SCHEDULER_OPTION : LOW_PRI_SCHEDULER_OPTION);
    Job job = new Job(jobConf, jobName);
    job.setJarByClass(getClass());
    job.setMapperClass(DistBlockFixerMapper.class);
    job.setNumReduceTasks(0);
    job.setInputFormatClass(DistBlockFixerInputFormat.class);
    job.setOutputFormatClass(SequenceFileOutputFormat.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(Text.class);

    DistBlockFixerInputFormat.setInputPaths(job, inDir);
    SequenceFileOutputFormat.setOutputPath(job, outDir);

    submitJob(job, filesInJob, priority);
    List<CorruptFileInfo> fileInfos = updateFileIndex(jobName, filesInJob, priority);
    // The implementation of submitJob() need not update jobIndex.
    // So check if the job exists in jobIndex before updating jobInfos.
    if (jobIndex.containsKey(job)) {
      jobIndex.put(job, fileInfos);
    }
    numJobsRunning++;
  }