//设计意图: //覆盖记录时,根据新记录得到一些新的key,但原旧记录也存在一些旧的key, //可以用笨办法删除原旧记录所有的key,再增加新记录所有的key。 // //但新旧记录可能有一些重复key,更好的方法是让新旧记录的两组key进行比较, //结果分成三部分: //1.只在新记录出现的key //2.只在旧记录出现的key //3.重复的key。 // //这样在执行覆盖时,增加第一部分,删除第二部分,重复的保持不变,所以就节省了时间 // //注意调这个函数前,确保集合是排过序的 // //原来newKeys和oldKeys参数类型都是ref,但因为用户类都是引用类型,所以没必须用ref参数 // parameters: // newKeys 新记录的key集合 // oldKeys 旧记录的key集合 // return: // 重复的key集合 public static KeyCollection Merge(KeyCollection newKeys, KeyCollection oldKeys) { KeyCollection dupKeys = new KeyCollection(); if (newKeys.Count == 0) { return(dupKeys); } if (oldKeys.Count == 0) { return(dupKeys); } KeyItem newOneKey; KeyItem oldOneKey; int i = 0; //i,j等于-1时表示对应的集合结束 int j = 0; int ret; //无条件循环,当有一个集合结束(下标变为-1)跳出循环 while (true) { if (i >= newKeys.Count) { i = -1; //strInfo += "左结束<br/>"; } if (j >= oldKeys.Count) { j = -1; //strInfo += "右结束<br/>"; } //两个集合都没有结束时,执行比较,否则跳出循环(至少一个集合结束) if (i != -1 && j != -1) { newOneKey = (KeyItem)newKeys[i]; oldOneKey = (KeyItem)oldKeys[j]; ret = newOneKey.CompareTo(oldOneKey); //MyCompareTo(oldOneKey); //改CompareTO //strInfo += "左-右,返回"+Convert.ToString(ret)+"<br/>"; if (ret == 0) //当等于0时,i,j不改变 { newKeys.Remove(newOneKey); //改为RemoveAt() oldKeys.Remove(oldOneKey); dupKeys.Add(oldOneKey); } //哪一个小,哪一个向下移动 if (ret < 0) { i++; } if (ret > 0) { j++; } //strInfo += "i=" + Convert.ToString(i) + "j=" + Convert.ToString(j) + "<br/>"; } else { break; } } return(dupKeys); }
// return: // -1 出错 // 0 成功 public int Write( string strDatabaseName, KeyCollection keys, delegate_getfilename getfilename, out string strError) { strError = ""; // 确保 keys 里面的事项是排序过的。如果没有排序,本函数也能工作,只是效率略低 DelayTable table = null; KeyCollection part_keys = new KeyCollection(); foreach (KeyItem item in keys) { if (table == null) { table = GetTable(strDatabaseName, item.SqlTableName); if (string.IsNullOrEmpty(table.FileName) == true) { string strFilename = getfilename(strDatabaseName, item.SqlTableName); int nRet = table.Create(strFilename, out strError); if (nRet == -1) { return(-1); } } } else { if (table.TableName != item.SqlTableName) { if (part_keys.Count > 0) { table.Write(part_keys); part_keys.Clear(); } table = GetTable(strDatabaseName, item.SqlTableName); if (string.IsNullOrEmpty(table.FileName) == true) { string strFilename = getfilename(strDatabaseName, item.SqlTableName); int nRet = table.Create(strFilename, out strError); if (nRet == -1) { return(-1); } } } } part_keys.Add(item); } if (part_keys.Count > 0) { Debug.Assert(table != null, ""); table.Write(part_keys); part_keys.Clear(); } return(0); }