예제 #1
0
        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);
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        //收到子树的响应
        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);
        }