static int GetLength(RecordBody body) { int nLength = 0; if (body == null) { return(0); } if (body.Xml != null) { nLength += body.Xml.Length; nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 } if (string.IsNullOrEmpty(body.Metadata) == false) { nLength += body.Metadata.Length; nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 } if (body.Timestamp != null) { nLength += body.Timestamp.Length * 2; nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 } if (body.Result != null) { if (body.Result.ErrorString != null) { nLength += body.Result.ErrorString.Length; } nLength += 16 + 20; // Value 和 ErrorCode 估算的尺寸 nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 } nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 return(nLength); }
static int GetLength(RecordBody body) { int nLength = 0; if (body == null) return 0; if (body.Xml != null) { nLength += body.Xml.Length; nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 } if (string.IsNullOrEmpty(body.Metadata) == false) { nLength += body.Metadata.Length; nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 } if (body.Timestamp != null) { nLength += body.Timestamp.Length * 2; nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 } if (body.Result != null) { if (body.Result.ErrorString != null) nLength += body.Result.ErrorString.Length; nLength += 16 + 20; // Value 和 ErrorCode 估算的尺寸 nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 } nLength += PACKAGE_UNIT_SIZE; // 估计 20 个 bytes 的额外消耗 return nLength; }
// 根据缓存的 ID 列表,重建这些记录的检索点 // strStyle "fastmode,deletekeys" 意思是更新数据库中一部分记录的检索点,因此需要逐条删除 keys,因此要求开始阶段keys表的 B+ 树不要删除。后面为了 buikcopy 可以删除 B+ 树 // "" 意思是慢速模式。本函数返回后不需要任何后续工作 // return: // -1 出错 // >=0 处理的 keys 行数 public virtual int RebuildKeys( string strStyle, out string strError) { strError = ""; if (this.RebuildIDs == null || this.RebuildIDs.Count == 0) return 0; bool bFastMode = StringUtil.IsInList("fastmode", strStyle); string strSubStyle = "rebuildkeys"; if (bFastMode == false) strSubStyle += ",deletekeys"; if (string.IsNullOrEmpty(strStyle) == false) strSubStyle += "," + strStyle; // 如果 strStyle 中本来就有 deletekeys,也会带过来 this.RebuildIDs.Seek(0); // 把指针放到开头位置 // TODO: 应当锁定对象,让文件指针不再改变 ? // List<string> ids = new List<string>(); List<RecordBody> records = new List<RecordBody>(); int nTotalCount = 0; string strID = ""; while (this.RebuildIDs.Read(out strID)) { if (string.IsNullOrEmpty(strID) == true) continue; // 跳过已经标记删除的 ID if (records.Count > 100) { List<RecordBody> outputs = null; int nRet = WriteRecords( null, // User oUser, records, strSubStyle, out outputs, out strError); if (nRet == -1) return -1; // TODO: 完善错误处理。一般应当尽可能继续处理下去。或者重试一次(如果是Bulkcopy,需要考虑重试是否会重复产生keys信息行的问题) // TODO: 是否及时清空那些已经处理的 ID? nTotalCount += nRet; records.Clear(); } RecordBody record = new RecordBody(); record.Path = "./" + strID; records.Add(record); } // 最后一批 if (records.Count > 0) { List<RecordBody> outputs = null; int nRet = WriteRecords( null, // User oUser, records, strSubStyle, out outputs, out strError); if (nRet == -1) return -1; // TODO: 完善错误处理。一般应当尽可能继续处理下去。或者重试一次(如果是Bulkcopy,需要考虑重试是否会重复产生keys信息行的问题) // TODO: 是否及时清空那些已经处理的 ID? nTotalCount += nRet; records.Clear(); } return nTotalCount; }