예제 #1
0
        /// <summary> Merge all MergeData. All MergeData elements should be disjunct (both views and digests). However,
        /// this method is prepared to resolve duplicate entries (for the same member). Resolution strategy for
        /// views is to merge only 1 of the duplicate members. Resolution strategy for digests is to take the higher
        /// seqnos for duplicate digests.<p>
        /// After merging all members into a Membership and subsequent sorting, the first member of the sorted membership
        /// will be the new coordinator.
        /// </summary>
        /// <param name="v">A list of MergeData items. Elements with merge_rejected=true were removed before. Is guaranteed
        /// not to be null and to contain at least 1 member.
        /// </param>
        internal virtual MergeData consolidateMergeData(System.Collections.ArrayList v)
        {
            MergeData ret = null;
            MergeData tmp_data;
            long logical_time = 0; // for new_vid
            ViewId new_vid, tmp_vid;
            MergeView new_view;
            View tmp_view;
            Membership new_mbrs = new Membership();
            int num_mbrs = 0;
            Digest new_digest = null;
            Address new_coord;
            System.Collections.ArrayList subgroups = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(11));
            // contains a list of Views, each View is a subgroup

            for (int i = 0; i < v.Count; i++)
            {
                tmp_data = (MergeData)v[i];

                gms.Stack.NCacheLog.Debug("merge data is " + tmp_data);

                tmp_view = tmp_data.View;
                if (tmp_view != null)
                {
                    tmp_vid = tmp_view.Vid;
                    if (tmp_vid != null)
                    {
                        // compute the new view id (max of all vids +1)
                        logical_time = System.Math.Max(logical_time, tmp_vid.Id);
                    }
                }
                // merge all membership lists into one (prevent duplicates)
                new_mbrs.add(tmp_view.Members);
                subgroups.Add(tmp_view.Clone());
            }

            // the new coordinator is the first member of the consolidated & sorted membership list
            new_mbrs.sort();
            num_mbrs = new_mbrs.size();
            new_coord = num_mbrs > 0 ? (Address)new_mbrs.elementAt(0) : null;
            if (new_coord == null)
            {
                gms.Stack.NCacheLog.Error("CoordGmsImpl.consolodateMergeData", "new_coord is null.");
                return null;
            }
            // should be the highest view ID seen up to now plus 1
            new_vid = new ViewId(new_coord, logical_time + 1);

            // determine the new view
            new_view = new MergeView(new_vid, new_mbrs.Members, subgroups);

            gms.Stack.NCacheLog.Debug("new merged view will be " + new_view);

            // determine the new digest
            new_digest = consolidateDigests(v, num_mbrs);
            if (new_digest == null)
            {
                gms.Stack.NCacheLog.Error("CoordGmsImpl.consolidateMergeData", "digest could not be consolidated.");
                return null;
            }

            gms.Stack.NCacheLog.Debug("consolidated digest=" + new_digest);

            ret = new MergeData(gms.local_addr, new_view, new_digest);
            return ret;
        }
예제 #2
0
        /// <summary> Invoked upon receiving a MERGE event from the MERGE layer. Starts the merge protocol.
        /// See description of protocol in DESIGN.
        /// </summary>
        /// <param name="other_coords">A list of coordinators (including myself) found by MERGE protocol
        /// </param>
        public override void merge(System.Collections.ArrayList other_coords)
        {
            Membership tmp;
            Address leader = null;

            if (merging)
            {
                gms.Stack.NCacheLog.Warn("CoordGmsImpl.merge", "merge already in progress, discarded MERGE event");
                return;
            }

            if (other_coords == null)
            {
                gms.Stack.NCacheLog.Warn("CoordGmsImpl.merge", "list of other coordinators is null. Will not start merge.");
                return;
            }

            if (other_coords.Count <= 1)
            {
                gms.Stack.NCacheLog.Error("CoordGmsImpl.merge", "number of coordinators found is " + other_coords.Count + "; will not perform merge");
                return;
            }

            /* Establish deterministic order, so that coords can elect leader */
            tmp = new Membership(other_coords);
            tmp.sort();
            leader = (Address)tmp.elementAt(0);
            gms.Stack.NCacheLog.Debug("coordinators in merge protocol are: " + tmp);
            if (leader.Equals(gms.local_addr))
            {
                gms.Stack.NCacheLog.Debug("I (" + leader + ") will be the leader. Starting the merge task");
                startMergeTask(other_coords);
            }
        }