private void updateDatabase(List<JobTuningInfo> jobTuningInfoList) {
    logger.info("Updating new parameter suggestion in database");
    if (jobTuningInfoList == null) {
      logger.info("No new parameter suggestion to update");
      return;
    }

    int paramSetNotGeneratedJobs = jobTuningInfoList.size();

    for (JobTuningInfo jobTuningInfo : jobTuningInfoList) {
      logger.info("Updating new parameter suggestion for job:" + jobTuningInfo.getTuningJob().jobDefId);

      JobDefinition job = jobTuningInfo.getTuningJob();
      List<TuningParameter> paramList = jobTuningInfo.getParametersToTune();
      String stringTunerState = jobTuningInfo.getTunerState();
      if (stringTunerState == null) {
        logger.error("Suggested parameter suggestion is empty for job id: " + job.jobDefId);
        continue;
      }

      TuningJobDefinition tuningJobDefinition = TuningJobDefinition.find.select("*")
          .fetch(TuningJobDefinition.TABLE.job, "*")
          .where()
          .eq(TuningJobDefinition.TABLE.job + "." + JobDefinition.TABLE.id, job.id)
          .eq(TuningJobDefinition.TABLE.tuningEnabled, 1)
          .findUnique();

      List<TuningParameter> derivedParameterList = new ArrayList<TuningParameter>();
        derivedParameterList = TuningParameter.find.where()
            .eq(TuningParameter.TABLE.tuningAlgorithm + "." + TuningAlgorithm.TABLE.id,
                tuningJobDefinition.tuningAlgorithm.id)
            .eq(TuningParameter.TABLE.isDerived, 1)
            .findList();

      logger.info("No. of derived tuning params for job " + tuningJobDefinition.job.jobName + ": "
          + derivedParameterList.size());

      JsonNode jsonTunerState = Json.parse(stringTunerState);
      JsonNode jsonSuggestedPopulation = jsonTunerState.get(JSON_CURRENT_POPULATION_KEY);

      if (jsonSuggestedPopulation == null) {
        continue;
      }

      paramSetNotGeneratedJobs--;

      List<Particle> suggestedPopulation = jsonToParticleList(jsonSuggestedPopulation);

      for (Particle suggestedParticle : suggestedPopulation) {
        AutoTuningMetricsController.markParamSetGenerated();
        List<JobSuggestedParamValue> jobSuggestedParamValueList = getParamValueList(suggestedParticle, paramList);

        Map<String, Double> jobSuggestedParamValueMap = new HashMap<String, Double>();
        for (JobSuggestedParamValue jobSuggestedParamValue : jobSuggestedParamValueList) {
          jobSuggestedParamValueMap.put(jobSuggestedParamValue.tuningParameter.paramName,
              jobSuggestedParamValue.paramValue);
        }

        for (TuningParameter derivedParameter : derivedParameterList) {
          logger.info("Computing value of derived param: " + derivedParameter.paramName);
          Double paramValue = null;
          if (derivedParameter.paramName.equals("mapreduce.reduce.java.opts")) {
            String parentParamName = "mapreduce.reduce.memory.mb";
            if (jobSuggestedParamValueMap.containsKey(parentParamName)) {
              paramValue = 0.75 * jobSuggestedParamValueMap.get(parentParamName);
            }
          } else if (derivedParameter.paramName.equals("mapreduce.map.java.opts")) {
            String parentParamName = "mapreduce.map.memory.mb";
            if (jobSuggestedParamValueMap.containsKey(parentParamName)) {
              paramValue = 0.75 * jobSuggestedParamValueMap.get(parentParamName);
            }
          } else if (derivedParameter.paramName.equals("mapreduce.input.fileinputformat.split.maxsize")) {
            String parentParamName = "pig.maxCombinedSplitSize";
            if (jobSuggestedParamValueMap.containsKey(parentParamName)) {
              paramValue = jobSuggestedParamValueMap.get(parentParamName);
            }
          }

          if (paramValue != null) {
            JobSuggestedParamValue jobSuggestedParamValue = new JobSuggestedParamValue();
            jobSuggestedParamValue.paramValue = paramValue;
            jobSuggestedParamValue.tuningParameter = derivedParameter;
            jobSuggestedParamValueList.add(jobSuggestedParamValue);
          }
        }

        JobSuggestedParamSet jobSuggestedParamSet = new JobSuggestedParamSet();
        jobSuggestedParamSet.jobDefinition = job;
        jobSuggestedParamSet.tuningAlgorithm = tuningJobDefinition.tuningAlgorithm;
        jobSuggestedParamSet.isParamSetDefault = false;
        jobSuggestedParamSet.isParamSetBest = false;
        if (isParamConstraintViolated(jobSuggestedParamValueList, jobSuggestedParamSet.tuningAlgorithm.jobType)) {
          logger.info("Parameter constraint violated. Applying penalty.");
          int penaltyConstant = 3;
          Double averageResourceUsagePerGBInput =
              tuningJobDefinition.averageResourceUsage * FileUtils.ONE_GB / tuningJobDefinition.averageInputSizeInBytes;
          Double maxDesiredResourceUsagePerGBInput =
              averageResourceUsagePerGBInput * tuningJobDefinition.allowedMaxResourceUsagePercent / 100.0;

          jobSuggestedParamSet.areConstraintsViolated = true;
          jobSuggestedParamSet.fitness = penaltyConstant * maxDesiredResourceUsagePerGBInput;
          jobSuggestedParamSet.paramSetState = JobSuggestedParamSet.ParamSetStatus.FITNESS_COMPUTED;
        } else {
          jobSuggestedParamSet.areConstraintsViolated = false;
          jobSuggestedParamSet.paramSetState = JobSuggestedParamSet.ParamSetStatus.CREATED;
        }
        Long paramSetId = saveSuggestedParamSet(jobSuggestedParamSet);

        for (JobSuggestedParamValue jobSuggestedParamValue : jobSuggestedParamValueList) {
          jobSuggestedParamValue.jobSuggestedParamSet = jobSuggestedParamSet;
        }
        suggestedParticle.setPramSetId(paramSetId);
        saveSuggestedParams(jobSuggestedParamValueList);
      }

      JsonNode updatedJsonSuggestedPopulation = particleListToJson(suggestedPopulation);

      ObjectNode updatedJsonTunerState = (ObjectNode) jsonTunerState;
      updatedJsonTunerState.put(JSON_CURRENT_POPULATION_KEY, updatedJsonSuggestedPopulation);
      String updatedStringTunerState = Json.stringify(updatedJsonTunerState);
      jobTuningInfo.setTunerState(updatedStringTunerState);
    }
    AutoTuningMetricsController.setParamSetGenerateWaitJobs(paramSetNotGeneratedJobs);
    saveTunerState(jobTuningInfoList);
  }
For every tuning info:
   For every new particle:
       From the tuner set extract the list of suggested parameters
       Check penalty
       Save the param in the job execution table by creating execution instance (Create an entry into param_set table)
       Update the execution instance in each of the suggested params (Update the param_set_id in each of the prams)
       save th suggested parameters
       update the paramsetid in the particle and add particle to a particlelist
   Update the tunerstate from the updated particles
   save the tuning info in db

@param jobTuningInfoList JobTuningInfo List
app/com/linkedin/drelephant/tuning/ParamGenerator.java