|
@@ -0,0 +1,572 @@
|
|
|
|
+/**
|
|
|
|
+ * 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.fs.slive;
|
|
|
|
+
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+import org.apache.hadoop.conf.Configuration;
|
|
|
|
+import org.apache.hadoop.fs.Path;
|
|
|
|
+import org.apache.hadoop.fs.slive.ArgumentParser.ParsedOutput;
|
|
|
|
+import org.apache.hadoop.fs.slive.Constants.Distribution;
|
|
|
|
+import org.apache.hadoop.fs.slive.Constants.OperationType;
|
|
|
|
+import org.apache.hadoop.util.StringUtils;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Class which merges options given from a config file and the command line and
|
|
|
|
+ * performs some basic verification of the data retrieved and sets the verified
|
|
|
|
+ * values back into the configuration object for return
|
|
|
|
+ */
|
|
|
|
+class ConfigMerger {
|
|
|
|
+ /**
|
|
|
|
+ * Exception that represents config problems...
|
|
|
|
+ */
|
|
|
|
+ static class ConfigException extends IOException {
|
|
|
|
+
|
|
|
|
+ private static final long serialVersionUID = 2047129184917444550L;
|
|
|
|
+
|
|
|
|
+ ConfigException(String msg) {
|
|
|
|
+ super(msg);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ConfigException(String msg, Throwable e) {
|
|
|
|
+ super(msg, e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Merges the given command line parsed output with the given configuration
|
|
|
|
+ * object and returns the new configuration object with the correct options
|
|
|
|
+ * overwritten
|
|
|
|
+ *
|
|
|
|
+ * @param opts
|
|
|
|
+ * the parsed command line option output
|
|
|
|
+ * @param base
|
|
|
|
+ * the base configuration to merge with
|
|
|
|
+ * @return merged configuration object
|
|
|
|
+ * @throws ConfigException
|
|
|
|
+ * when configuration errors or verification occur
|
|
|
|
+ */
|
|
|
|
+ Configuration getMerged(ParsedOutput opts, Configuration base)
|
|
|
|
+ throws ConfigException {
|
|
|
|
+ return handleOptions(opts, base);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Gets the base set of operations to use
|
|
|
|
+ *
|
|
|
|
+ * @return Map
|
|
|
|
+ */
|
|
|
|
+ private Map<OperationType, OperationData> getBaseOperations() {
|
|
|
|
+ Map<OperationType, OperationData> base = new HashMap<OperationType, OperationData>();
|
|
|
|
+ // add in all the operations
|
|
|
|
+ // since they will all be applied unless changed
|
|
|
|
+ OperationType[] types = OperationType.values();
|
|
|
|
+ for (OperationType type : types) {
|
|
|
|
+ base.put(type, new OperationData(Distribution.UNIFORM, null));
|
|
|
|
+ }
|
|
|
|
+ return base;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Handles the specific task of merging operations from the command line or
|
|
|
|
+ * extractor object into the base configuration provided
|
|
|
|
+ *
|
|
|
|
+ * @param opts
|
|
|
|
+ * the parsed command line option output
|
|
|
|
+ * @param base
|
|
|
|
+ * the base configuration to merge with
|
|
|
|
+ * @param extractor
|
|
|
|
+ * the access object to fetch operations from if none from the
|
|
|
|
+ * command line
|
|
|
|
+ * @return merged configuration object
|
|
|
|
+ * @throws ConfigException
|
|
|
|
+ * when verification fails
|
|
|
|
+ */
|
|
|
|
+ private Configuration handleOperations(ParsedOutput opts, Configuration base,
|
|
|
|
+ ConfigExtractor extractor) throws ConfigException {
|
|
|
|
+ // get the base set to start off with
|
|
|
|
+ Map<OperationType, OperationData> operations = getBaseOperations();
|
|
|
|
+ // merge with what is coming from config
|
|
|
|
+ Map<OperationType, OperationData> cfgOperations = extractor.getOperations();
|
|
|
|
+ for (OperationType opType : cfgOperations.keySet()) {
|
|
|
|
+ operations.put(opType, cfgOperations.get(opType));
|
|
|
|
+ }
|
|
|
|
+ // see if any coming in from the command line
|
|
|
|
+ for (OperationType opType : OperationType.values()) {
|
|
|
|
+ String opName = opType.lowerName();
|
|
|
|
+ String opVal = opts.getValue(opName);
|
|
|
|
+ if (opVal != null) {
|
|
|
|
+ operations.put(opType, new OperationData(opVal));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // remove those with <= zero percent
|
|
|
|
+ {
|
|
|
|
+ Map<OperationType, OperationData> cleanedOps = new HashMap<OperationType, OperationData>();
|
|
|
|
+ for (OperationType opType : operations.keySet()) {
|
|
|
|
+ OperationData data = operations.get(opType);
|
|
|
|
+ if (data.getPercent() == null || data.getPercent() > 0.0d) {
|
|
|
|
+ cleanedOps.put(opType, data);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ operations = cleanedOps;
|
|
|
|
+ }
|
|
|
|
+ if (operations.isEmpty()) {
|
|
|
|
+ throw new ConfigException("No operations provided!");
|
|
|
|
+ }
|
|
|
|
+ // verify and adjust
|
|
|
|
+ double currPct = 0;
|
|
|
|
+ int needFill = 0;
|
|
|
|
+ for (OperationType type : operations.keySet()) {
|
|
|
|
+ OperationData op = operations.get(type);
|
|
|
|
+ if (op.getPercent() != null) {
|
|
|
|
+ currPct += op.getPercent();
|
|
|
|
+ } else {
|
|
|
|
+ needFill++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (currPct > 1) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Unable to have accumlative percent greater than 100%");
|
|
|
|
+ }
|
|
|
|
+ if (needFill > 0 && currPct < 1) {
|
|
|
|
+ double leftOver = 1.0 - currPct;
|
|
|
|
+ Map<OperationType, OperationData> mpcp = new HashMap<OperationType, OperationData>();
|
|
|
|
+ for (OperationType type : operations.keySet()) {
|
|
|
|
+ OperationData op = operations.get(type);
|
|
|
|
+ if (op.getPercent() == null) {
|
|
|
|
+ op = new OperationData(op.getDistribution(), (leftOver / needFill));
|
|
|
|
+ }
|
|
|
|
+ mpcp.put(type, op);
|
|
|
|
+ }
|
|
|
|
+ operations = mpcp;
|
|
|
|
+ } else if (needFill == 0 && currPct < 1) {
|
|
|
|
+ // redistribute
|
|
|
|
+ double leftOver = 1.0 - currPct;
|
|
|
|
+ Map<OperationType, OperationData> mpcp = new HashMap<OperationType, OperationData>();
|
|
|
|
+ double each = leftOver / operations.keySet().size();
|
|
|
|
+ for (OperationType t : operations.keySet()) {
|
|
|
|
+ OperationData op = operations.get(t);
|
|
|
|
+ op = new OperationData(op.getDistribution(), (op.getPercent() + each));
|
|
|
|
+ mpcp.put(t, op);
|
|
|
|
+ }
|
|
|
|
+ operations = mpcp;
|
|
|
|
+ } else if (needFill > 0 && currPct >= 1) {
|
|
|
|
+ throw new ConfigException(needFill
|
|
|
|
+ + " unfilled operations but no percentage left to fill with");
|
|
|
|
+ }
|
|
|
|
+ // save into base
|
|
|
|
+ for (OperationType opType : operations.keySet()) {
|
|
|
|
+ String opName = opType.lowerName();
|
|
|
|
+ OperationData opData = operations.get(opType);
|
|
|
|
+ String distr = opData.getDistribution().lowerName();
|
|
|
|
+ String ratio = new Double(opData.getPercent() * 100.0d).toString();
|
|
|
|
+ base.set(String.format(Constants.OP, opName), opData.toString());
|
|
|
|
+ base.set(String.format(Constants.OP_DISTR, opName), distr);
|
|
|
|
+ base.set(String.format(Constants.OP_PERCENT, opName), ratio);
|
|
|
|
+ }
|
|
|
|
+ return base;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Handles merging all options and verifying from the given command line
|
|
|
|
+ * output and the given base configuration and returns the merged
|
|
|
|
+ * configuration
|
|
|
|
+ *
|
|
|
|
+ * @param opts
|
|
|
|
+ * the parsed command line option output
|
|
|
|
+ * @param base
|
|
|
|
+ * the base configuration to merge with
|
|
|
|
+ * @return the merged configuration
|
|
|
|
+ * @throws ConfigException
|
|
|
|
+ */
|
|
|
|
+ private Configuration handleOptions(ParsedOutput opts, Configuration base)
|
|
|
|
+ throws ConfigException {
|
|
|
|
+ // ensure variables are overwritten and verified
|
|
|
|
+ ConfigExtractor extractor = new ConfigExtractor(base);
|
|
|
|
+ // overwrite the map amount and check to ensure > 0
|
|
|
|
+ {
|
|
|
|
+ Integer mapAmount = null;
|
|
|
|
+ try {
|
|
|
|
+ mapAmount = extractor.getMapAmount(opts.getValue(ConfigOption.MAPS
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException("Error extracting & merging map amount", e);
|
|
|
|
+ }
|
|
|
|
+ if (mapAmount != null) {
|
|
|
|
+ if (mapAmount <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Map amount can not be less than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.MAPS.getCfgOption(), mapAmount.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // overwrite the reducer amount and check to ensure > 0
|
|
|
|
+ {
|
|
|
|
+ Integer reduceAmount = null;
|
|
|
|
+ try {
|
|
|
|
+ reduceAmount = extractor.getMapAmount(opts.getValue(ConfigOption.REDUCES
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging reducer amount", e);
|
|
|
|
+ }
|
|
|
|
+ if (reduceAmount != null) {
|
|
|
|
+ if (reduceAmount <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Reducer amount can not be less than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.REDUCES.getCfgOption(), reduceAmount.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // overwrite the duration amount and ensure > 0
|
|
|
|
+ {
|
|
|
|
+ Integer duration = null;
|
|
|
|
+ try {
|
|
|
|
+ duration = extractor.getDuration(opts.getValue(ConfigOption.DURATION
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException("Error extracting & merging duration", e);
|
|
|
|
+ }
|
|
|
|
+ if (duration != null) {
|
|
|
|
+ if (duration <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Duration can not be less than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.DURATION.getCfgOption(), duration.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // overwrite the operation amount and ensure > 0
|
|
|
|
+ {
|
|
|
|
+ Integer operationAmount = null;
|
|
|
|
+ try {
|
|
|
|
+ operationAmount = extractor.getOpCount(opts.getValue(ConfigOption.OPS
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging operation amount", e);
|
|
|
|
+ }
|
|
|
|
+ if (operationAmount != null) {
|
|
|
|
+ if (operationAmount <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Operation amount can not be less than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.OPS.getCfgOption(), operationAmount.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // overwrite the exit on error setting
|
|
|
|
+ {
|
|
|
|
+ try {
|
|
|
|
+ boolean exitOnError = extractor.shouldExitOnFirstError(opts
|
|
|
|
+ .getValue(ConfigOption.EXIT_ON_ERROR.getOpt()));
|
|
|
|
+ base.setBoolean(ConfigOption.EXIT_ON_ERROR.getCfgOption(), exitOnError);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging exit on error value", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // verify and set file limit and ensure > 0
|
|
|
|
+ {
|
|
|
|
+ Integer fileAm = null;
|
|
|
|
+ try {
|
|
|
|
+ fileAm = extractor.getTotalFiles(opts.getValue(ConfigOption.FILES
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging total file limit amount", e);
|
|
|
|
+ }
|
|
|
|
+ if (fileAm != null) {
|
|
|
|
+ if (fileAm <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "File amount can not be less than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.FILES.getCfgOption(), fileAm.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the grid queue to run on
|
|
|
|
+ {
|
|
|
|
+ try {
|
|
|
|
+ String qname = extractor.getQueueName(opts
|
|
|
|
+ .getValue(ConfigOption.QUEUE_NAME.getOpt()));
|
|
|
|
+ if (qname != null) {
|
|
|
|
+ base.set(ConfigOption.QUEUE_NAME.getCfgOption(), qname);
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException("Error extracting & merging queue name", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // verify and set the directory limit and ensure > 0
|
|
|
|
+ {
|
|
|
|
+ Integer directoryLimit = null;
|
|
|
|
+ try {
|
|
|
|
+ directoryLimit = extractor.getDirSize(opts
|
|
|
|
+ .getValue(ConfigOption.DIR_SIZE.getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging directory file limit", e);
|
|
|
|
+ }
|
|
|
|
+ if (directoryLimit != null) {
|
|
|
|
+ if (directoryLimit <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Directory file limit can not be less than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.DIR_SIZE.getCfgOption(), directoryLimit
|
|
|
|
+ .toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the base directory
|
|
|
|
+ {
|
|
|
|
+ Path basedir = null;
|
|
|
|
+ try {
|
|
|
|
+ basedir = extractor.getBaseDirectory(opts
|
|
|
|
+ .getValue(ConfigOption.BASE_DIR.getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException("Error extracting & merging base directory",
|
|
|
|
+ e);
|
|
|
|
+ }
|
|
|
|
+ if (basedir != null) {
|
|
|
|
+ // always ensure in slive dir
|
|
|
|
+ basedir = new Path(basedir, Constants.BASE_DIR);
|
|
|
|
+ base.set(ConfigOption.BASE_DIR.getCfgOption(), basedir.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the result file
|
|
|
|
+ {
|
|
|
|
+ String fn = null;
|
|
|
|
+ try {
|
|
|
|
+ fn = extractor.getResultFile(opts.getValue(ConfigOption.RESULT_FILE
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException("Error extracting & merging result file", e);
|
|
|
|
+ }
|
|
|
|
+ if (fn != null) {
|
|
|
|
+ base.set(ConfigOption.RESULT_FILE.getCfgOption(), fn);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ {
|
|
|
|
+ String fn = null;
|
|
|
|
+ try {
|
|
|
|
+ fn = extractor.getResultFile(opts.getValue(ConfigOption.RESULT_FILE
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException("Error extracting & merging result file", e);
|
|
|
|
+ }
|
|
|
|
+ if (fn != null) {
|
|
|
|
+ base.set(ConfigOption.RESULT_FILE.getCfgOption(), fn);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the operations
|
|
|
|
+ {
|
|
|
|
+ try {
|
|
|
|
+ base = handleOperations(opts, base, extractor);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException("Error extracting & merging operations", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the replication amount range
|
|
|
|
+ {
|
|
|
|
+ Range<Short> replicationAm = null;
|
|
|
|
+ try {
|
|
|
|
+ replicationAm = extractor.getReplication(opts
|
|
|
|
+ .getValue(ConfigOption.REPLICATION_AM.getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging replication amount range", e);
|
|
|
|
+ }
|
|
|
|
+ if (replicationAm != null) {
|
|
|
|
+ int minRepl = base.getInt(Constants.MIN_REPLICATION, 1);
|
|
|
|
+ if (replicationAm.getLower() < minRepl) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Replication amount minimum is less than property configured minimum "
|
|
|
|
+ + minRepl);
|
|
|
|
+ }
|
|
|
|
+ if (replicationAm.getLower() > replicationAm.getUpper()) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Replication amount minimum is greater than its maximum");
|
|
|
|
+ }
|
|
|
|
+ if (replicationAm.getLower() <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Replication amount minimum must be greater than zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.REPLICATION_AM.getCfgOption(), replicationAm
|
|
|
|
+ .toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the sleep range
|
|
|
|
+ {
|
|
|
|
+ Range<Long> sleepRange = null;
|
|
|
|
+ try {
|
|
|
|
+ sleepRange = extractor.getSleepRange(opts
|
|
|
|
+ .getValue(ConfigOption.SLEEP_TIME.getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging sleep size range", e);
|
|
|
|
+ }
|
|
|
|
+ if (sleepRange != null) {
|
|
|
|
+ if (sleepRange.getLower() > sleepRange.getUpper()) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Sleep range minimum is greater than its maximum");
|
|
|
|
+ }
|
|
|
|
+ if (sleepRange.getLower() <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Sleep range minimum must be greater than zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.SLEEP_TIME.getCfgOption(), sleepRange.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the packet size if given
|
|
|
|
+ {
|
|
|
|
+ String pSize = opts.getValue(ConfigOption.PACKET_SIZE.getOpt());
|
|
|
|
+ if (pSize == null) {
|
|
|
|
+ pSize = ConfigOption.PACKET_SIZE.getDefault();
|
|
|
|
+ }
|
|
|
|
+ if (pSize != null) {
|
|
|
|
+ try {
|
|
|
|
+ Long packetSize = StringUtils.TraditionalBinaryPrefix
|
|
|
|
+ .string2long(pSize);
|
|
|
|
+ base.set(ConfigOption.PACKET_SIZE.getCfgOption(), packetSize
|
|
|
|
+ .toString());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging write packet size", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the block size range
|
|
|
|
+ {
|
|
|
|
+ Range<Long> blockSize = null;
|
|
|
|
+ try {
|
|
|
|
+ blockSize = extractor.getBlockSize(opts
|
|
|
|
+ .getValue(ConfigOption.BLOCK_SIZE.getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging block size range", e);
|
|
|
|
+ }
|
|
|
|
+ if (blockSize != null) {
|
|
|
|
+ if (blockSize.getLower() > blockSize.getUpper()) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Block size minimum is greater than its maximum");
|
|
|
|
+ }
|
|
|
|
+ if (blockSize.getLower() <= 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Block size minimum must be greater than zero");
|
|
|
|
+ }
|
|
|
|
+ // ensure block size is a multiple of BYTES_PER_CHECKSUM
|
|
|
|
+ // if a value is set in the configuration
|
|
|
|
+ Long bytesPerChecksum = extractor.getByteCheckSum();
|
|
|
|
+ if (bytesPerChecksum != null) {
|
|
|
|
+ if ((blockSize.getLower() % bytesPerChecksum) != 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Blocksize lower bound must be a multiple of "
|
|
|
|
+ + bytesPerChecksum);
|
|
|
|
+ }
|
|
|
|
+ if ((blockSize.getUpper() % bytesPerChecksum) != 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Blocksize upper bound must be a multiple of "
|
|
|
|
+ + bytesPerChecksum);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.BLOCK_SIZE.getCfgOption(), blockSize.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the read size range
|
|
|
|
+ {
|
|
|
|
+ Range<Long> readSize = null;
|
|
|
|
+ try {
|
|
|
|
+ readSize = extractor.getReadSize(opts.getValue(ConfigOption.READ_SIZE
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException("Error extracting & merging read size range",
|
|
|
|
+ e);
|
|
|
|
+ }
|
|
|
|
+ if (readSize != null) {
|
|
|
|
+ if (readSize.getLower() > readSize.getUpper()) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Read size minimum is greater than its maximum");
|
|
|
|
+ }
|
|
|
|
+ if (readSize.getLower() < 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Read size minimum must be greater than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.READ_SIZE.getCfgOption(), readSize.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the write size range
|
|
|
|
+ {
|
|
|
|
+ Range<Long> writeSize = null;
|
|
|
|
+ try {
|
|
|
|
+ writeSize = extractor.getWriteSize(opts
|
|
|
|
+ .getValue(ConfigOption.WRITE_SIZE.getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging write size range", e);
|
|
|
|
+ }
|
|
|
|
+ if (writeSize != null) {
|
|
|
|
+ if (writeSize.getLower() > writeSize.getUpper()) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Write size minimum is greater than its maximum");
|
|
|
|
+ }
|
|
|
|
+ if (writeSize.getLower() < 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Write size minimum must be greater than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base.set(ConfigOption.WRITE_SIZE.getCfgOption(), writeSize.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the append size range
|
|
|
|
+ {
|
|
|
|
+ Range<Long> appendSize = null;
|
|
|
|
+ try {
|
|
|
|
+ appendSize = extractor.getAppendSize(opts
|
|
|
|
+ .getValue(ConfigOption.APPEND_SIZE.getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging append size range", e);
|
|
|
|
+ }
|
|
|
|
+ if (appendSize != null) {
|
|
|
|
+ if (appendSize.getLower() > appendSize.getUpper()) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Append size minimum is greater than its maximum");
|
|
|
|
+ }
|
|
|
|
+ if (appendSize.getLower() < 0) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Append size minimum must be greater than or equal to zero");
|
|
|
|
+ }
|
|
|
|
+ base
|
|
|
|
+ .set(ConfigOption.APPEND_SIZE.getCfgOption(), appendSize.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // set the seed
|
|
|
|
+ {
|
|
|
|
+ Long seed = null;
|
|
|
|
+ try {
|
|
|
|
+ seed = extractor.getRandomSeed(opts.getValue(ConfigOption.RANDOM_SEED
|
|
|
|
+ .getOpt()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ConfigException(
|
|
|
|
+ "Error extracting & merging random number seed", e);
|
|
|
|
+ }
|
|
|
|
+ if (seed != null) {
|
|
|
|
+ base.set(ConfigOption.RANDOM_SEED.getCfgOption(), seed.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return base;
|
|
|
|
+ }
|
|
|
|
+}
|