/** * Default implementation for a merge. Picks the new coordinator among the coordinators of the old subviews * by getting all coords, sorting them and picking the first. Then the coord is added to the new list, and * all subviews are subsequently added.<p/> * Tries to minimize coordinatorship moving around between different members * @param subviews A list of membership lists, e.g. [{A,B,C}, {M,N,O,P}, {X,Y,Z}]. This is a merge between * 3 subviews. Guaranteed to be non-null (but may be empty) * @return The new membership. Needs to be non-null and cannot contain duplicates */ public List<Address> getNewMembership(final Collection<Collection<Address>> subviews) { // add the coord of each subview Membership coords=new Membership(); subviews.stream().filter(subview -> !subview.isEmpty()).forEach(subview -> coords.add(subview.iterator().next())); // pick the first coord of the sorted list as the new coord coords.sort(); Membership new_mbrs=new Membership().add(coords.elementAt(0)); // add all other members in the order in which they occurred in their subviews - dupes are not added subviews.forEach(new_mbrs::add); return new_mbrs.getMembers(); } }
/** * Clears the membership and adds all members of a given membership parameter. Prior to setting * membership this method will clear out all the old members of this membership by invoking the * {@code clear} method. * @param m a membership containing all the members this membership will contain */ public Membership set(Membership m) { clear(); if(m != null) add(m.getMembers()); return this; }
/** * Takes the existing membership list and removes suspected and left members, then adds new * members to the end of the list * @param current_members The list of current members. Guaranteed to be non-null (but may be empty) * @param joiners The joining members. Guaranteed to be non-null (but may be empty) * @param leavers Members that are leaving. Guaranteed to be non-null (but may be empty) * @param suspects Members which are suspected. Guaranteed to be non-null (but may be empty) * @return The new membership. Needs to be non-null and cannot contain duplicates */ public List<Address> getNewMembership(final Collection<Address> current_members, final Collection<Address> joiners, final Collection<Address> leavers, final Collection<Address> suspects) { Membership mbrs=new Membership(current_members).remove(leavers).remove(suspects).add(joiners); return mbrs.getMembers(); }
/** * Clears the membership and adds all members of v This method will clear out all the old members * of this membership by invoking the {@code Clear} method. Then it will add all the all * members provided in the vector v * * @param v * - a vector containing all the members this membership will contain */ public Membership set(Collection<Address> v) { clear(); return add(v); }
/** Returns the address of the merge leader */ protected Address determineMergeLeader(Map<Address,View> views) { // we need the merge *coordinators* not merge participants because not everyone can lead a merge ! Collection<Address> coords=Util.determineActualMergeCoords(views); if(coords.isEmpty()) coords=Util.determineMergeCoords(views); // https://issues.jboss.org/browse/JGRP-2092 if(coords.isEmpty()) { log.error("%s: unable to determine merge leader from %s; not starting a merge", gms.local_addr, views); return null; } return new Membership(coords).sort().elementAt(0); // establish a deterministic order, so that coords can elect leader }
/** Returns potential coordinator based on lexicographic ordering of member addresses. Another approach would be to keep track of the primary partition and return the first member if we are the primary partition. */ protected boolean iWouldBeCoordinator(Vector new_mbrs) { Membership tmp_mbrs=gms.members.copy(); tmp_mbrs.merge(new_mbrs, null); tmp_mbrs.sort(); return !(tmp_mbrs.size() <= 0 || gms.local_addr == null) && gms.local_addr.equals(tmp_mbrs.elementAt(0)); }
/** * Old default implementation for a merge. Adds all members into a list, sorts the list and returns it * @param subviews A list of membership lists, e.g. [{A,B,C}, {M,N,O,P}, {X,Y,Z}]. This is a merge between * 3 subviews. Guaranteed to be non-null (but may be empty) * @return The new membership. Needs to be non-null and cannot contain duplicates */ public static List<Address> getNewMembershipOld(final Collection<Collection<Address>> subviews) { Membership mbrs=new Membership(); subviews.forEach(mbrs::add); return mbrs.sort().getMembers(); }
/** * Called when a merge happened. The largest subview wins. */ public List<Address> getNewMembership(final Collection<Collection<Address>> subviews) { ArrayList<Collection<Address>> aSubviews=new ArrayList<>(subviews); int sLargest = 0; int iLargest = 0; for (int i = 0; i < aSubviews.size(); i++) { int size = aSubviews.get(i).size(); if (size > sLargest) { sLargest = size; iLargest = i; } } Membership mbrs = new Membership(aSubviews.get(iLargest)); for (int i = 0; i < aSubviews.size(); i++) if (i != iLargest) mbrs.add(aSubviews.get(i)); return mbrs.getMembers(); }
/** * Merges membership with the new members and removes suspects. * The Merge method will remove all the suspects and add in the new members. * It will do it in the order * 1. Remove suspects * 2. Add new members * the order is very important to notice. * * @param new_mems - a vector containing a list of members (Address) to be added to this membership * @param suspects - a vector containing a list of members (Address) to be removed from this membership */ public Membership merge(Collection<Address> new_mems, Collection<Address> suspects) { remove(suspects); return add(new_mems); }
List<Address> current_members=gms.members.getMembers(); if(gms.members.contains(mbr)) { // already joined: return current digest and membership log.trace("%s: %s already present; returning existing view %s", gms.local_addr, mbr, gms.view); Tuple<View,Digest> tuple=gms.getViewAndDigest();
public Membership add(Address ... mbrs) { for(Address mbr: mbrs) add(mbr); return this; }
/** * Computes the next view. Returns a copy that has {@code leavers} and * {@code suspected_mbrs} removed and {@code joiners} added. */ public View getNextView(Collection<Address> joiners, Collection<Address> leavers, Collection<Address> suspected_mbrs) { synchronized(members) { ViewId view_id=view != null? view.getViewId() : null; if(view_id == null) { log.error(Util.getMessage("ViewidIsNull")); return null; // this should *never* happen ! } long vid=Math.max(view_id.getId(), ltime) + 1; ltime=vid; List<Address> mbrs=computeNewMembership(tmp_members.getMembers(), joiners, leavers, suspected_mbrs); Address new_coord=!mbrs.isEmpty()? mbrs.get(0) : local_addr; View v=new View(new_coord, vid, mbrs); // Update membership (see DESIGN for explanation): tmp_members.set(mbrs); // Update joining list (see DESIGN for explanation) if(joiners != null) joiners.stream().filter(tmp_mbr -> !joining.contains(tmp_mbr)).forEach(joining::add); // Update leaving list (see DESIGN for explanations) if(leavers != null) leavers.stream().filter(addr -> !leaving.contains(addr)).forEach(leaving::add); if(suspected_mbrs != null) suspected_mbrs.stream().filter(addr -> !leaving.contains(addr)).forEach(leaving::add); return v; } }
Membership membership = new Membership(); membership.setPerson(person); membership.setPersonGroup(personGroup); personGroup.getMemberships().add(membership); membershipSession.persist(membership);
/** * Returns a copy of this membership * * @return an exact copy of this membership */ public Membership copy() { return new Membership(this.members); }
/** * Determines whether this member is the new coordinator given a list of suspected members. This is * computed as follows: the list of currently suspected members (suspected_mbrs) is removed from the current * membership. If the first member of the resulting list is equals to the local_addr, then it is true, * otherwise false. Example: own address is B, current membership is {A, B, C, D}, suspected members are {A, * D}. The resulting list is {B, C}. The first member of {B, C} is B, which is equal to the * local_addr. Therefore, true is returned. */ boolean wouldIBeCoordinator(Collection<Address> leaving_mbrs) { List<Address> mbrs=gms.computeNewMembership(gms.members.getMembers(), null, leaving_mbrs, suspected_mbrs); if(mbrs.isEmpty()) return false; Address new_coord=mbrs.get(0); return gms.local_addr.equals(new_coord); }
Map<Integer,Membership> map = new HashMap<Integer,Membership>(); Membership m = new Membership("First", "LastName", 1,1234567890); map.put(m.getId(), m);
if(!members.contains(msg.getSrc())) break;