/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.jobgroup; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import com.slamd.asn1.ASN1Boolean; import com.slamd.asn1.ASN1Element; import com.slamd.asn1.ASN1Integer; import com.slamd.asn1.ASN1OctetString; import com.slamd.asn1.ASN1Sequence; import com.slamd.common.Constants; import com.slamd.common.SLAMDException; import com.slamd.db.DecodeException; import com.slamd.job.Job; import com.slamd.job.JobClass; import com.slamd.job.JobItem; import com.slamd.job.OptimizationAlgorithm; import com.slamd.job.OptimizingJob; import com.slamd.job.UnknownJobClass; import com.slamd.parameter.InvalidValueException; import com.slamd.parameter.Parameter; import com.slamd.parameter.ParameterList; import com.slamd.server.SLAMDServer; import com.slamd.server.Scheduler; /** * This class defines a data structure for holding information about an * optimizing job that is scheduled as part of a job group. * * * @author Neil A. Wilson */ public class JobGroupOptimizingJob implements JobGroupItem { /** * The name of the encoded element that holds the optimizing job name. */ public static final String ELEMENT_NAME = "name"; /** * The name of the encoded element that holds the job class name. */ public static final String ELEMENT_JOB_CLASS = "job_class"; /** * The name of the encoded element that holds the duration. */ public static final String ELEMENT_DURATION = "duration"; /** * The name of the encoded element that holds the delay between iterations. */ public static final String ELEMENT_DELAY_BETWEEN_ITERATIONS = "delay_between_iterations"; /** * The name of the encoded element that holds the number of clients. */ public static final String ELEMENT_NUM_CLIENTS = "num_clients"; /** * The name of the encoded element that holds the minimum number of threads * per client. */ public static final String ELEMENT_MIN_THREADS = "min_threads"; /** * The name of the encoded element that holds the maximum number of threads * per client. */ public static final String ELEMENT_MAX_THREADS = "max_threads"; /** * The name of the encoded element that holds the thread increment. */ public static final String ELEMENT_THREAD_INCREMENT = "thread_increment"; /** * The name of the encoded element that holds the statistics collection * interval. */ public static final String ELEMENT_COLLECTION_INTERVAL = "collection_interval"; /** * The name of the encoded element that holds the maximum number of * non-improving iterations. */ public static final String ELEMENT_MAX_NONIMPROVING = "max_nonimproving"; /** * The name of the encoded element that holds the thread startup delay. */ public static final String ELEMENT_THREAD_STARTUP_DELAY = "thread_startup_delay"; /** * The name of the encoded element that holds the flag indicating whether to * re-run the best iteration. */ public static final String ELEMENT_RERUN_BEST_ITERATION = "rerun_best_iteration"; /** * The name of the encoded element that holds the re-run duration. */ public static final String ELEMENT_RERUN_DURATION = "rerun_duration"; /** * The name of the encoded element that holds the set of dependencies for the * optimizing job. */ public static final String ELEMENT_DEPENDENCIES = "dependencies"; /** * The name of the encoded element that holds the optimization algorithm. */ public static final String ELEMENT_OPTIMIZATION_ALGORITHM = "optimization_algorithm"; /** * The name of the encoded element that holds the set of mapped parameters. */ public static final String ELEMENT_MAPPED_PARAMS = "mapped_parameters"; /** * The name of the encoded element that holds the set of fixed parameters. */ public static final String ELEMENT_FIXED_PARAMS = "fixed_parameters"; // The set of dependencies for this optimizing job. They will be the names of // other jobs or optimizing jobs in the job group on which this job is // dependent. private ArrayList<String> dependencies; // Indicates whether to re-run the best iteration for this optimizing job. private boolean reRunBestIteration; // The optimizing job parameters that will be requested from the user, mapped // from the names used in the job group to the parameter stub for this // optimizing job. private LinkedHashMap<String,String> mappedParameters; // The statistics collection interval for this optimizing job. private int collectionInterval; // The delay in seconds between iterations of this optimizing job. private int delayBetweenIterations; // The maximum length of time in seconds that regular iterations of this // optimizing job should run. private int duration; // The maximum number of consecutive non-improving iterations for this // optimizing job. private int maxNonImproving; // The maximum number of threads to use to execute the optimizing job. private int maxThreads; // The minimum number of threads to use to execute the optimizing job. private int minThreads; // The number of clients to use to execute the optimizing job. private int numClients; // The maximum length of time in seconds that the re-run iteration should run. private int reRunDuration; // The thread increment to use for this optimizing job. private int threadIncrement; // The thread startup delay for this job. private int threadStartupDelay; // The job class for this optimizing job. private JobClass jobClass; // The job group with which this optimizing job is associated. private JobGroup jobGroup; // The optimization algorithm for this optimizing job. private OptimizationAlgorithm optimizationAlgorithm; // The fixed-value parameters that will always be used for this job in the job // group. private ParameterList fixedParameters; // The set of parameters for the associated optimization algorithm. private ParameterList optimizationParameters; // A name used to identify this job in the job group. private String name; /** * Creates a new job group optimizing job with the provided information. * * @param name The name for this optimizing job. * @param jobGroup The job group with which this optimizing * job is associated. * @param jobClass The job class for this optimizing job. * @param duration The duration in seconds for iterations of * this optimizing job. * @param delayBetweenIterations The length of time in seconds that should * be allowed between the end of one iteration * and the beginning of the next. * @param numClients The number of clients to use to run this * optimizing job. * @param minThreads The minimum number of threads per client * for this optimizing job. * @param maxThreads The maximum number of threads per client * for this optimizing job. * @param threadIncrement The thread increment between iterations for * this optimizing job. * @param collectionInterval The collection interval for this optimizing * job. * @param maxNonImproving The maximum number of non-improving * iterations that will be allowed for this * optimizing job. * @param threadStartupDelay The thread startup delay for iterations of * this optimizing job. * @param reRunBestIteration Indicates whether to re-run the best * iteration of this optimizing job. * @param reRunDuration The duration in seconds for the re-run * iteration. * @param dependencies The names of the job group jobs and/or * optimizing jobs on which this optimizing * job is dependent. * @param optimizationAlgorithm The optimization algorithm for this * optimizing job. * @param optimizationParameters The set of parameters for use with the * optimization algorithm. * @param mappedParameters The set of mapped parameters for this * optimizing job. * @param fixedParameters The set of fixed parameters for this * optimizing job. */ public JobGroupOptimizingJob(String name, JobGroup jobGroup, JobClass jobClass, int duration, int delayBetweenIterations, int numClients, int minThreads, int maxThreads, int threadIncrement, int collectionInterval, int maxNonImproving, int threadStartupDelay, boolean reRunBestIteration, int reRunDuration, ArrayList<String> dependencies, OptimizationAlgorithm optimizationAlgorithm, ParameterList optimizationParameters, LinkedHashMap<String,String> mappedParameters, ParameterList fixedParameters) { this.name = name; this.jobGroup = jobGroup; this.jobClass = jobClass; this.duration = duration; this.delayBetweenIterations = delayBetweenIterations; this.numClients = numClients; this.minThreads = minThreads; this.maxThreads = maxThreads; this.threadIncrement = threadIncrement; this.collectionInterval = collectionInterval; this.maxNonImproving = maxNonImproving; this.threadStartupDelay = threadStartupDelay; this.reRunBestIteration = reRunBestIteration; this.reRunDuration = reRunDuration; this.dependencies = dependencies; this.optimizationAlgorithm = optimizationAlgorithm; this.optimizationParameters = optimizationParameters; this.mappedParameters = mappedParameters; this.fixedParameters = fixedParameters; } /** * Retrieves the human-readable name for this optimizing job. * * @return The human-readable name for this optimizing job. */ public String getName() { return name; } /** * Specifies the human-readable name for this optimizing job. * * @param name The human-readable name for this optimizing job. */ public void setName(String name) { this.name = name; } /** * Retrieves the job group for this optimizing job. * * @return The job group for this optimizing job. */ public JobGroup getJobGroup() { return jobGroup; } /** * Specifies the job group for this optimizing job. * * @param jobGroup The job group for this optimizing job. */ public void setJobGroup(JobGroup jobGroup) { this.jobGroup = jobGroup; } /** * Retrieves the job class for this optimizing job. * * @return The job class for this optimizing job. */ public JobClass getJobClass() { return jobClass; } /** * Specifies the job class for this optimizing job. * * @param jobClass The job class for this optimizing job. */ public void setJobClass(JobClass jobClass) { this.jobClass = jobClass; } /** * Retrieves the duration for iterations of this optimizing job. * * @return The duration for iterations of this optimizing job. */ public int getDuration() { return duration; } /** * Specifies the duration for iterations of this optimizing job. * * @param duration The duration for iterations of this optimizing job. */ public void setDuration(int duration) { this.duration = duration; } /** * Retrieves the delay between iterations for this optimizing job. * * @return The delay between iterations for this optimizing job. */ public int getDelayBetweenIterations() { return delayBetweenIterations; } /** * Specifies the delay between iterations for this optimizing job. * * @param delayBetweenIterations The delay between iterations for this * optimizing job. */ public void setDelayBetweenIterations(int delayBetweenIterations) { this.delayBetweenIterations = delayBetweenIterations; } /** * Retrieves the number of clients for this optimizing job. * * @return The number of clients for this optimizing job. */ public int getNumClients() { return numClients; } /** * Specifies the number of clients for this optimizing job. * * @param numClients The number of clients for this optimizing job. */ public void setNumClients(int numClients) { this.numClients = numClients; } /** * Retrieves the minimum number of threads per client for this optimizing job. * * @return The minimum number of threads per client for this optimizing job. */ public int getMinThreads() { return minThreads; } /** * Specifies the minimum number of threads per client for this optimizing job. * * @param minThreads The minimum number of threads per client for this * optimizing job. */ public void setMinThreads(int minThreads) { this.minThreads = minThreads; } /** * Retrieves the maximum number of threads per client for this optimizing job. * * @return The maximum number of threads per client for this optimizing job. */ public int getMaxThreads() { return maxThreads; } /** * Specifies the maximum number of threads per client for this optimizing job. * * @param maxThreads The maximum number of threads per client for this * optimizing job. */ public void setMaxThreads(int maxThreads) { this.maxThreads = maxThreads; } /** * Retrieves the increment in the number of threads per client between * iterations of this optimizing job. * * @return The increment in the number of threads per client between * iterations of this optimizing job. */ public int getThreadIncrement() { return threadIncrement; } /** * Specifies the increment in the number of threads per client between * iterations of this optimizing job. * * @param threadIncrement The increment in the number of threads per client * between iterations of this optimizing job. */ public void setThreadIncrement(int threadIncrement) { this.threadIncrement = threadIncrement; } /** * Retrieves the statistics collection interval for this optimizing job. * * @return The statistics collection interval for this optimizing job. */ public int getCollectionInterval() { return collectionInterval; } /** * Specifies the statistics collection interval for this optimizing job. * * @param collectionInterval The statistics collection interval for this * optimizing job. */ public void setCollectionInterval(int collectionInterval) { this.collectionInterval = collectionInterval; } /** * Retrieves the maximum number of non-improving iterations that will be * allowed for this optimizing job. * * @return The maximum number of non-improving iterations that will be * allowed for this optimizing job. */ public int getMaxNonImprovingIterations() { return maxNonImproving; } /** * Specifies the maximum number of non-improving iterations that will be * allowed for this optimizing job. * * @param maxNonImproving The maximum number of non-improving iterations * that will be allowed for this optimizing job. */ public void setMaxNonImprovingIterations(int maxNonImproving) { this.maxNonImproving = maxNonImproving; } /** * Retrieves the delay in milliseconds that should be used when creating * threads for this optimizing job. * * @return The delay in milliseconds that should be used when creating * threads for this optimizing job. */ public int getThreadStartupDelay() { return threadStartupDelay; } /** * Specifies the delay in milliseconds that should be used when creating * threads for this optimizing job. * * @param threadStartupDelay The delay in milliseconds that should be used * when creating threads for this optimizing job. */ public void setThreadStartupDelay(int threadStartupDelay) { this.threadStartupDelay = threadStartupDelay; } /** * Indicates whether to re-run the best iteration of this optimizing job. * * @return <CODE>true</CODE> if the best iteration of this optimizing job * should be re-run, or <CODE>false</CODE> if not. */ public boolean reRunBestIteration() { return reRunBestIteration; } /** * Specifies whether to re-run the best iteration of this optimizing job. * * @param reRunBestIteration Specifies whether to re-run the best iteration * of this optimizing job. */ public void setReRunBestIteration(boolean reRunBestIteration) { this.reRunBestIteration = reRunBestIteration; } /** * Retrieves the duration in seconds for the re-run iteration of this * optimizing job. * * @return The duration in seconds for the re-run iteration of this * optimizing job. */ public int getReRunDuration() { return reRunDuration; } /** * Specifies the duration in seconds for the re-run iteration of this * optimizing job. * * @param reRunDuration The duration in seconds for the re-run iteration of * this optimizing job. */ public void setReRunDuration(int reRunDuration) { this.reRunDuration = reRunDuration; } /** * Retrieves the names of the jobs and/or optimizing jobs on which this * optimizing job is dependent. The contents of the returned list may be * altered by the caller. * * @return The names of the jobs and/or optimizing jobs on which this * optimizing job is dependent. */ public ArrayList<String> getDependencies() { return dependencies; } /** * Retrieves the optimization algorithm for this optimizing job. * * @return The optimization algorithm for this optimizing job. */ public OptimizationAlgorithm getOptimizationAlgorithm() { return optimizationAlgorithm; } /** * Specifies the optimization algorithm for this optimizing job. * * @param optimizationAlgorithm The optimization algorithm for this * optimizing job. */ public void setOptimizationAlgorithm(OptimizationAlgorithm optimizationAlgorithm) { this.optimizationAlgorithm = optimizationAlgorithm; } /** * Retrieves the set of parameters for use with the optimization algorithm. * * @return The set of parameters for use with the optimization algorithm. */ public ParameterList getOptimizationParameters() { return optimizationParameters; } /** * Specifies the set of parameters for use with the optimization algorithm. * * @param optimizationParameters The set of parameters for use with the * optimization algorithm. */ public void setOptimizationParameters(ParameterList optimizationParameters) { this.optimizationParameters = optimizationParameters; } /** * Retrieves the set of mapped parameters for this optimizing job, mapped * between the name of the parameter for the job class and the name of the * parameter associated with the job group. The contents of the returned map * may be altered by the caller. * * @return The set of mapped parameters for this optimizing job. */ public LinkedHashMap<String,String> getMappedParameters() { return mappedParameters; } /** * Retrieves the set of fixed parameters for this optimizing job. The * returned parameter list may be altered by the caller. * * @return The set of fixed parameters for this optimizing job. */ public ParameterList getFixedParameters() { return fixedParameters; } /** * Schedules this optimizing job for execution by the SLAMD server using the * provided information. * * @param slamdServer The reference to the SLAMD server to use * when scheduling the optimizing job. * @param startTime The start time to use for the optimizing * job. * @param folderName The name of the folder into which the * optimizing job should be placed. * @param requestedClients The set of clients that have been * requested for this job group. * @param requestedMonitorClients the set of resource monitor clients that * have been requested for this job group. * @param monitorClientsIfAvailable Indicates whether the clients used to * run the job should be monitored if there * are also resource monitor clients * running on the same system. * @param externalDependencies A set of jobs outside of this job group * on which the scheduled optimizing job * should be dependent. * @param parameters The set of parameters that the user * provided for the job group. * @param scheduledJobs The set of jobs and optimizing jobs that * have been scheduled so far as part of * the job group. They will be mapped from * the name of the job or optimizing job in * this job group to the corresponding * object. * @param messages A list of messages that should be * displayed to the user as a result of * scheduling the optimizing job. * * @throws SLAMDException If a problem occurs while attempting to schedule * the optimizing job. */ public void schedule(SLAMDServer slamdServer, Date startTime, String folderName, String[] requestedClients, String[] requestedMonitorClients, boolean monitorClientsIfAvailable, String[] externalDependencies, ParameterList parameters, LinkedHashMap<String,JobItem> scheduledJobs, ArrayList<String> messages) throws SLAMDException { // Create a new parameter list that combines the mapped parameters and the // fixed parameters. Parameter[] params = jobClass.getParameterStubs().clone().getParameters(); for (int i=0; i < params.length; i++) { String paramName = params[i].getName(); String mappedName = mappedParameters.get(paramName); if (mappedName == null) { Parameter p = fixedParameters.getParameter(paramName); if (p != null) { params[i].setValueFrom(p); } } else { Parameter p = parameters.getParameter(mappedName); if (p != null) { params[i].setValueFrom(p); } } } ParameterList jobParameters = new ParameterList(params); // Create the set of dependencies for the optimizing job. ArrayList<String> depList = new ArrayList<String>(dependencies.size()); if ((externalDependencies != null) && (externalDependencies.length > 0)) { for (int i=0; i < externalDependencies.length; i++) { depList.add(externalDependencies[i]); } } for (int i=0; i < dependencies.size(); i++) { String dependencyName = dependencies.get(i); Object o = scheduledJobs.get(dependencyName); if (o == null) { continue; } else if (o instanceof Job) { depList.add(((Job) o).getJobID()); } else if (o instanceof OptimizingJob) { depList.add(((OptimizingJob) o).getOptimizingJobID()); } } String[] dependencyArray = new String[depList.size()]; depList.toArray(dependencyArray); // Create the requested client array. String[] clientArray = null; if ((requestedClients != null) && (requestedClients.length > 0)) { // FIXME -- Do we need to worry about the possibility of jobs running in // parallel within this job group? ArrayList<String> clientList = new ArrayList<String>(numClients); for (int i=0; ((i < numClients) && (i < requestedClients.length)); i++) { clientList.add(requestedClients[i]); } clientArray = new String[clientList.size()]; clientList.toArray(clientArray); } // Get a reference to the scheduler and create the optimizing job ID. Scheduler scheduler = slamdServer.getScheduler(); String optimizingJobID = scheduler.generateUniqueID(); // Create the optimizing job using the information available. OptimizingJob optimizingJob = new OptimizingJob(slamdServer, optimizingJobID, optimizationAlgorithm, jobClass, folderName, name, true, startTime, duration, delayBetweenIterations, numClients, clientArray, requestedMonitorClients, monitorClientsIfAvailable, minThreads, maxThreads, threadIncrement, collectionInterval, maxNonImproving, null, reRunBestIteration, reRunDuration, jobParameters, false); optimizingJob.setJobGroup(jobGroup.getName()); optimizingJob.setDependencies(dependencyArray); optimizingJob.setThreadStartupDelay(threadStartupDelay); // Initialize the optimization algorithm. try { optimizationAlgorithm.initializeOptimizationAlgorithm(optimizingJob, optimizationParameters); } catch (InvalidValueException ive) { throw new SLAMDException("ERROR: Failure while initializing the " + "optimization algorithm for optimizing job " + name + ": " + ive.getMessage()); } // Schedule the optimizing job for execution. scheduler.scheduleOptimizingJob(optimizingJob, folderName); messages.add("Successfully scheduled optimizing job " + name + " with optimizing job ID " + optimizingJobID); // Add the optimizing job to the job hash so it can be used as a dependency // for other jobs. scheduledJobs.put(name, optimizingJob); } /** * Encodes the information in this job group optimizing job to an ASN.1 * element suitable for use in an encoded job group. * * @return The ASN.1 element containing the encoded optimizing job * information. */ public ASN1Element encode() { ArrayList<ASN1Element> elementList = new ArrayList<ASN1Element>(); elementList.add(new ASN1OctetString(ELEMENT_NAME)); elementList.add(new ASN1OctetString(name)); elementList.add(new ASN1OctetString(ELEMENT_JOB_CLASS)); elementList.add(new ASN1OctetString(jobClass.getClass().getName())); if (duration > 0) { elementList.add(new ASN1OctetString(ELEMENT_DURATION)); elementList.add(new ASN1Integer(duration)); } if (delayBetweenIterations > 0) { elementList.add(new ASN1OctetString(ELEMENT_DELAY_BETWEEN_ITERATIONS)); elementList.add(new ASN1Integer(delayBetweenIterations)); } elementList.add(new ASN1OctetString(ELEMENT_NUM_CLIENTS)); elementList.add(new ASN1Integer(numClients)); elementList.add(new ASN1OctetString(ELEMENT_MIN_THREADS)); elementList.add(new ASN1Integer(minThreads)); if (maxThreads > 0) { elementList.add(new ASN1OctetString(ELEMENT_MAX_THREADS)); elementList.add(new ASN1Integer(maxThreads)); } elementList.add(new ASN1OctetString(ELEMENT_THREAD_INCREMENT)); elementList.add(new ASN1Integer(threadIncrement)); elementList.add(new ASN1OctetString(ELEMENT_COLLECTION_INTERVAL)); elementList.add(new ASN1Integer(collectionInterval)); elementList.add(new ASN1OctetString(ELEMENT_MAX_NONIMPROVING)); elementList.add(new ASN1Integer(maxNonImproving)); if (threadStartupDelay > 0) { elementList.add(new ASN1OctetString(ELEMENT_THREAD_STARTUP_DELAY)); elementList.add(new ASN1Integer(threadStartupDelay)); } elementList.add(new ASN1OctetString(ELEMENT_RERUN_BEST_ITERATION)); elementList.add(new ASN1Boolean(reRunBestIteration)); if (reRunDuration > 0) { elementList.add(new ASN1OctetString(ELEMENT_RERUN_DURATION)); elementList.add(new ASN1Integer(reRunDuration)); } if ((dependencies != null) && (! dependencies.isEmpty())) { ArrayList<ASN1Element> depElements = new ArrayList<ASN1Element>(dependencies.size()); for (int i=0; i < dependencies.size(); i++) { depElements.add(new ASN1OctetString(dependencies.get(i))); } elementList.add(new ASN1OctetString(ELEMENT_DEPENDENCIES)); elementList.add(new ASN1Sequence(depElements)); } if (jobClass instanceof UnknownJobClass) { ASN1Element[] optimizationAlgorithmElements = new ASN1Element[] { new ASN1OctetString(optimizationAlgorithm.getClass().getName()), new ASN1Sequence() }; elementList.add(new ASN1OctetString(ELEMENT_OPTIMIZATION_ALGORITHM)); elementList.add(new ASN1Sequence(optimizationAlgorithmElements)); } else { Parameter[] optimizationParams = optimizationParameters.getParameters(); ASN1Element[] optParamsElements = new ASN1Element[optimizationParams.length]; for (int i=0; i < optimizationParams.length; i++) { ASN1Element[] optParamElements = new ASN1Element[] { new ASN1OctetString(optimizationParams[i].getName()), new ASN1OctetString(optimizationParams[i].getValueString()) }; optParamsElements[i] = new ASN1Sequence(optParamElements); } ASN1Element[] optimizationAlgorithmElements = new ASN1Element[] { new ASN1OctetString(optimizationAlgorithm.getClass().getName()), new ASN1Sequence(optParamsElements) }; elementList.add(new ASN1OctetString(ELEMENT_OPTIMIZATION_ALGORITHM)); elementList.add(new ASN1Sequence(optimizationAlgorithmElements)); } if ((mappedParameters != null) && (! mappedParameters.isEmpty())) { ArrayList<ASN1Element> paramElements = new ArrayList<ASN1Element>(); Iterator<String> iterator = mappedParameters.keySet().iterator(); while (iterator.hasNext()) { String jobName = iterator.next(); String groupName = mappedParameters.get(jobName); ASN1Element[] paramElementArray = { new ASN1OctetString(jobName), new ASN1OctetString(groupName) }; paramElements.add(new ASN1Sequence(paramElementArray)); } elementList.add(new ASN1OctetString(ELEMENT_MAPPED_PARAMS)); elementList.add(new ASN1Sequence(paramElements)); } if (fixedParameters != null) { elementList.add(new ASN1OctetString(ELEMENT_FIXED_PARAMS)); elementList.add(fixedParameters.encode()); } return new ASN1Sequence(elementList); } /** * Decodes the information in the provided element as a job group optimizing * job. * * @param slamdServer The SLAMD server instance to use in the * decoding process. * @param jobGroup The job group with which this optimizing job * is associated. * @param encodedOptimizingJob The encoded optimizing job information to * decode. * * @return The decoded job group optimizing job. * * @throws DecodeException If a problem occurs while attempting to decode * the optimizing job information. */ public static JobGroupOptimizingJob decode(SLAMDServer slamdServer, JobGroup jobGroup, ASN1Element encodedOptimizingJob) throws DecodeException { try { ArrayList<String> dependencies = new ArrayList<String>(); LinkedHashMap<String,String> mappedParameters = new LinkedHashMap<String,String>(); boolean reRunBestIteration = false; int collectionInterval = Constants.DEFAULT_COLLECTION_INTERVAL; int delayBetweenIterations = 0; int duration = -1; int maxNonImproving = 1; int maxThreads = -1; int minThreads = 1; int numClients = -1; int reRunDuration = -1; int threadIncrement = 1; int threadStartupDelay = 0; JobClass jobClass = null; OptimizationAlgorithm optimizationAlgorithm = null; ParameterList fixedParameters = new ParameterList(); ParameterList optimizationParameters = new ParameterList(); String name = null; ASN1Element[] elements = encodedOptimizingJob.decodeAsSequence().getElements(); for (int i=0; i < elements.length; i += 2) { String elementName = elements[i].decodeAsOctetString().getStringValue(); if (elementName.equals(ELEMENT_NAME)) { name = elements[i+1].decodeAsOctetString().getStringValue(); } else if (elementName.equals(ELEMENT_JOB_CLASS)) { // FIXME -- Does this need to be able to handle classes that aren't // registered? String jobClassName = elements[i+1].decodeAsOctetString().getStringValue(); jobClass = slamdServer.getJobClass(jobClassName); } else if (elementName.equals(ELEMENT_DURATION)) { duration = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_DELAY_BETWEEN_ITERATIONS)) { delayBetweenIterations = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_NUM_CLIENTS)) { numClients = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_MIN_THREADS)) { minThreads = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_MAX_THREADS)) { maxThreads = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_THREAD_INCREMENT)) { threadIncrement = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_COLLECTION_INTERVAL)) { collectionInterval = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_MAX_NONIMPROVING)) { maxNonImproving = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_THREAD_STARTUP_DELAY)) { threadStartupDelay = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_RERUN_BEST_ITERATION)) { reRunBestIteration = elements[i+1].decodeAsBoolean().getBooleanValue(); } else if (elementName.equals(ELEMENT_RERUN_DURATION)) { reRunDuration = elements[i+1].decodeAsInteger().getIntValue(); } else if (elementName.equals(ELEMENT_DEPENDENCIES)) { ASN1Element[] depElements = elements[i+1].decodeAsSequence().getElements(); for (int j=0; j < depElements.length; j++) { dependencies.add( depElements[j].decodeAsOctetString().getStringValue()); } } else if (elementName.equals(ELEMENT_OPTIMIZATION_ALGORITHM)) { if (jobClass == null) { for (int j=i+2; j < elements.length; j += 2) { String elementName2 = elements[j].decodeAsOctetString().getStringValue(); if (elementName2.equals(ELEMENT_JOB_CLASS)) { String className = elements[j+1].decodeAsOctetString().getStringValue(); jobClass = slamdServer.getOrLoadJobClass(className); break; } } } ASN1Element[] algorithmElements = elements[i+1].decodeAsSequence().getElements(); String algorithmName = algorithmElements[0].decodeAsOctetString().getStringValue(); optimizationAlgorithm = (OptimizationAlgorithm) Constants.classForName(algorithmName).newInstance(); optimizationParameters = optimizationAlgorithm. getOptimizationAlgorithmParameterStubs(jobClass).clone(); ASN1Element[] paramsElements = algorithmElements[1].decodeAsSequence().getElements(); for (int j=0; j < paramsElements.length; j++) { ASN1Element[] paramElements = paramsElements[j].decodeAsSequence().getElements(); String paramName = paramElements[0].decodeAsOctetString().getStringValue(); String paramValue = paramElements[1].decodeAsOctetString().getStringValue(); Parameter p = optimizationParameters.getParameter(paramName); if (p != null) { p.setValueFromString(paramValue); } } } else if (elementName.equals(ELEMENT_MAPPED_PARAMS)) { ASN1Element[] paramElements = elements[i+1].decodeAsSequence().getElements(); for (int j=0; j < paramElements.length; j++) { ASN1Element[] pElements = paramElements[j].decodeAsSequence().getElements(); mappedParameters.put( pElements[0].decodeAsOctetString().getStringValue(), pElements[1].decodeAsOctetString().getStringValue()); } } else if (elementName.equals(ELEMENT_FIXED_PARAMS)) { fixedParameters = ParameterList.decode(elements[i+1]); } } return new JobGroupOptimizingJob(name, jobGroup, jobClass, duration, delayBetweenIterations, numClients, minThreads, maxThreads, threadIncrement, collectionInterval, maxNonImproving, threadStartupDelay, reRunBestIteration, reRunDuration, dependencies, optimizationAlgorithm, optimizationParameters, mappedParameters, fixedParameters); } catch (Exception e) { throw new DecodeException("Unable to decode the job group optimizing " + "job: " + e, e); } } }