private boolean didParameterSetConverge(List<TuningJobExecutionParamSet> tuningJobExecutionParamSets) {
    boolean result = false;
    int numParamSetForConvergence = 3;

    if (tuningJobExecutionParamSets.size() < numParamSetForConvergence) {
      return false;
    }

    TuningAlgorithm.JobType jobType = tuningJobExecutionParamSets.get(0).jobSuggestedParamSet.tuningAlgorithm.jobType;

    if (jobType == TuningAlgorithm.JobType.PIG) {

      Map<Integer, Set<Double>> paramValueSet = new HashMap<Integer, Set<Double>>();

      for (TuningJobExecutionParamSet tuningJobExecutionParamSet : tuningJobExecutionParamSets) {

        JobSuggestedParamSet jobSuggestedParamSet = tuningJobExecutionParamSet.jobSuggestedParamSet;

        List<JobSuggestedParamValue> jobSuggestedParamValueList = JobSuggestedParamValue.find.where()
            .eq(JobSuggestedParamValue.TABLE.jobSuggestedParamSet + '.' + JobSuggestedParamSet.TABLE.id,
                jobSuggestedParamSet.id)
            .or(Expr.eq(JobSuggestedParamValue.TABLE.tuningParameter + '.' + TuningParameter.TABLE.paramName,
                "mapreduce.map.memory.mb"),
                Expr.eq(JobSuggestedParamValue.TABLE.tuningParameter + '.' + TuningParameter.TABLE.paramName,
                    "mapreduce.reduce.memory.mb"))
            .findList();

        // if jobSuggestedParamValueList contains both mapreduce.map.memory.mb and mapreduce.reduce.memory.mb
        // ie, if the size of jobSuggestedParamValueList is 2
        if (jobSuggestedParamValueList != null && jobSuggestedParamValueList.size() == 2) {
          numParamSetForConvergence -= 1;
          for (JobSuggestedParamValue jobSuggestedParamValue : jobSuggestedParamValueList) {
            Set<Double> tmp;
            if (paramValueSet.containsKey(jobSuggestedParamValue.id)) {
              tmp = paramValueSet.get(jobSuggestedParamValue.id);
            } else {
              tmp = new HashSet<Double>();
            }
            tmp.add(jobSuggestedParamValue.paramValue);
            paramValueSet.put(jobSuggestedParamValue.id, tmp);
          }
        }

        if (numParamSetForConvergence == 0) {
          break;
        }
      }

      result = true;
      for (Integer paramId : paramValueSet.keySet()) {
        if (paramValueSet.get(paramId).size() > 1) {
          result = false;
        }
      }
    }

    if (result) {
      logger.info("Switching off tuning for job: " + tuningJobExecutionParamSets.get(
          0).jobSuggestedParamSet.jobDefinition.jobName + " Reason: parameter set converged");
    }
    return result;
  }
Checks if the tuning parameters converge
@param tuningJobExecutionParamSets List of previous executions and corresponding param sets
@return true if the parameters converge, else false
app/com/linkedin/drelephant/tuning/FitnessComputeUtil.java