/// <summary> /// Selects an operation from the known operation set or returns null if none /// are available by applying the weighting algorithms and then handing off the /// weight operations to the selection object. /// </summary> /// <param name="elapsed">the currently elapsed time (milliseconds) of the running program /// </param> /// <param name="duration">the maximum amount of milliseconds of the running program</param> /// <returns>operation or null if none left</returns> internal virtual Operation Select(int elapsed, int duration) { IList <OperationWeight> validOps = new AList <OperationWeight>(operations.Count); foreach (Constants.OperationType type in operations.Keys) { WeightSelector.OperationInfo opinfo = operations[type]; if (opinfo == null || opinfo.amountLeft <= 0) { continue; } WeightSelector.Weightable weighter = weights[opinfo.distribution]; if (weighter != null) { OperationWeight weightOp = new OperationWeight(opinfo.operation, weighter.Weight( elapsed, duration)); validOps.AddItem(weightOp); } else { throw new RuntimeException("Unable to get weight for distribution " + opinfo.distribution ); } } if (validOps.IsEmpty()) { return(null); } return(GetSelector().Select(validOps)); }
/// <summary> /// Sets up the operation using the given configuration by setting up the /// number of operations to perform (and how many are left) and setting up the /// operation objects to be used throughout selection. /// </summary> /// <param name="cfg">ConfigExtractor.</param> private void ConfigureOperations(ConfigExtractor cfg) { operations = new SortedDictionary <Constants.OperationType, WeightSelector.OperationInfo >(); IDictionary <Constants.OperationType, OperationData> opinfo = cfg.GetOperations(); int totalAm = cfg.GetOpCount(); int opsLeft = totalAm; NumberFormat formatter = Formatter.GetPercentFormatter(); foreach (Constants.OperationType type in opinfo.Keys) { OperationData opData = opinfo[type]; WeightSelector.OperationInfo info = new WeightSelector.OperationInfo(); info.distribution = opData.GetDistribution(); int amLeft = DetermineHowMany(totalAm, opData, type); opsLeft -= amLeft; Log.Info(type.ToString() + " has " + amLeft + " initial operations out of " + totalAm + " for its ratio " + formatter.Format(opData.GetPercent())); info.amountLeft = amLeft; Operation op = factory.GetOperation(type); // wrap operation in finalizer so that amount left gets decrements when // its done if (op != null) { ObserveableOp.Observer fn = new _Observer_138(this, type); info.operation = new ObserveableOp(op, fn); operations[type] = info; } } if (opsLeft > 0) { Log.Info(opsLeft + " left over operations found (due to inability to support partial operations)" ); } }
public void NotifyFinished(Operation op) { WeightSelector.OperationInfo opInfo = this._enclosing.operations[type]; if (opInfo != null) { --opInfo.amountLeft; } }