[Spread-cvs] cvs commit: spread/javalib MembershipInfo.java

jonathan at spread.org jonathan at spread.org
Tue Jul 12 09:50:34 EDT 2011


jonathan    04/10/29 17:13:10

  Modified:    javalib  MembershipInfo.java
  Log:
  Apply Ryan Caudy's rework of groups code to report multiple VS sets
  in membership messages. This breaks the SP API, althought some backwards
  compability code is included. Also fixes the Java interface to support
  new methods.
  
  Revision  Changes    Path
  1.4       +117 -30   spread/javalib/MembershipInfo.java
  
  Index: MembershipInfo.java
  ===================================================================
  RCS file: /storage/cvsroot/spread/javalib/MembershipInfo.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MembershipInfo.java	5 Mar 2004 00:37:12 -0000	1.3
  +++ MembershipInfo.java	29 Oct 2004 21:13:10 -0000	1.4
  @@ -70,20 +70,30 @@
   	///////////////////////
   	private Vector members;
   	
  -	// The group(s) that joined/left/disconeccted/stayed.
  -	/////////////////////////////////////////////////////
  -	private SpreadGroup groups[];
  -	
  +	// The private groups of members that joined/left/disconected/stayed.
  +	// For caused-by join/leave/disconnect, this has 1 element, with 1 member.
  +	// For caused-by network, this has 1 element for every virtual synchrony set,
  +  //  and each set has a variable number of members.
  +	/////////////////////////////////////////////////////////////////////////////
  +	private VirtualSynchronySet virtualSynchronySets[];
  +  
  +	// Null for caused-by join/leave/disconnect,
  +	// For caused-by network, points to vs-set for the SpreadConnection
  +	// that this was sent on.
  +	private VirtualSynchronySet myVirtualSynchronySet;
  +
   	// Constructor.
   	///////////////
  -	protected MembershipInfo(SpreadConnection connection, int serviceType, Vector groups, SpreadGroup sender, byte data[], boolean daemonEndianMismatch)
  -	{		
  +	protected MembershipInfo(SpreadConnection connection, int serviceType,
  +													 Vector groups, SpreadGroup sender,
  +													 byte data[], boolean daemonEndianMismatch)
  +	{
   		// Set local variables.
   		///////////////////////
   		this.serviceType = serviceType;
  -		this.group = sender;
  -		this.members = groups;
  -		
  +		this.group       = sender;
  +		this.members     = groups;
  +
   		// Is this a regular membership message.
   		////////////////////////////////////////
   		if(isRegularMembership())
  @@ -106,31 +116,53 @@
   				id[1] = SpreadConnection.flip(id[1]);
   				id[2] = SpreadConnection.flip(id[2]);
   			}
  -			
  +
   			// Create the group ID.
   			///////////////////////
   			this.groupID = new GroupID(id[0], id[1], id[2]);
  -			
  +
   			// Get the number of groups.
   			////////////////////////////
  -			int numGroups = SpreadConnection.toInt(data, dataIndex);
  -			if(daemonEndianMismatch)
  -			{
  -				numGroups = SpreadConnection.flip(numGroups);
  +			int numSets = SpreadConnection.toInt(data, dataIndex);
  +			if(daemonEndianMismatch) {
  +					numSets = SpreadConnection.flip(numSets);
   			}
   			dataIndex += 4;
  -			
  -			// Get the groups.
  -			//////////////////
  -			this.groups = new SpreadGroup[numGroups];
  -			for(int i = 0 ; i < numGroups ; i++)
  -			{
  -				this.groups[i] = connection.toGroup(data, dataIndex);
  -				dataIndex += connection.MAX_GROUP_NAME;
  +
  +			// Maybe this should throw a SpreadException if the number of sets
  +			// isn't positive, or if the offset isn't found, or if a set
  +			// doesn't have a positive number of members.  Older versions
  +			// did nothing of the kind, and trusted Spread, however.
  +
  +			int byteOffsetToLocalSet = SpreadConnection.toInt(data, dataIndex);
  +			if(daemonEndianMismatch) {
  +					byteOffsetToLocalSet = SpreadConnection.flip(byteOffsetToLocalSet);
  +			}
  +			dataIndex += 4;
  +
  +			int byteIndexOfFirstSet = dataIndex;
  +			virtualSynchronySets    = new VirtualSynchronySet[numSets];
  +
  +			// Get the virtual synchrony sets
  +			/////////////////////////////////
  +			for( int i = 0; i < numSets; ++i ) {
  +					int numMembers = SpreadConnection.toInt(data, dataIndex);
  +					if(daemonEndianMismatch) {
  +							numMembers = SpreadConnection.flip(numMembers);
  +					}
  +					virtualSynchronySets[i] = new VirtualSynchronySet(numMembers);
  +					if( byteOffsetToLocalSet == dataIndex - byteIndexOfFirstSet ) {
  +							myVirtualSynchronySet = virtualSynchronySets[i];
  +					}
  +					dataIndex += 4;
  +					for( int j = 0 ; j < numMembers ; ++j ) {
  +							virtualSynchronySets[i].addMember( connection.toGroup(data, dataIndex) );
  +							dataIndex += connection.MAX_GROUP_NAME;
  +					}
   			}
   		}
   	}
  -	
  +
   	// Checking the service-type.
   	/////////////////////////////
   	/**
  @@ -301,7 +333,7 @@
   	public SpreadGroup getJoined()
   	{
   		if((isRegularMembership()) && (isCausedByJoin()))
  -			return groups[0];
  +			return virtualSynchronySets[0].getMembers()[0];
   		return null;
   	}
   	
  @@ -320,7 +352,7 @@
   	{
   		if((isRegularMembership()) && 
   		   ( isCausedByLeave() || isCausedByDisconnect() ) )
  -			return groups[0];
  +			return virtualSynchronySets[0].getMembers()[0];
   		return null;
   	}
   	
  @@ -338,7 +370,7 @@
   	public SpreadGroup getDisconnected()
   	{
   		if((isRegularMembership()) && (isCausedByDisconnect()))
  -			return groups[0];
  +			return virtualSynchronySets[0].getMembers()[0];
   		return null;
   	}
   	
  @@ -352,11 +384,66 @@
   	 * 
   	 * @return  the private groups of the members who were not partitioned
   	 * @see  MembershipInfo#isCausedByNetwork()
  +	 * @deprecated -- new code should use the methods below.  This implementation
  +	 *                is provided for backwards-compatibility only.
   	 */
   	public SpreadGroup[] getStayed()
   	{
  -		if((isRegularMembership()) && (isCausedByNetwork()))
  -			return groups;
  +			VirtualSynchronySet set = getMyVirtualSynchronySet();
  +			if( set == null ) {
  +					return null;
  +			}
  +			return set.getMembers();
  +	}
  +
  +	// Get all the virtual synchrony sets from the associated membership
  +	// message.
  +	public VirtualSynchronySet[] getVirtualSynchronySets() {
  +		if( isRegularMembership() && isCausedByNetwork() ) {
  +			return virtualSynchronySets;
  +		}
   		return null;
   	}
  -}
  +
  +	// Get my own virtual synchrony set.
  +	public VirtualSynchronySet getMyVirtualSynchronySet() {
  +		if( isRegularMembership() && isCausedByNetwork() ) {
  +			return myVirtualSynchronySet;
  +		}
  +		return null;
  +	}
  +
  +
  +	// This inner class is basically just a wrapper around an array of
  +	// SpreadGroups.  It is intended for use to represent the private group
  +	// names of a set of members known to have been virtually synchronous
  +	// in their last membership (before the membership represented by
  +	// this MembershipInfo).
  +	public class VirtualSynchronySet {
  +
  +		private int size;
  +		private SpreadGroup privateGroups[];
  +
  +		protected VirtualSynchronySet(int capacity) {
  +			size          = 0;
  +			privateGroups = new SpreadGroup[capacity];
  +		}
  +
  +		public int getCapacity() {
  +			return privateGroups.length;
  +		}
  +
  +		public int getSize() {
  +			return size;
  +		}
  +
  +		public SpreadGroup[] getMembers() {
  +			return privateGroups;
  +		}
  +
  +		public void addMember(SpreadGroup member) {
  +			privateGroups[size++] = member;
  +		}
  +	}
  +
  +} // end class
  
  
  




More information about the Spread-cvs mailing list