/// <summary> /// Returns the of list of non function properties (nfps) measured for the configurations of the given file. To tune up performance, /// we consider only the first configurtion of the file and assume that all configurations have the same nfps. /// </summary> /// <param name="file">The xml file consisting of configurations.</param> /// <returns>The list of nfps the configurations have measurements.</returns> public static List <NFProperty> propertiesOfConfigurations(string file) { List <NFProperty> properties = new List <NFProperty>(); XmlDocument dat = new System.Xml.XmlDocument(); dat.Load(file); XmlElement currentElemt = dat.DocumentElement; XmlNode node = currentElemt.ChildNodes[0]; foreach (XmlNode childNode in node.ChildNodes) { switch (childNode.Attributes[0].Value) { case "Configuration": break; case "Variable Features": break; case "BinaryOptions": break; case "NumericOptions": break; default: NFProperty property = new NFProperty(childNode.Attributes[0].Value); properties.Add(property); break; } } return(properties); }
/// <summary> /// This method returns the configuration specific value of the property. /// </summary> /// <param name="property">A non functional property.</param> /// <returns>The value of the property stored in the configuration.</returns> public double GetNFPValue(NFProperty property) { if (!nfpValues.Keys.Contains(property)) { return(-1); } return(nfpValues[property]); }
/// <summary> /// Clears the global state. This mehtod should be used after performing all experiments of one case study. /// </summary> public static void clear() { varModel = null; currentNFP = null; allMeasurements = new ResultDB(); evalutionSet = new ResultDB(); infModel = null; nfProperties = new Dictionary <string, NFProperty>(); }
/// <summary> /// Clears the global state. This mehtod should be used after performing all experiments of one case study. /// </summary> public static void clear() { varModel = null; currentNFP = null; allMeasurements = new ResultDB(); evaluationSet = new ResultDB(); nfProperties = new Dictionary <string, NFProperty>(); optionOrder = new List <ConfigurationOption>(); }
/// <summary> /// The mehtod returns non function property with the given name. If there is no property with the name, a new property is created. /// </summary> /// <param name="name">Name of the property</param> /// <returns>A non functional property with the specified name.</returns> public static NFProperty getOrCreateProperty(string name) { if (nfProperties.Keys.Contains(name)) { return(nfProperties[name]); } else { NFProperty newProp = new NFProperty(name); nfProperties.Add(name, newProp); return(newProp); } }
/// <summary> /// Desines a measured value for a non-functional property. /// </summary> /// <param name="prop">The non-functional property the measuremed value is defined for.</param> /// <param name="val">The value for the non-functional property.</param> public void setMeasuredValue(NFProperty prop, double val) { if (prop == null) { return; } if (this.nfpValues.Keys.Contains(prop)) { this.nfpValues[prop] = val; } else { this.nfpValues.Add(prop, val); } }
/// <summary> /// This method returns a list of all configurations stored in a given file. All options of the configurations have to be defined in the variability model. /// </summary> /// <param name="dat">Object representing the configuration file.</param> /// <param name="varModel">Variability model of the configurations.</param> /// <returns>Returns a list of configurations that were defined in the XML document. Can be an empty list.</returns> public static List <Configuration> readConfigurations(XmlDocument dat, VariabilityModel varModel) { XmlElement currentElemt = dat.DocumentElement; parseHeaderOfDocument(currentElemt); HashSet <Configuration> configurations = new HashSet <Configuration>(); int configsWithTooLargeDeviation = 0; foreach (XmlNode nodeOfOneConfiguration in currentElemt.ChildNodes) { bool readMultipleMeasurements = false; if (nodeOfOneConfiguration.Attributes.Count > 0 && nodeOfOneConfiguration.Attributes[0].Value.ToLower() == "true") { readMultipleMeasurements = true; } Dictionary <NFProperty, double> propertiesForConfig = new Dictionary <NFProperty, double>();; bool alternativeFormat = false; string binaryString = ""; string numericString = ""; string configID = ""; Dictionary <NFProperty, double> measuredProperty = new Dictionary <NFProperty, double>(); Configuration c = null; bool hasSetConfig = false; foreach (XmlNode childNode in nodeOfOneConfiguration.ChildNodes) { if (c == null && hasSetConfig) { continue; } switch (childNode.Attributes[0].Value) { // TODO we use this to support result files having the old structure case "BinaryOptions": case "Configuration": binaryString = childNode.InnerText; break; case "NumericOptions": case "Variable Features": numericString = childNode.InnerText; break; case "ConfigID": if (readMultipleMeasurements) { configID = childNode.InnerText.Replace("_", "%;%"); } else { configID = childNode.InnerText; } if (configID.Contains("%;%seek") && configID.Contains("%;%seek0") == false) { hasSetConfig = true; c = null; break; } alternativeFormat = true; c = Configuration.createFromHashString(configID, GlobalState.varModel); hasSetConfig = true; break; default: NFProperty property = GlobalState.getOrCreateProperty(childNode.Attributes[0].Value); double measuredValue = 0; //-1 means that measurement failed... 3rd values strongly devigates in C.'s measurements, hence we use it only in case we have no other measurements if (readMultipleMeasurements) { //if (property.Name != "run-real") // continue; String[] m = childNode.InnerText.ToString().Split(separator); double val1 = 0; if (!Double.TryParse(m[0], out val1)) { break; } if (m.Length > 1) { List <double> values = new List <double>(); double avg = 0; foreach (var i in m) { double d = double.Parse(i.Replace(decimalDelimiter, '.'), System.Globalization.CultureInfo.InvariantCulture); if (d != -1) { values.Add(d); avg += d; } } if (values.Count == 0) { configsWithTooLargeDeviation++; c = null; break; } avg = avg / values.Count; /* foreach (var d in values) * { * if ((d / avg) * 100 > 10) * { * configsWithTooLargeDeviation++; * c = null; * break; * } * }*/ measuredValue = avg; /*double val2 = Convert.ToDouble(m[1]); * if (val1 == -1) * measuredValue = val2; * else if (val1 == -1 && val2 == -1) * measuredValue = Convert.ToDouble(m[2]); * else if (val2 == -1) * measuredValue = val1; * else * measuredValue = (val1 + val2) / 2;*/ } else { measuredValue = val1; } } else { measuredValue = double.Parse(childNode.InnerText.ToString().Replace(decimalDelimiter, '.'), System.Globalization.CultureInfo.InvariantCulture); } // TODO how to handle configurations with negative nfps? if (measuredValue < 0) { goto nextConfig; } // Save the largest measured value. double currentMaxMeasuredValue; if (GlobalState.allMeasurements.maxMeasuredValue.TryGetValue(property, out currentMaxMeasuredValue)) { if (Math.Abs(measuredValue) > Math.Abs(currentMaxMeasuredValue)) { GlobalState.allMeasurements.maxMeasuredValue[property] = measuredValue; } } else { GlobalState.allMeasurements.maxMeasuredValue.Add(property, measuredValue); } // Add measured value to the configuration. if (alternativeFormat && c != null) { c.setMeasuredValue(property, measuredValue); } else { measuredProperty.Add(property, measuredValue); } break; } } if (alternativeFormat && c != null) { if (configurations.Contains(c)) { GlobalState.logError.logLine("Mutiple definition of one configuration in the configurations file: " + c.ToString()); } else { // if (GlobalState.currentNFP != null && c.nfpValues.Keys.Contains(GlobalState.currentNFP) && c.nfpValues[GlobalState.currentNFP] != -1) configurations.Add(c); } continue; } // indicates if this configuration is valid in the current feature model bool valid = true; // parse the binary options string Dictionary <BinaryOption, BinaryOption.BinaryValue> binaryOptions = new Dictionary <BinaryOption, BinaryOption.BinaryValue>(); valid &= parseBinaryOptionString(binaryString, out binaryOptions, varModel); // parse the numeric options string Dictionary <NumericOption, double> numericOptions = new Dictionary <NumericOption, double>(); valid &= parseNumericOptionString(numericString, out numericOptions, varModel); // Add "root" binary option to the configuration if (!binaryOptions.ContainsKey(varModel.Root)) { binaryOptions.Add(varModel.Root, BinaryOption.BinaryValue.Selected); } if (valid) { Configuration config = new Configuration(binaryOptions, numericOptions, measuredProperty); configurations.Add(config); } else { GlobalState.logError.logLine("Invalid configuration:" + binaryString + numericString); } nextConfig : { } } GlobalState.logInfo.logLine("Configs with too large deviation: " + configsWithTooLargeDeviation); return(configurations.ToList()); }
/// <summary> /// This method reads all configurations specified in the .csv file. In this mehtod, we assume that the file has a header. /// </summary> /// <param name="file"></param> /// <param name="model">The variabiliy model for the configurations.</param> /// <returns>A list of all configurations </returns> public static List <Configuration> readConfigurations_Header_CSV(String file, VariabilityModel model) { List <Configuration> configurations = new List <Configuration>(); StreamReader sr = new StreamReader(file); String[] optionOrder = new String[model.getOptions().Count]; String[] nfpOrder = null; bool isHeader = true; while (!sr.EndOfStream) { String[] tokens = sr.ReadLine().Split(';'); if (isHeader) { nfpOrder = new String[tokens.Length - optionOrder.Length]; for (int i = 0; i < tokens.Length; i++) { String token = tokens[i]; if (i < optionOrder.Length) { optionOrder[i] = token; } else { nfpOrder[i - optionOrder.Length] = token; if (!GlobalState.nfProperties.ContainsKey(token)) { GlobalState.nfProperties.Add(token, new NFProperty(token)); } } } isHeader = false; } else { Dictionary <BinaryOption, BinaryOption.BinaryValue> binOptions = new Dictionary <BinaryOption, BinaryOption.BinaryValue>(); Dictionary <NumericOption, double> numOptions = new Dictionary <NumericOption, double>(); Dictionary <NFProperty, double> properties = new Dictionary <NFProperty, double>(); for (int i = 0; i < tokens.Length; i++) { String token = tokens[i]; if (i < optionOrder.Length) { ConfigurationOption option = model.getOption(optionOrder[i]); if (option.GetType() == typeof(BinaryOption)) { if (token.Equals("true") || token.Equals("1")) { binOptions.Add((BinaryOption)option, BinaryOption.BinaryValue.Selected); } } else { double value = Convert.ToDouble(token); numOptions.Add((NumericOption)option, value); } } else { NFProperty nfp = GlobalState.nfProperties[nfpOrder[i - optionOrder.Length]]; double value = Convert.ToDouble(token); properties.Add(nfp, value); double currentMaxMeasuredValue; if (GlobalState.allMeasurements.maxMeasuredValue.TryGetValue(nfp, out currentMaxMeasuredValue)) { if (Math.Abs(value) > Math.Abs(currentMaxMeasuredValue)) { GlobalState.allMeasurements.maxMeasuredValue[nfp] = value; } } else { GlobalState.allMeasurements.maxMeasuredValue.Add(nfp, value); } } } Configuration config = new Configuration(binOptions, numOptions, properties); configurations.Add(config); } } sr.Close(); return(configurations); }
/// <summary> /// This method returns a list of all configurations stored in a given file. All options of the configurations have to be defined in the variability model. /// </summary> /// <param name="dat">Object representing the configuration file.</param> /// <param name="model">Variability model of the configurations.</param> /// <returns>Returns a list of configurations that were defined in the XML document. Can be an empty list.</returns> public static List <Configuration> readConfigurations(XmlDocument dat, VariabilityModel model) { XmlElement currentElemt = dat.DocumentElement; HashSet <Configuration> configurations = new HashSet <Configuration>(); int numberOfConfigs = currentElemt.ChildNodes.Count; int configsWithTooLargeDeviation = 0; foreach (XmlNode node in currentElemt.ChildNodes) { bool readMultipleMeasurements = false; if (node.Attributes.Count > 0 && node.Attributes[0].Value.ToLower() == "true") { readMultipleMeasurements = true; } Dictionary <NFProperty, double> propertiesForConfig = new Dictionary <NFProperty, double>();; bool alternativeFormat = false; string binaryString = ""; string numericString = ""; string configID = ""; Dictionary <NFProperty, double> measuredProperty = new Dictionary <NFProperty, double>(); Configuration c = null; bool hasSetConfig = false; foreach (XmlNode childNode in node.ChildNodes) { if (c == null && hasSetConfig) { continue; } switch (childNode.Attributes[0].Value) { // TODO we use this to support result files having the old structure case "Configuration": binaryString = childNode.InnerText; break; case "Variable Features": numericString = childNode.InnerText; break; case "BinaryOptions": binaryString = childNode.InnerText; break; case "NumericOptions": numericString = childNode.InnerText; break; case "ConfigID": if (readMultipleMeasurements) { configID = childNode.InnerText.Replace("_", "%;%"); } else { configID = childNode.InnerText; } if (configID.Contains("%;%seek") && configID.Contains("%;%seek0") == false) { hasSetConfig = true; c = null; break; } alternativeFormat = true; c = Configuration.createFromHashString(configID, GlobalState.varModel); hasSetConfig = true; break; case "CompilerOptions": //todo break; case "ConfigFileOptions": //todo break; case "ParameterOptions": //todo break; case "ProgramName": //todo break; case "StartupBegin": //todo break; case "StartupEnd": //todo break; default: NFProperty property = GlobalState.getOrCreateProperty(childNode.Attributes[0].Value); double measuredValue = 0; //-1 means that measurement failed... 3rd values strongly devigates in C.'s measurements, hence we use it only in case we have no other measurements if (readMultipleMeasurements) { if (property.Name != "run-real") { continue; } String[] m = childNode.InnerText.ToString().Split(','); double val1 = 0; if (!Double.TryParse(m[0], out val1)) { break; } if (m.Length > 1) { List <double> values = new List <double>(); double avg = 0; foreach (var i in m) { double d = Convert.ToDouble(i); if (d != -1) { values.Add(d); avg += d; } } if (values.Count == 0) { configsWithTooLargeDeviation++; c = null; break; } avg = avg / values.Count; /* foreach (var d in values) * { * if ((d / avg) * 100 > 10) * { * configsWithTooLargeDeviation++; * c = null; * break; * } * }*/ measuredValue = avg; /*double val2 = Convert.ToDouble(m[1]); * if (val1 == -1) * measuredValue = val2; * else if (val1 == -1 && val2 == -1) * measuredValue = Convert.ToDouble(m[2]); * else if (val2 == -1) * measuredValue = val1; * else * measuredValue = (val1 + val2) / 2;*/ } else { measuredValue = val1; } } else { measuredValue = Convert.ToDouble(childNode.InnerText.ToString().Replace(',', '.')); } if (alternativeFormat && c != null) { c.setMeasuredValue(property, measuredValue); } else { measuredProperty.Add(property, measuredValue); } break; } } if (alternativeFormat && c != null) { if (configurations.Contains(c)) { GlobalState.logError.log("Mutiple definition of one configuration in the configurations file: " + c.ToString()); } else { // if (GlobalState.currentNFP != null && c.nfpValues.Keys.Contains(GlobalState.currentNFP) && c.nfpValues[GlobalState.currentNFP] != -1) configurations.Add(c); } cont : { } continue; } Dictionary <BinaryOption, BinaryOption.BinaryValue> binaryOptions = new Dictionary <BinaryOption, BinaryOption.BinaryValue>(); string[] binaryOptionNames = binaryString.Split(','); foreach (string binaryOptionName in binaryOptionNames) { string currOption = binaryOptionName.Trim(); if (currOption.Length > 0) { BinaryOption bOpt = null; bOpt = model.getBinaryOption(currOption); if (bOpt == null) { GlobalState.logError.log("No Binary option found with name: " + currOption); } binaryOptions.Add(bOpt, BinaryOption.BinaryValue.Selected); } } // Add "root" binary option to the configuration if (!binaryOptions.ContainsKey(model.Root)) { binaryOptions.Add(model.Root, BinaryOption.BinaryValue.Selected); } Dictionary <NumericOption, double> numericOptions = new Dictionary <NumericOption, double>(); if (!string.IsNullOrEmpty(numericString)) { string[] numOptionArray = numericString.Trim().Split(','); foreach (string numOption in numOptionArray) { string[] numOptionsKeyValue; if (numOption.Contains(";")) { numOptionsKeyValue = numOption.Split(';'); } else { numOptionsKeyValue = numOption.Split(' ');// added for rc-lookahead 40 } numOptionsKeyValue[0] = numOptionsKeyValue[0].Trim(); if (numOptionsKeyValue[0].Length == 0) { continue; } NumericOption varFeat = model.getNumericOption(numOptionsKeyValue[0]); if (varFeat == null) { GlobalState.logError.log("No numeric option found with name: " + numOptionsKeyValue[0]); } double varFeatValue = Convert.ToDouble(numOptionsKeyValue[1]); numericOptions.Add(varFeat, varFeatValue); } } Configuration config = new Configuration(binaryOptions, numericOptions, measuredProperty); //if(configurations.Contains(config)) //{ // GlobalState.logError.log("Mutiple definition of one configuration in the configurations file: " + config.ToString()); //}else //{ configurations.Add(config); //} } GlobalState.logInfo.log("Configs with too large deviation: " + configsWithTooLargeDeviation); return(configurations.ToList()); }
/// <summary> /// /// </summary> /// <param name="property"></param> public static void setDefaultProperty(NFProperty property) { GlobalState.currentNFP = property; }
/// <summary> /// /// </summary> /// <param name="propertyName">Name of the property.</param> public static void setDefaultProperty(String propertyName) { GlobalState.currentNFP = GlobalState.nfProperties[propertyName]; }
public InfluenceModel(VariabilityModel vm, NFProperty nfp) { this.vm = vm; this.nfp = nfp; }