/// <summary> /// Converts the <see cref="sourceValue" /> parameter to the <see cref="destinationType" /> parameter using <see cref="formatProvider" /// /> and <see cref="ignoreCase" /> /// </summary> /// <param name="sourceValue">the <see cref="System.Object"/> to convert from</param> /// <param name="destinationType">the <see cref="System.Type" /> to convert to</param> /// <param name="formatProvider">not used by this TypeConverter.</param> /// <param name="ignoreCase">when set to <c>true</c>, will ignore the case when converting.</param> /// <returns> /// an instance of <see cref="GranularityType" />, or <c>null</c> if there is no suitable conversion. /// </returns> public override object ConvertFrom(object sourceValue, global::System.Type destinationType, global::System.IFormatProvider formatProvider, bool ignoreCase) => GranularityType.CreateFrom(sourceValue);
//要使用递归么? /// <summary> /// 生成以指定CG为根的克隆家系 /// </summary> /// <param name="crdFileName">克隆群所在版本的CRD文件名名称(不含路径)</param> /// <param name="cgInfo">克隆群信息(id及size)</param> /// <param name="mapXmlCollection">所用表示相邻版本版本映射的xml文档集合</param> public void BuildForCG(string crdFileName, CGInfo cgInfo, List <XmlDocument> mapXmlCollection, ref int id) { List <XmlDocument> mapXmlDocs = new List <XmlDocument>(); #region 获得从crdFileName版本开始的所有映射文档,保存在mapXmlDocs中 bool flag = false; foreach (XmlDocument mapXml in mapXmlCollection) { if (!flag) { if (mapXml.DocumentElement.ChildNodes[0].InnerText == crdFileName) { mapXmlDocs.Add(mapXml); flag = true; } } else//将从这一版本开始的所有mapXml加入mapXmlDocs中 { mapXmlDocs.Add(mapXml); } } #endregion if (mapXmlDocs.Count == 0) { return; } else { #region 构造克隆家系信息 string startFile = mapXmlDocs[0].DocumentElement.ChildNodes[0].InnerText; bool atBlocks; //粒度标识,在函数调用时传递粒度信息 if (startFile.IndexOf("_blocks-") != -1) { CloneGenealogy.granularity = GranularityType.BLOCKS; atBlocks = true; this.startVersion = startFile.Substring(0, startFile.IndexOf("_blocks-")); } else { CloneGenealogy.granularity = GranularityType.FUNCTIONS; atBlocks = false; this.startVersion = startFile.Substring(0, startFile.IndexOf("_functions-")); } this.rootCGid = cgInfo.id; //保存根克隆群在该版本中的id this.evolutionList = new List <Evolution>(); #endregion #region 构造进化关系列表 int index = -1; int evoID = 0; int endIndex = -1; //记录克隆家系停止生长的版本的位置 List <CGInfo> cgInfoList = new List <CGInfo>(); //cgInfoList用来存放当前所关注的克隆群,可能是多个,因此用列表 cgInfoList.Add(cgInfo); foreach (XmlDocument mapXml in mapXmlDocs) { index++; List <CloneGroupMapping> cgMapList = new List <CloneGroupMapping>(); //存放当前两个版本间相关映射集 foreach (CGInfo info in cgInfoList) //这个循环是考虑分裂的情况而设 { //找出mapXml中以info代表的CG为源的所有映射,多数情况下为1个,少数情况多于一个 foreach (XmlElement cgMapNode in mapXml.DocumentElement.SelectNodes("CGMap")) { CloneGroupMapping cgMap = new CloneGroupMapping(); cgMap.CreateCGMapppingFromCGMapNode(cgMapNode); if (cgMap.srcCGInfo.id == info.id) { cgMapList.Add(cgMap); } } } string srcFileName = mapXml.DocumentElement.ChildNodes[0].InnerText; string destFileName = mapXml.DocumentElement.ChildNodes[1].InnerText; cgInfoList = new List <CGInfo>(); if (cgMapList.Count != 0) { //为选出的每一个CGMap构造Evolution对象。同时更新cgInfoList foreach (CloneGroupMapping cgMap in cgMapList) { Evolution evolution = new Evolution(); evolution.BuildFromCGMap(cgMap, srcFileName, destFileName, ref this.evolutionList, ref evoID, atBlocks); this.evolutionList.Add(evolution); cgInfoList.Add(cgMap.destCGInfo); endIndex = index; //更新endIndex的值 } } else//当cgMapList.Count为0时,说明此克隆家系停止生长 { break; } } #endregion #region 补全克隆家系信息 this.age = endIndex + 2; //计算年龄(年龄指克隆群在几个版本中存在,等于它所发生的进化次数+1) if (this.age > 1) //如果该克隆群寿命大于1(即不是只在单个版本出现) { string endFile = mapXmlDocs[endIndex].DocumentElement.ChildNodes[1].InnerText; if (atBlocks) { this.endVersion = endFile.Substring(0, endFile.IndexOf("_blocks-")); } else { this.endVersion = endFile.Substring(0, endFile.IndexOf("_functions-")); } if (this.evolutionList != null && this.evolutionList.Count != 0) { id++; this.ID = id.ToString(); } #region 统计各种进化模式出现的次数,保存在evoPatternCount数组中 this.evoPatternCount = new int[7] { 0, 0, 0, 0, 0, 0, 0 }; foreach (Evolution evolution in this.evolutionList) { if (evolution.CGMapInfo.pattern.IndexOf("STATIC") != -1) { this.evoPatternCount[0]++; } if (evolution.CGMapInfo.pattern.IndexOf("SAME") != -1) { this.evoPatternCount[1]++; } if (evolution.CGMapInfo.pattern.IndexOf("ADD") != -1) { this.evoPatternCount[2]++; } if (evolution.CGMapInfo.pattern.IndexOf("DELETE") != -1) { this.evoPatternCount[3]++; } if (evolution.CGMapInfo.pattern.IndexOf("CONSISTENTCHANGE") != -1) { this.evoPatternCount[4]++; } if (evolution.CGMapInfo.pattern.IndexOf("INCONSISTENTCHANGE") != -1) { this.evoPatternCount[5]++; } if (evolution.CGMapInfo.pattern.IndexOf("SPLIT") != -1) { this.evoPatternCount[6]++; } } #endregion } #endregion } }