/// <summary> /// Pop an item from the head of the queue. /// </summary> /// <remarks> /// NOTE: TrySteal() can be invoked from any thread. /// </remarks> /// <param name="item">Head item of the queue when operation is successful.</param> /// <returns><see langword="True"/> if operation was successful.</returns> public bool TrySteal(out T item) { // read top TopData curTop = _top; // read bottom BottomData curBottom = _bottom; if (IsEmpty(curBottom, curTop, _capacity)) { item = default(T); if (ReferenceEquals(curTop, _top)) { return(false); } else { // NOTE (steveb): this is contentious access case; we currently return 'false' but may want to differentiate in the future return(false); } } // if deque isn't empty, calcuate next top pointer TopData newTop; if (curTop.Index != 0) { // stay at current node newTop = new TopData(curTop.Tag, curTop.Node, curTop.Index - 1); } else { // move to next node and update tag newTop = new TopData(curTop.Tag + 1, curTop.Node.Prev, _capacity - 1); } // read value T retVal = curTop.Node.Data[curTop.Index]; // try updating _top using CAS if (SysUtil.CAS(ref _top, curTop, newTop)) { // clear out the entry we read, so the GC can reclaim it SysUtil.CAS(ref curTop.Node.Data[curTop.Index], retVal, default(T)); // free old node curTop.Node.Next = null; item = retVal; return(true); } else { item = default(T); // NOTE (steveb): this is contentious access case; we currently return 'false' but may want to differentiate in the future return(false); } }
/// <summary> /// Create a new instance. /// </summary> /// <param name="capacity">Maximum number of items in the queue.</param> public WorkStealingDeque(int capacity) { _capacity = capacity; DequeNode nodeB = new DequeNode(_capacity, null); DequeNode nodeA = new DequeNode(_capacity, nodeB); _bottom = new BottomData(nodeA, _capacity - 1); _top = new TopData(0, nodeA, _capacity - 1); }
//--- Class Methods --- private static bool IsEmpty(BottomData bottom, TopData top, int capacity) { if (ReferenceEquals(bottom.Node, top.Node) && ((bottom.Index == top.Index) || (bottom.Index == (top.Index + 1)))) { return(true); } else if (ReferenceEquals(bottom.Node, top.Node.Next) && (bottom.Index == 0) && (top.Index == (capacity - 1))) { return(true); } return(false); }
public TimeLinkCountDto GetTimeLinkCount(string categoryId, string prjId, string startTime, string endTime, int percent, int topNum, int sumNum, int timeInterval) { DateTime tpStart = new DateTime(); DateTime tpEnd = new DateTime(); DateTime.TryParse(startTime, out tpStart); DateTime.TryParse(endTime, out tpEnd); List <ObjectId> cateIds = new List <ObjectId>(); //拆分categoryId,转为ObjectId数组 if (!string.IsNullOrEmpty(categoryId)) { cateIds = categoryId.Split(';').Where(x => !string.IsNullOrEmpty(x)).Select(x => new ObjectId(x)).ToList(); } //多个分组时剔除根分组 cateIds.Remove(ObjectId.Empty); int years = 3; //图表时间范围,按天的是3年,按周和按月是5年 switch (timeInterval) { case 1: years = 3; break; case 7: years = 5; break; case 30: years = 5; break; default: break; } TimeLinkCountDto result = new TimeLinkCountDto(); if (string.IsNullOrEmpty(prjId) && string.IsNullOrEmpty(categoryId)) { return(result); } var groupBuilder = Builders <Dnl_KeywordMapping> .Filter; var builder = Builders <Dnl_Link_Baidu> .Filter; //List<ObjectId> proIds = new List<ObjectId>(); //if (!string.IsNullOrEmpty(categoryId)) //{ // proIds = prjId.Split(';').Where(x => !string.IsNullOrEmpty(x)).Select(x => new ObjectId(x)).ToList(); //} //获取关键词列表 List <string> keywordList = new List <string>(); //关键词列表 var keyToCate = new Dictionary <string, string>(); //关键词与词组和项目Id比对词典 //从获取分组中关键词 var groupFilter = groupBuilder.In(x => x.CategoryId, cateIds) & groupBuilder.Eq(x => x.IsDel, false); var groupCol = MongoDBHelper.Instance.GetDnl_KeywordMapping(); var taskList = groupCol.Find(groupFilter).Project(x => new { KeywordId = x.KeywordId.ToString(), CategoryId = x.CategoryId.ToString() }).ToList(); foreach (var x in taskList) { if (!keywordList.Contains(x.KeywordId)) { keywordList.Add(x.KeywordId); } if (!keyToCate.ContainsKey(x.KeywordId)) { keyToCate.Add(x.KeywordId, x.CategoryId); } else { //将一个关键词Id对应的多个分组ID拼接在一起 keyToCate[x.KeywordId] += ";" + x.CategoryId; } } //获取项目中关键词,因为词组Id和项目Id混在一起,所以要不规则对项目ID查询一遍 var filterPro = groupBuilder.Eq(x => x.CategoryId, ObjectId.Empty) & groupBuilder.In(x => x.ProjectId, cateIds) & groupBuilder.Eq(x => x.IsDel, false); var taskList2 = MongoDBHelper.Instance.GetDnl_KeywordMapping().Find(filterPro).Project(x => new { KeywordId = x.KeywordId.ToString(), CategoryId = x.ProjectId.ToString(), ProjectId = x.ProjectId.ToString() }).ToList(); foreach (var x in taskList2) { if (!keywordList.Contains(x.KeywordId)) //如果词典中无该关键词Id,新增 { keywordList.Add(x.KeywordId); } if (!keyToCate.ContainsKey(x.KeywordId)) { keyToCate.Add(x.KeywordId, x.ProjectId); } else //如果词典中已有该关键词Id,则在对应数据中追加 { keyToCate[x.KeywordId] += ";" + x.ProjectId; } } //获取发表时间 var filter = builder.In(x => x.SearchkeywordId, keywordList) & builder.Ne(x => x.PublishTime, ""); var queryDatas = MongoDBHelper.Instance.GetDnl_Link_Baidu().Find(filter).Project(x => new { PublishTime = x.PublishTime, KeywordId = x.SearchkeywordId, Title = x.Title, Description = x.Description }).ToList(); //获取包含分组ID的链接发布时间信息 List <LinkStatus> linkList = new List <LinkStatus>(); foreach (var x in queryDatas) { DateTime tmpDt = new DateTime(); DateTime.TryParse(x.PublishTime, out tmpDt); LinkStatus v = new LinkStatus(); v.PublishTime = tmpDt; v.CategoryId = keyToCate[x.KeywordId]; v.Title = x.Title; v.Description = x.Description; linkList.Add(v); } //删除异常时间 如0001-01-01与2063-23-12等时间,并排序 linkList = linkList.Where(x => x.PublishTime > new DateTime(1753, 1, 09)).Where(x => x.PublishTime <= DateTime.Now).OrderByDescending(x => x.PublishTime).ToList(); //建立时间坐标 List <DateTime> xCoordinate = new List <DateTime>(); //int i = 1; if (linkList.Count > 0) { DateTime now = linkList[0].PublishTime; DateTime end = now.AddYears(-years); while (now >= end) { xCoordinate.Add(now); now = now.AddDays(-timeInterval); } } xCoordinate.Reverse(); result.Times = xCoordinate; //获取起止时间位置 int xStart; int xEnd; if (string.IsNullOrEmpty(startTime) && string.IsNullOrEmpty(endTime)) { for (int i = 0; i < xCoordinate.Count; i++) { if (xCoordinate[i] <= tpStart) { xStart = i; } if (xCoordinate[i] <= tpEnd) { xEnd = i; } } } //将发布时间依分组拆分 List <CategoryList> categoryList = new List <CategoryList>(); //建立分组 foreach (var x in cateIds) { CategoryList v = new CategoryList(); v.PublishTime = new List <DateTime>(); v.CategoryId = x.ToString(); categoryList.Add(v); } //获取分组名并分配到数据中去 var namefilter = Builders <Dnl_KeywordCategory> .Filter.In(x => x._id, cateIds); var nameList = MongoDBHelper.Instance.GetDnl_KeywordCategory().Find(namefilter).Project(x => new { Name = x.Name, CategoryId = x._id.ToString() }).ToList(); foreach (var x in nameList) { CategoryList cat = categoryList.Find(s => s.CategoryId.Equals(x.CategoryId)); cat.CategoryName = x.Name; } //同样再对项目名查询一遍 var namefilter2 = Builders <IW2S_Project> .Filter.In(x => x._id, cateIds); var nameList2 = MongoDBHelper.Instance.GetIW2S_Projects().Find(namefilter2).Project(x => new { Name = x.Name, CategoryId = x._id.ToString() }).ToList(); foreach (var x in nameList2) { CategoryList cat = categoryList.Find(s => s.CategoryId.Equals(x.CategoryId)); cat.CategoryName = x.Name; } //获取各分组内数据的发布时间 foreach (var cate in categoryList) { var links = linkList.FindAll(x => x.CategoryId.Contains(cate.CategoryId)); //因为链接可能有多个分组 cate.PublishTime.AddRange(links.Select(x => x.PublishTime)); } List <LineData> lineData = new List <LineData>(); //top数据 List <TopData> topData = new List <TopData>(); //遍历数组,获取不同分组的数据 foreach (var categoryData in categoryList) { LineData line = new LineData(); line.name = categoryData.CategoryName; List <int> linkCounts = new List <int>(); if (categoryData.PublishTime.Count > 0) { DateTime now = linkList[0].PublishTime; DateTime end = new DateTime(); end = now.AddYears(-years); while (now >= end) { linkCounts.Add(categoryData.PublishTime.Where(x => x <= now && x > now.AddDays(-timeInterval)).Count()); now = now.AddDays(-timeInterval); } } else { continue; } //将链接数倒序 linkCounts.Reverse(); line.LinkCount = linkCounts; lineData.Add(line); //将坐标添加到临时数据列表中 List <DateTime> temp = new List <DateTime>(); for (int i = 0; i < xCoordinate.Count; i++) { TopData v = new TopData(); v.name = categoryData.CategoryName; v.CategoryId = categoryData.CategoryId; v.X = xCoordinate[i]; v.Y = linkCounts[i]; topData.Add(v); } } //获取top数据及自动摘要节点 if (string.IsNullOrEmpty(startTime) && string.IsNullOrEmpty(endTime)) { topData = topData.Where(x => x.X > linkList[0].PublishTime.AddYears(-1)).ToList().OrderByDescending(x => x.Y).ToList <TopData>(); } else { topData = topData.Where(x => x.X > tpStart).Where(x => x.X < tpEnd).OrderByDescending(x => x.Y).ToList <TopData>(); } //获取限定数量的摘要时间节点 List <TopData> tempSum = new List <TopData>(); if (sumNum > 0) { tempSum = topData.Take(sumNum).ToList(); } else { tempSum = topData.Take(1).ToList(); } topData = topData.Take(topNum).ToList(); List <SumData> sumData = new List <SumData>(); //摘要 //获取摘要节点 for (var i = 0; i < tempSum.Count; i++) { SumData sum = new SumData(); sum.Y = tempSum[i].Y; sum.X = tempSum[i].X; sum.CategoryName = tempSum[i].name; sum.CategoryId = tempSum[i].CategoryId; sumData.Add(sum); } //依节点查询数据库,生成摘要 JiebaController jieba = new JiebaController(); for (var i = 0; i < sumData.Count; i++) { DateTime time = sumData[i].X; //当前时间节点 string source = ""; foreach (var x in linkList) { if (x.PublishTime <= time && x.PublishTime > time.AddDays(-timeInterval)) { if (x.CategoryId.Equals(sumData[i].CategoryId)) { source += x.Title + "。" + System.Environment.NewLine + x.Description + "。" + System.Environment.NewLine; } } } var tempStr = jieba.GetSummary(sumData[i].CategoryName, time.ToString(), prjId, source); if (tempStr.Count > 0 && tempStr[0].Length > 40) { tempStr[0] = tempStr[0].Substring(0, 39); tempStr[0] += "…"; } if (tempStr.Count > 0) { sumData[i].Summary = tempStr[0]; } } result.Sum = sumData; //在percent大于0时,获取最大值,将不高于最大值percent百分比的值设为0,topData值删除 List <TopData> delList = new List <TopData>(); if (percent > 0) { int maxCount = topData[0].Y; int limit = maxCount * percent / 100; for (int i = 0; i < lineData.Count; i++) { for (int j = 0; j < lineData[i].LinkCount.Count; j++) { if (lineData[i].LinkCount[j] < limit) { lineData[i].LinkCount[j] = 0; } } } foreach (var x in topData) { if (x.Y < limit) { delList.Add(x); } } foreach (var x in delList) { topData.Remove(x); } //for (int i = 0; i < topData.Count; i++) //{ // if (topData[i].Y < limit) topData[i].Y = 0; //} } //将top数据分配到各组中去 for (int i = 0; i < lineData.Count; i++) { lineData[i].topData = new List <TopData>(); foreach (var x in topData) { if (lineData[i].name.Equals(x.name)) { lineData[i].topData.Add(x); } } } result.LineDataList = lineData; return(result); }
/// <summary> /// Pop an item from the tail of the queue. /// </summary> /// <remarks> /// NOTE: Push() and TryPop() <strong>MUST</strong> be called from the same thread. /// </remarks> /// <param name="item">Tail item of the queue when operation is successful.</param> /// <returns><see langword="True"/> if operation was successful.</returns> public bool TryPop(out T item) { item = default(T); // read bottom data BottomData curBottom = _bottom; BottomData newBottom; if (curBottom.Index != (_capacity - 1)) { newBottom = new BottomData(curBottom.Node, curBottom.Index + 1); } else { newBottom = new BottomData(curBottom.Node.Next, 0); } // update bottom _bottom = newBottom; // read top TopData curTop = _top; // read data to be popped T retVal = newBottom.Node.Data[newBottom.Index]; // case 1: if _top has crossed _bottom if (ReferenceEquals(curBottom.Node, curTop.Node) && (curBottom.Index == curTop.Index)) { // return bottom to its old position _bottom = curBottom; return(false); } // case 2: when popping the last entry in the deque (i.e. deque is empty after the update of bottom) if (ReferenceEquals(newBottom.Node, curTop.Node) && (newBottom.Index == curTop.Index)) { // try to update _top's tag so no concurrent Steal operation will also pop the same entry TopData newTopVal = new TopData(curTop.Tag + 1, curTop.Node, curTop.Index); if (SysUtil.CAS(ref _top, curTop, newTopVal)) { // TODO (steveb): clear out the entry we read, so the GC can reclaim it // free old node if needed if (!ReferenceEquals(curBottom.Node, newBottom.Node)) { newBottom.Node.Prev = null; } item = retVal; return(true); } else { // if CAS failed (i.e. a concurrent Steal operation alrady popped that last entry) // return bottom to its old position _bottom = curBottom; return(false); } } // case 3: regular case (i.e. there was a least one entry in the deque _after_ bottom's update) // free old node if needed if (!ReferenceEquals(curBottom.Node, newBottom.Node)) { newBottom.Node.Prev = null; } item = retVal; return(true); }
public Data() { topData = new TopData(); }