View Javadoc

1   /*
2    * Copyright (c) 1998-2002 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  
19  package jgroup.relacs.types;
20  
21  import java.io.IOException;
22  import java.io.ObjectInput;
23  import java.io.ObjectOutput;
24  
25  import jgroup.core.EndPoint;
26  import jgroup.core.MemberId;
27  import net.jini.jeri.Endpoint;
28  import net.jini.jeri.tcp.TcpEndpoint;
29  
30  /**
31   *  Implementation of the <code>jgroup.core.MemberId</code> interface.
32   *
33   *  @author Alberto Montresor
34   *  @author Hein Meling
35   *  @since Jgroup 0.9
36   */
37  final public class MemberIdImpl
38    implements MemberId
39  {
40  
41    ////////////////////////////////////////////////////////////////////////////////////////////
42    // Constants
43    ////////////////////////////////////////////////////////////////////////////////////////////
44  
45    private static final long serialVersionUID = -6545889514187752437L;
46  
47    public static final int SIZE = EndPointImpl.SIZE + IncarnationId.SIZE + LocalId.SIZE;
48  
49   
50    ////////////////////////////////////////////////////////////////////////////////////////////
51    // Fields
52    ////////////////////////////////////////////////////////////////////////////////////////////
53  
54    /** Endpoint of the machine hosting the Jgroup Daemon */
55    private EndPoint endpoint;
56    
57    /** Value used to distinguish different incarnation of the same host */
58    private int incarnation;
59    
60    /** The local identifier for a member associated with a Jgroup daemon */
61    private LocalId localId;
62  
63    
64    ////////////////////////////////////////////////////////////////////////////////////////////
65    // Constructors
66    ////////////////////////////////////////////////////////////////////////////////////////////
67  
68    /**
69     *  Default constructor for externalization
70     */
71    public MemberIdImpl() { }
72  
73  
74    /**
75     *  Builds a new <code>MemberId</code> with the specified arguments.
76     */
77    public MemberIdImpl(EndPoint endpoint, int incarnation,
78      EndPoint localEndPoint, int count)
79    {
80      this.endpoint = endpoint;
81      this.incarnation = incarnation;
82      this.localId = new LocalId(count, localEndPoint);
83    }
84  
85  
86    /**
87     *  Builds a new <code>MemberId</code> with the specified arguments.
88     */
89    public MemberIdImpl(EndPoint endpoint, int incarnation, LocalId localId)
90    {
91      this.endpoint = endpoint;
92      this.incarnation = incarnation;
93      this.localId = localId;
94    }
95  
96  
97    ////////////////////////////////////////////////////////////////////////////////////////////
98    // Methods from MemberId interface
99    ////////////////////////////////////////////////////////////////////////////////////////////
100 
101 
102   /* (non-Javadoc)
103    * @see jgroup.core.MemberId#getEndPoint()
104    */
105   public EndPoint getEndPoint()
106   {
107     return endpoint;
108   }
109   
110   /* (non-Javadoc)
111    * @see jgroup.core.MemberId#getTcpEndpoint()
112    */
113   public Endpoint getTcpEndpoint()
114   {
115     String hostname = getCanonicalHostName();
116     int port = getServerPort();
117     return TcpEndpoint.getInstance(hostname, port);
118   }
119 
120   /* (non-Javadoc)
121    * @see jgroup.core.MemberId#getLocalId()
122    */
123   public LocalId getLocalId()
124   {
125     return localId;
126   }
127 
128   /* (non-Javadoc)
129    * @see jgroup.core.MemberId#getCanonicalHostName()
130    */
131   public String getCanonicalHostName()
132   {
133     return localId.getEndpoint().getAddress().getCanonicalHostName();
134   }
135 
136   /* (non-Javadoc)
137    * @see jgroup.core.MemberId#getServerPort(int)
138    */
139   public int getServerPort()
140   {
141     /*
142      * The port to use is deterministic, and associated directly
143      * with the local member, which may be in the same JVM
144      * as the Jgroup Daemon (or may not be in the same JVM).
145      */
146     return localId.getMemberNo() + localId.getEndpoint().getPort();
147   }
148 
149   /* (non-Javadoc)
150    * @see jgroup.core.MemberId#isNewer(jgroup.core.MemberId)
151    */
152   public boolean isNewer(MemberId obj)
153   {
154     if (obj == null)
155       return false;
156     MemberIdImpl id = (MemberIdImpl)obj;
157     return (incarnation > id.incarnation
158       && localId.equals(id.localId)
159       && endpoint.equals(id.endpoint));
160   }
161 
162   /* (non-Javadoc)
163    * @see jgroup.core.MemberId#isNeighbour(jgroup.core.MemberId)
164    */
165   public boolean isNeighbour(MemberId obj)
166   {
167     if (obj == null)
168       return false;
169     MemberIdImpl id = (MemberIdImpl)obj;
170     return (incarnation == id.incarnation
171       && localId.equals(id.localId)
172       && endpoint.equals(id.endpoint));
173   }
174 
175 
176   /**
177    *  Compares this member with the given member for the purpose of sorting.
178    *  This is used to define th partial order for all the members in a group.
179    *  <p>
180    * 
181    *  @return
182    *     Returns a positive value if and only if this <code>EndPoint</code> is
183    *     greater than the given one, or this <code>EndPoint</code> is equal to
184    *     the given one and this local id is greater than the given one. <p>
185    * 
186    *     We return zero if the members have the same id; that is the same EndPoint
187    *     and the same localId.  We do not consider the incarnation value. <p>
188    * 
189    *     Otherwise, we returns a negative value.
190    *
191    *  @see jgroup.core.MemberId
192    */
193   public int compareTo(MemberId member)
194   {
195     if (this == member) {
196       return 0;
197     } else {
198       int epValue = endpoint.compareTo(member.getEndPoint());
199       if (epValue == 0) {
200         return (localId.getMemberNo() - member.getLocalId().getMemberNo());
201       } else {
202         return epValue;
203       }
204     }
205   }
206 
207 
208   ////////////////////////////////////////////////////////////////////////////////////////////
209   // Object methods
210   ////////////////////////////////////////////////////////////////////////////////////////////
211 
212   /**
213    *  Returns a string representation of the object.
214    */
215   public String toString()
216   {
217     StringBuilder buf = new StringBuilder("[");
218     buf.append(endpoint);
219     if (!localId.getEndpoint().equals(endpoint)) {
220       buf.append(", ");
221       buf.append(localId);
222     } else {
223       buf.append(".");
224       buf.append(localId.getMemberNo());
225     }
226 //    buf.append(", ");
227 //    buf.append(incarnation);
228     buf.append("]");
229     return buf.toString();
230   }
231 
232 
233   /**
234    *  Returns a hashcode for the <code>MemberId</code>.  Two
235    *  <code>MemberId</code>s will have the same hashcode if they are
236    *  equal with respect to their content.
237    *
238    *  @return the hashcode
239    */
240   public int hashCode()
241   {
242     return endpoint.hashCode() + incarnation + localId.hashCode();
243   }
244 
245   /**
246    *  Compares two <code>MemberIdImpl</code>s for content equality.
247    *
248    *  @param obj
249    *    The object to compare with
250    *  @return 
251    *    True if these objects are equal; false otherwise.
252    */
253   public boolean equals(Object obj)
254   {
255     if (!(obj instanceof MemberIdImpl))
256       return false;
257     MemberIdImpl id = (MemberIdImpl) obj;
258     return (incarnation == id.incarnation
259       && localId.equals(id.localId)
260       && endpoint.equals(id.endpoint));
261   }
262 
263   ////////////////////////////////////////////////////////////////////////////////////////////
264   // Methods for externalization
265   ////////////////////////////////////////////////////////////////////////////////////////////
266 
267   
268   /**
269    *  Restores the content of this object from the marshalled data contained
270    *  in the specified input stream.
271    * 
272    *  @param in the stream to be read
273    */
274   public void readExternal(ObjectInput in)
275     throws IOException, ClassNotFoundException
276   {
277     endpoint = new EndPointImpl();
278     endpoint.readExternal(in);
279     incarnation = IncarnationId.unmarshal(in);
280     localId = new LocalId();
281     localId.readExternal(in);
282   }
283 
284   /**
285    *  Marshals the content of this object to the specified output stream.
286    * 
287    *  @param out the stream to be written
288    */
289   public void writeExternal(ObjectOutput out)
290     throws IOException
291   {
292     endpoint.writeExternal(out);
293     IncarnationId.marshal(out, incarnation);
294     localId.writeExternal(out);
295   }
296 
297 } // END MemberIdImpl