// 实现IComparable接口的CompareTo()方法, // 根据ID比较两个对象的大小,以便排序, // 按右对齐方式比较 // obj: An object to compare with this instance // 返回值 A 32-bit signed integer that indicates the relative order of the comparands. The return value has these meanings: // Less than zero: This instance is less than obj. // Zero: This instance is equal to obj. // Greater than zero: This instance is greater than obj. // 异常: ArgumentException,obj is not the same type as this instance. public override int CompareTo(object obj) { TopArticleItem item = (TopArticleItem)obj; if (this.m_ticks == 0) { throw (new Exception("this.ticks不能为0")); } if (item.m_ticks == 0) { throw (new Exception("item.ticks不能为0")); } if (this.m_bColumnTop != item.m_bColumnTop) { if (this.m_bColumnTop != 0) { return((-1) * 1); } return((-1) * (-1)); } long delta = this.m_ticks - item.m_ticks; if (delta != 0) { if (delta < 0) { return((-1) * (-1)); } else { return((-1) * 1); } } /* * delta = this.m_id - item.m_id; * if (delta != 0) * { * if (delta < 0) * return (-1) * (-1); * else * return (-1) * 1; * } * */ return(0); }
// 快速获得事项的记录路径 public string GetItemRecPath(Int64 nIndex) { // 加读锁 this.m_lock.AcquireReaderLock(m_nLockTimeout); try { TopArticleItem item = (TopArticleItem)this.GetCompareItem(nIndex, false); if (item == null) { return(""); // error } return(item.m_strRecPath); } finally { this.m_lock.ReleaseReaderLock(); } }
// [外部调用] // 修改评注记录后,更新栏目存储结构 // parameters: // strAction 动作。change/delete/new // return: // -2 栏目缓存尚未创建,因此无从更新 // -1 error // 0 not found line object // 1 succeed public int UpdateLine( System.Web.UI.Page page, string strAction, string strRecPath, string strXml, out string strError) { strError = ""; if (this.CommentColumn == null || this.CommentColumn.Opened == false) { strError = "尚未创建栏目缓存..."; return -2; } this.m_lockCommentColumn.AcquireWriterLock(m_nCommentColumnLockTimeout); try { int nIndex = -1; int i = 0; Line line = null; if (strAction == "change" || strAction == "delete") { // 在Storage中找 // 需要写锁定 for (i = 0; i < this.CommentColumn.Count; i++) { string strCurrentRecPath = this.CommentColumn.GetItemRecPath(i); if (strCurrentRecPath == strRecPath) { nIndex = i; line = ((TopArticleItem)this.CommentColumn[nIndex]).Line; Debug.Assert(line.m_strRecPath == strRecPath, ""); this.CommentColumn.RemoveAt(nIndex); if (strAction == "delete") return 1; break; // goto FOUND; } } if (strAction == "delete") return 0; } else if (strAction == "new") { line = new Line(); line.m_strRecPath = strRecPath; } else { strError = "未知的strAction值 '" + strAction + "'"; return -1; } // FOUND: if (strAction == "delete") return 1; int nRet = line.ProcessXml( null, // page, 这里至关重要,不能允许灵敏中断 strXml, out strError); if (nRet == -1) { // 将此情况写入错误日志 this.WriteErrorLog("在UpdateLine()函数中,调用line.ProcessXml()发生错误, 记录路径=" + line.m_strRecPath + ")。这将导致栏目主页面中,该记录从显示中丢失。详细原因:" + strError); return -1; } { // 如果插入位置在Storage范围内 TopArticleItem item = new TopArticleItem(); item.Line = line; this.CommentColumn.Insert(0, item); } return 1; } finally { this.m_lockCommentColumn.ReleaseWriterLock(); } }
// 检索顶层文章 // return: // -1 error // 其他 命中数 private int SearchTopLevelArticles( SessionInfo sessioninfo, System.Web.UI.Page page, out string strError) { strError = ""; if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return -1; } // 检索全部评注文章 一定时间范围内的? List<string> dbnames = new List<string>(); for (int i = 0; i < this.ItemDbs.Count; i++) { ItemDbCfg cfg = this.ItemDbs[i]; string strDbName = cfg.CommentDbName; if (String.IsNullOrEmpty(strDbName) == true) continue; dbnames.Add(strDbName); } DateTime now = DateTime.Now; DateTime oneyearbefore = now - new TimeSpan(365, 0, 0, 0); string strTime = DateTimeUtil.Rfc1123DateTimeString(oneyearbefore.ToUniversalTime()); string strQueryXml = ""; for (int i = 0; i < dbnames.Count; i++) { string strDbName = dbnames[i]; string strOneQueryXml = "<target list='" + strDbName + ":" + "最后修改时间'><item><word>" // <order>DESC</order> + strTime + "</word><match>exact</match><relation>" + StringUtil.GetXmlStringSimple(">=") + "</relation><dataType>number</dataType><maxCount>" + "-1"// Convert.ToString(m_nMaxLineCount) + "</maxCount></item><lang>zh</lang></target>"; if (i > 0) strQueryXml += "<operator value='OR' />"; strQueryXml += strOneQueryXml; } if (dbnames.Count > 0) strQueryXml = "<group>" + strQueryXml + "</group>"; RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); Debug.Assert(channel != null, "Channels.GetChannel 异常"); if (page != null) { page.Response.Write("--- begin search ...<br/>"); page.Response.Flush(); } DateTime time = DateTime.Now; long nRet = channel.DoSearch(strQueryXml, "default", out strError); if (nRet == -1) { strError = "检索时出错: " + strError; return -1; } TimeSpan delta = DateTime.Now - time; if (page != null) { page.Response.Write("search end. hitcount=" + nRet.ToString() + ", time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } if (nRet == 0) return 0; // not found if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return -1; } if (page != null) { page.Response.Write("--- begin get search result ...<br/>"); page.Response.Flush(); } time = DateTime.Now; List<string> aPath = null; nRet = channel.DoGetSearchResult( "default", -1, "zh", null, // stop, out aPath, out strError); if (nRet == -1) { strError = "获得检索结果时出错: " + strError; return -1; } if (page != null) { delta = DateTime.Now - time; page.Response.Write("get search result end. lines=" + aPath.Count.ToString() + ", time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } if (aPath.Count == 0) { strError = "获取的检索结果为空"; return -1; } if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return -1; } if (page != null) { page.Response.Write("--- begin build storage ...<br/>"); page.Response.Flush(); } time = DateTime.Now; this.CommentColumn.Clear(); // 清空集合 // 加入新行对象。新行对象中,只初始化了m_strRecPath参数 for (int i = 0; i < Math.Min(aPath.Count, 1000000); i++) // <Math.Min(aPath.Count, 10) { Line line = new Line(); // line.Container = this; line.m_strRecPath = aPath[i]; nRet = line.InitialInfo( page, channel, out strError); if (nRet == -1) return -1; if (nRet == 1) return -1; // 灵敏中断 TopArticleItem item = new TopArticleItem(); item.Line = line; this.CommentColumn.Add(item); if (page != null && (i % 100) == 0) { page.Response.Write("process " + Convert.ToString(i) + "<br/>"); page.Response.Flush(); } } if (page != null) { delta = DateTime.Now - time; page.Response.Write("build storage end. time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } return 1; }
// [外部调用] // 修改评注记录后,更新栏目存储结构 // parameters: // strAction 动作。change/delete/new // return: // -2 栏目缓存尚未创建,因此无从更新 // -1 error // 0 not found line object // 1 succeed public int UpdateLine( System.Web.UI.Page page, string strAction, string strRecPath, string strXml, out string strError) { strError = ""; if (this.CommentColumn == null || this.CommentColumn.Opened == false) { strError = "尚未创建栏目缓存..."; return(-2); } this.m_lockCommentColumn.AcquireWriterLock(m_nCommentColumnLockTimeout); try { int nIndex = -1; int i = 0; Line line = null; if (strAction == "change" || strAction == "delete") { // 在Storage中找 // 需要写锁定 for (i = 0; i < this.CommentColumn.Count; i++) { string strCurrentRecPath = this.CommentColumn.GetItemRecPath(i); if (strCurrentRecPath == strRecPath) { nIndex = i; line = ((TopArticleItem)this.CommentColumn[nIndex]).Line; Debug.Assert(line.m_strRecPath == strRecPath, ""); this.CommentColumn.RemoveAt(nIndex); if (strAction == "delete") { return(1); } break; // goto FOUND; } } if (strAction == "delete") { return(0); } } else if (strAction == "new") { line = new Line(); line.m_strRecPath = strRecPath; } else { strError = "未知的strAction值 '" + strAction + "'"; return(-1); } // FOUND: if (strAction == "delete") { return(1); } int nRet = line.ProcessXml( null, // page, 这里至关重要,不能允许灵敏中断 strXml, out strError); if (nRet == -1) { // 将此情况写入错误日志 this.WriteErrorLog("在UpdateLine()函数中,调用line.ProcessXml()发生错误, 记录路径=" + line.m_strRecPath + ")。这将导致栏目主页面中,该记录从显示中丢失。详细原因:" + strError); return(-1); } { // 如果插入位置在Storage范围内 TopArticleItem item = new TopArticleItem(); item.Line = line; this.CommentColumn.Insert(0, item); } return(1); } finally { this.m_lockCommentColumn.ReleaseWriterLock(); } }
// 检索顶层文章 // return: // -1 error // 其他 命中数 private int SearchTopLevelArticles( SessionInfo sessioninfo, System.Web.UI.Page page, out string strError) { strError = ""; if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return(-1); } // 检索全部评注文章 一定时间范围内的? List <string> dbnames = new List <string>(); for (int i = 0; i < this.ItemDbs.Count; i++) { ItemDbCfg cfg = this.ItemDbs[i]; string strDbName = cfg.CommentDbName; if (String.IsNullOrEmpty(strDbName) == true) { continue; } dbnames.Add(strDbName); } DateTime now = DateTime.Now; DateTime oneyearbefore = now - new TimeSpan(365, 0, 0, 0); string strTime = DateTimeUtil.Rfc1123DateTimeString(oneyearbefore.ToUniversalTime()); string strQueryXml = ""; for (int i = 0; i < dbnames.Count; i++) { string strDbName = dbnames[i]; string strOneQueryXml = "<target list='" + strDbName + ":" + "最后修改时间'><item><word>" // <order>DESC</order> + strTime + "</word><match>exact</match><relation>" + StringUtil.GetXmlStringSimple(">=") + "</relation><dataType>number</dataType><maxCount>" + "-1" // Convert.ToString(m_nMaxLineCount) + "</maxCount></item><lang>zh</lang></target>"; if (i > 0) { strQueryXml += "<operator value='OR' />"; } strQueryXml += strOneQueryXml; } if (dbnames.Count > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); Debug.Assert(channel != null, "Channels.GetChannel 异常"); if (page != null) { page.Response.Write("--- begin search ...<br/>"); page.Response.Flush(); } DateTime time = DateTime.Now; long nRet = channel.DoSearch(strQueryXml, "default", out strError); if (nRet == -1) { strError = "检索时出错: " + strError; return(-1); } TimeSpan delta = DateTime.Now - time; if (page != null) { page.Response.Write("search end. hitcount=" + nRet.ToString() + ", time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } if (nRet == 0) { return(0); // not found } if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return(-1); } if (page != null) { page.Response.Write("--- begin get search result ...<br/>"); page.Response.Flush(); } time = DateTime.Now; List <string> aPath = null; nRet = channel.DoGetSearchResult( "default", -1, "zh", null, // stop, out aPath, out strError); if (nRet == -1) { strError = "获得检索结果时出错: " + strError; return(-1); } if (page != null) { delta = DateTime.Now - time; page.Response.Write("get search result end. lines=" + aPath.Count.ToString() + ", time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } if (aPath.Count == 0) { strError = "获取的检索结果为空"; return(-1); } if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return(-1); } if (page != null) { page.Response.Write("--- begin build storage ...<br/>"); page.Response.Flush(); } time = DateTime.Now; this.CommentColumn.Clear(); // 清空集合 // 加入新行对象。新行对象中,只初始化了m_strRecPath参数 for (int i = 0; i < Math.Min(aPath.Count, 1000000); i++) // <Math.Min(aPath.Count, 10) { Line line = new Line(); // line.Container = this; line.m_strRecPath = aPath[i]; nRet = line.InitialInfo( page, channel, out strError); if (nRet == -1) { return(-1); } if (nRet == 1) { return(-1); // 灵敏中断 } TopArticleItem item = new TopArticleItem(); item.Line = line; this.CommentColumn.Add(item); if (page != null && (i % 100) == 0) { page.Response.Write("process " + Convert.ToString(i) + "<br/>"); page.Response.Flush(); } } if (page != null) { delta = DateTime.Now - time; page.Response.Write("build storage end. time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } return(1); }