public void CheckNativeGroupResponse(object o) { string groupident = (string)o; if (this.pendingNativeGroupResponses.Count == 0) return; Console.WriteLine("Reader{0} check native group response. ", this.Id); if (!this.pendingNativeGroupResponses.ContainsKey(groupident)) return; if (!this.cachedCheckedRecvResponse.ContainsKey(groupident)) this.cachedCheckedRecvResponse.Add(groupident, scheduler.currentTime); else this.cachedCheckedRecvResponse[groupident] = scheduler.currentTime; Dictionary<int, NativeGroupResponseEntry> entrySet = this.pendingNativeGroupResponses[groupident]; /* Console.WriteLine("count:{0}-{1}", this.pendingNativeGroupResponses.Count, this.pendingNativeGroupResponses[groupident].Count); foreach (int c in entrySet.Keys) { Console.Write("ppp:{0}\t", c); }*/ string[] l = groupident.Split('-'); int origId = int.Parse(l[0]); int k = int.Parse(l[1]); int h0 = int.Parse(l[2]); //检查节点是否全部返回 int waitingNodes = 0; int availCount = 0; foreach (int nodeId in entrySet.Keys) { NativeGroupResponseEntry e = entrySet[nodeId]; if (e == null)//尚未返回 { Console.WriteLine("Reader{0} is waiting for reader{1}", this.Id, nodeId); waitingNodes ++; continue; } else if (e.h < 0) { Console.WriteLine("error impossible , abort"); return; } e.h++; if (this.cachedCandidateNodes.ContainsKey(k) && this.cachedCandidateNodes[k].Contains(nodeId)) continue; if (e.avail == true) availCount++; //Console.Write("e: {0}\t", e.nodeId); } if (waitingNodes > 0) return; if (origId != this.Id) { if(!entrySet.ContainsKey(this.Id)) entrySet.Add(this.Id, new NativeGroupResponseEntry(this.Id, 1, h0, origId, k, !this.anonGroups.groups.ContainsKey(k))); SendNativeGroupResponse(this.requestNode, entrySet.Values.ToList()); } else//到了初始节点 { //现有节点可以建组,无需等待或做其他操作 if (this.cachedCandidateNodes.ContainsKey(k)) { //if (entrySet.Count - waitingNodes + this.cachedCandidateNodes[k].Count >= k) if (availCount +this.cachedCandidateNodes[k].Count >= k-1)//算上自己 { this.anonGroups.ks.Remove(k); HashSet<int> set = new HashSet<int>(); set.Add(this.Id); int i = 1; foreach (int nodeId in this.cachedCandidateNodes[k]) { if (i == k) break; set.Add(nodeId); i++; } foreach (int nodeId in entrySet.Keys) { if (i == k) break; if (entrySet[nodeId] == null || entrySet[nodeId].avail == false) continue; set.Add(nodeId); i++; } this.anonGroups.groups.Add(k, set); PrintGroupNodes(set); PrivacyReader.rootReader = this; foreach (int nodeId in set) SendSetGroup(this.Id, this.Id, k, nodeId, set, new HashSet<int>() { nodeId }); } } else if (waitingNodes > 0) //需要等待子节点 return; //之前已经建立成功 else if (this.anonGroups.groups.ContainsKey(k)) return; //不满足要求 else if (entrySet.Count < k - 1) { this.lastesth++; Console.WriteLine("New round-----------------------------------------------------------------------"); SendNativeGroupRequest(this.lastesth, this.lastesth, k, this.Id); string newgroupident = origId + "-" + k + "-" + this.lastesth; if (!this.pendingNativeGroupResponses.ContainsKey(newgroupident)) this.pendingNativeGroupResponses.Add(newgroupident, new Dictionary<int, NativeGroupResponseEntry>()); if (!this.cachedRecvRequest.ContainsKey(newgroupident)) this.cachedRecvRequest.Add(newgroupident, scheduler.currentTime); Event.AddEvent(new Event(scheduler.currentTime + 0.3f, EventType.CHK_NATGROUP, this, newgroupident)); } else //建立成功 { this.anonGroups.ks.Remove(k); HashSet<int> set = new HashSet<int>(); set.Add(this.Id); int i = 1; foreach (int nodeId in entrySet.Keys) { if (i == k) break; if(entrySet[nodeId].avail == false) continue; set.Add(nodeId); i++; } this.anonGroups.groups.Add(k, set); PrintGroupNodes(set); PrivacyReader.rootReader = this; foreach (int nodeId in set) SendSetGroup(this.Id, this.Id, k, nodeId, set, new HashSet<int>() { nodeId }); } } //Console.WriteLine("pendingNativeGroupResponses[{0}] count: {1}", groupident, this.pendingNativeGroupResponses[groupident].Count); entrySet.Clear(); this.pendingNativeGroupResponses.Remove(groupident); //Console.WriteLine("pendingNativeGroupResponses count: {0}", this.pendingNativeGroupResponses.Count); }
public void CheckNativeLargeGroupResponse(object o) { string groupident = (string)o; if (this.pendingNativeGroupResponses.Count == 0) return; Console.WriteLine("Reader{0} check large native group response. ", this.Id); if (!this.pendingNativeGroupResponses.ContainsKey(groupident)) return; if (!this.cachedCheckedRecvResponse.ContainsKey(groupident)) this.cachedCheckedRecvResponse.Add(groupident, scheduler.currentTime); else this.cachedCheckedRecvResponse[groupident] = scheduler.currentTime; string[] l = groupident.Split('-'); //string groupident = this.id + "-" + k + "-" + this.lastesth; int k = int.Parse(l[1]); if (this.anonGroups.groups.ContainsKey(k)) return; if (this.cachedCandidateNodes[k].Count >= k)//可以建立匿名组了 { this.anonGroups.ks.Remove(k); HashSet<int> set = new HashSet<int>(); set.Add(this.Id); int i = 1; foreach (int nodeId in this.cachedCandidateNodes[k]) { if (i == k) break; set.Add(nodeId); i++; } this.anonGroups.groups.Add(k, set); PrintGroupNodes(set); PrivacyReader.rootReader = this; foreach (int nodeId in set) SendSetGroup(this.Id, this.Id, k, nodeId, set, new HashSet<int>(){nodeId}); return; } else if (scheduler.currentTime - this.cachedRecvRequest[groupident] >= global.native2WaitingTimeout)//使用native方法 { this.lastesth = 2; Console.WriteLine("{0:F4} [FALLBACK] {1}{2} start to use the native method", scheduler.currentTime, this.type, this.Id); SendNativeGroupRequest(this.lastesth, this.lastesth, k, this.Id); groupident = this.Id + "-" + k + "-" + this.lastesth; if(!this.pendingNativeGroupResponses.ContainsKey(groupident)) this.pendingNativeGroupResponses.Add(groupident, new Dictionary<int, NativeGroupResponseEntry>()); if(!this.cachedRecvRequest.ContainsKey(groupident)) this.cachedRecvRequest.Add(groupident, scheduler.currentTime); Event.AddEvent(new Event(scheduler.currentTime + 0.3f, EventType.CHK_NATGROUP, this, groupident)); return; } }
//收到子树的响应 public void RecvSubTreeInfo(Packet pkg) { if (pkg.Next != this.Id && pkg.Next!= BroadcastNode.Node.Id) return; if (pkg.Prev == Id && pkg.PrevType == type) return; if (this.Id != pkg.Dst) { this.retryOnSendingFailture = true; RoutePacket(pkg); this.retryOnSendingFailture = false; return; } int rootId = pkg.SubTreeInfo.rootId; List<int> newsubtree = pkg.SubTreeInfo.subtree; SubNodeStatus newstatus = (SubNodeStatus)pkg.SubTreeInfo.status; int newcn = pkg.SubTreeInfo.cn; int child = pkg.Src; string key = rootId + ""; if (!this.CachedTreeEntries.ContainsKey(key)) return; AnonyTreeEntry subTreeInfo = this.CachedTreeEntries[key]; //update是子树节点是否有更新 bool update = false; if (newstatus == SubNodeStatus.OUTSIDE)//对方为非匿名区域节点 { subTreeInfo.cn++; } else if (!subTreeInfo.subtree.ContainsKey(child)) //新的子节点 { if (newsubtree != null) { subTreeInfo.subtree.Add(child, new SubTreeEntry()); subTreeInfo.subtree[child].subnodeLastPing = scheduler.currentTime; foreach (int x in newsubtree) { subTreeInfo.subtree[child].subnodes.Add(x); } } if (newstatus != SubNodeStatus.RETRIEVING) subTreeInfo.cn += newcn; if (!subTreeInfo.subtree.ContainsKey(child)) subTreeInfo.subtree.Add(child, new SubTreeEntry()); subTreeInfo.subtree[child].subcn = newcn; subTreeInfo.subtree[child].status = newstatus; subTreeInfo.subtree[child].hops = 1; subTreeInfo.subtree[child].subnodeLastPing = scheduler.currentTime; } else { //更新子树 HashSet<int> subnodes = subTreeInfo.subtree[child].subnodes; int oldcn = subTreeInfo.subtree[child].subcn; List<int> temp = new List<int>(); foreach (int c in subnodes) { if (!newsubtree.Contains(c)) { temp.Add(c); update = true; } } foreach (int c in temp) { subnodes.Remove(c); } foreach (int x in newsubtree) { if (!subnodes.Contains(x)) { subnodes.Add(x); update = true; } } if (subTreeInfo.subtree[child].status != newstatus) update = true; subTreeInfo.cn = subTreeInfo.cn + (newcn - oldcn); subTreeInfo.subtree[child].subcn = newcn; subTreeInfo.subtree[child].status = newstatus; subTreeInfo.subtree[child].subnodeLastPing = scheduler.currentTime; } subTreeInfo.lastSubTreeUpdateTime = scheduler.currentTime; /* Console.WriteLine("{0}---{1}", child, newstatus); foreach (KeyValuePair<int, SubTreeEntry> pair in subTreeInfo.subtree) { int c = pair.Key; SubNodeStatus status = pair.Value.status; Console.WriteLine("{0}->{1}", c, status); } */ //update1是本区域是否还有等待的节点 bool update1 = true; if (scheduler.currentTime < subTreeInfo.checkSubTreeTime) update1 = false; else { foreach (KeyValuePair<int, SubTreeEntry> pair in subTreeInfo.subtree) { int c = pair.Key; SubNodeStatus status = pair.Value.status; if (status == SubNodeStatus.RETRIEVING && Utility.Distance(this, (Reader)Node.getNode(c, NodeType.READER)) < global.nodeMaxDist)//无需更新 { update1 = false; Console.WriteLine("reader{0} is still retrieving, waiting...", c); break; } } } List<int> sublist = getSubTreeNode(rootId); //Console.WriteLine("debug: cached subtree count {0}:{1}, update:{2}, update1:{3}", sublist.Count, Utility.DumpListIntSet(sublist), update, update1); if (this.Id != rootId)//中间节点 { //需要更新 if (update == true && update1 == true) { //Event.AddEvent(new Event(scheduler.CurrentTime + global.waitChildDelay, EventType.CHK_SUBTREE, this, new List<int>() { rootId })); List<int> list = getSubTreeNode(rootId); subTreeInfo.status = SubNodeStatus.NORMAL; SendSubTreeInfo(rootId, list, SubNodeStatus.NORMAL, subTreeInfo.cn, subTreeInfo.parent); } } else //根节点 { //检查 List<int> temp = new List<int>(); //找到所有达到要求的匿名组 foreach (int k in this.anonGroups.ks) { int totalUnavailAnonyNodeCout = GetTotalUnavailAnonyNodeCout(subTreeInfo, k); int totalNodeCount = getSubTreeCount(subTreeInfo.subtree) + 1; if (totalNodeCount - totalUnavailAnonyNodeCout >= k) { //DumpTreeNodes(k); temp.Add(k); } else//不满足要求 { //看看是否有节点未返回 foreach (int c in subTreeInfo.subtree.Keys) { SubTreeEntry subtree = subTreeInfo.subtree[c]; //还有一个子节点未返回结果 if (subtree.status == SubNodeStatus.RETRIEVING) { Console.WriteLine("debug: child READER{0} is still retrieving, waiting...", c); return; } } //全部有结果,则重来 Console.WriteLine("cached subtree: {0}", Utility.DumpListIntSet(getSubTreeNode(rootId))); //还没达到k要求,重新发送 Console.WriteLine("New round-----------------------------------------------------------------------"); int m = k - getSubTreeCount(subTreeInfo.subtree) - 1; foreach (KeyValuePair<int, SubTreeEntry> pair in subTreeInfo.subtree) { int c = pair.Key; SubTreeEntry e = pair.Value; if (m <= 0) break; if (e.subcn == 0) continue; //进位,不四舍五入了,合理的数为m*(e.subcn/subTreeInfo.cn)+1,但是为了加速,就乘以2, int newm = (int)(1 + 2 * m * ((float)e.subcn / subTreeInfo.cn)); SendTreeGroupRequest(this.Id, newm, c, -1, 0, 0, 0); Console.WriteLine("send to {0}, m:{1}", c, newm); } Console.WriteLine("total: {0}", getSubTreeCount(subTreeInfo.subtree) + 1); DumpTreeNodes(key, k); return; } } //发送setgroup请求 foreach (int k in temp) { string newgroupident = rootId + "-" + rootId + "-" + k; this.anonGroups.ks.Remove(k); if (!this.anonGroups.groups.ContainsKey(k)) this.anonGroups.groups.Add(k, new HashSet<int>()); HashSet<int> group = this.anonGroups.groups[k]; Dictionary<int, HashSet<int>> tempgroup = new Dictionary<int, HashSet<int>>(); if (!this.anonGroups.groups[k].Contains(this.Id)) this.anonGroups.groups[k].Add(this.Id); foreach (KeyValuePair<int, SubTreeEntry> pair in subTreeInfo.subtree) { int c = pair.Key; HashSet<int> l = pair.Value.subnodes; this.anonGroups.groups[k].Add(c); tempgroup.Add(c, new HashSet<int>()); tempgroup[c].Add(c); int end = 0; if (group.Count + l.Count + 1 > k) end = k - group.Count; else end = l.Count; int i = 0; foreach (int x in l) { if (i == end) break; this.anonGroups.groups[k].Add(x); tempgroup[c].Add(x); i++; } if (group.Count >= k) break; } foreach (KeyValuePair<int, HashSet<int>> pair in tempgroup) { int c = pair.Key; string ckey = c + "-" + k; HashSet<int> subnodes = pair.Value; if (!this.anonGroups.subUnavailAnonyNodes.ContainsKey(ckey)) this.anonGroups.subUnavailAnonyNodes.Add(ckey, new HashSet<int>()); Utility.AddHashSet(this.anonGroups.subUnavailAnonyNodes[ckey], subnodes); SendSetGroup(rootId, rootId, k, c, this.anonGroups.groups[k], subnodes);//这里rootId和origId应该是一样的 //TODO subUnavailAnonyNodeCounts在节点消失的时候应该减少的 } PrintGroupNodes(k); DumpTreeNodes(key, k); PrivacyReader.rootReader = this; //为建立新组作准备,将所有节点放到一个框内 if (PrivacyReader.AnonFrames.GetFrameCount() == 0) PrivacyReader.AnonFrames.Init(this.anonGroups.groups[k], this.Id, false); PrivacyReader.AnonFrames.DumpFrames(this.Id); } } Console.WriteLine("newstatus:{0}, current cn:{1}", newstatus, subTreeInfo.cn); }