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.mss;
20  
21  import java.io.Externalizable;
22  import java.io.IOException;
23  import java.io.ObjectInput;
24  import java.io.ObjectOutput;
25  
26  import jgroup.core.EndPoint;
27  import jgroup.relacs.types.EndPointImpl;
28  import jgroup.relacs.types.GroupIndex;
29  import jgroup.relacs.types.IncarnationId;
30  
31  /**
32   *  The <code>TopologyEntry</code> class
33   *
34   *  @author Salvatore Cammarata
35   *  @author Hein Meling
36   *  @since Jgroup 1.2
37   */
38  final class TopologyEntry 
39  implements Externalizable
40  {
41  
42    ////////////////////////////////////////////////////////////////////////////////////////////
43    // Fields
44    ////////////////////////////////////////////////////////////////////////////////////////////
45  
46    /** */
47    RoutingTableEntry routing;
48  
49    /** */
50    EndPoint[] reachable;
51  
52    /** */
53    int[] incarnationId;
54  
55    /** The number of bytes required to marshal this topology entry instance */
56    private transient int marshalSize;
57  
58  
59    ////////////////////////////////////////////////////////////////////////////////////////////
60    // Constructors
61    ////////////////////////////////////////////////////////////////////////////////////////////
62  
63    /** 
64     *  Default constructor for externalization
65     */
66    TopologyEntry() 
67    {
68    }
69  
70  
71    /**
72     *  
73     */
74    TopologyEntry(RoutingTableEntry rt, MssHost[] members)
75    {
76      marshalSize = RoutingTableEntry.SIZE + GroupIndex.SIZE
77        + members.length*(EndPointImpl.SIZE + IncarnationId.SIZE);
78      routing = rt;
79      reachable = new EndPoint[members.length];
80      incarnationId = new int[members.length];
81      for (int i = 0; i < members.length; i++) {
82        reachable[i] = members[i].getEndPoint();
83        incarnationId[i] = members[i].getIncarnationId();
84      }
85    }
86  
87  
88    ////////////////////////////////////////////////////////////////////////////////////////////
89    // Methods
90    ////////////////////////////////////////////////////////////////////////////////////////////
91  
92    /**
93     *  Returns the number of bytes required to marshal this topology
94     *  entry instance.
95     */
96    public int getMarshalSize()
97    {
98      return marshalSize;
99    }
100 
101 
102   /**
103    *  Returns the maximum number of bytes required to marshal a topology
104    *  entry instance, when the reachability set includes all hosts in
105    *  the system.
106    */
107   public static int getMaxSize(int maxNumOfHosts)
108   {
109     return (RoutingTableEntry.SIZE + GroupIndex.SIZE
110       + maxNumOfHosts*(EndPointImpl.SIZE + IncarnationId.SIZE));
111   }
112 
113 
114   /**
115    *  Updates the reachability information for the cluster associated
116    *  with this <code>TopologyEntry</code> object.
117    */
118   public boolean updateReachability(MssHost[] members)
119   {
120     boolean changed = false;
121     /*
122      * This at least avoids creating new arrays, if the new set is the
123      * same size as before.
124      */
125     if (reachable.length != members.length) {
126       reachable = new EndPoint[members.length];
127       incarnationId = new int[members.length];
128       marshalSize = RoutingTableEntry.SIZE + GroupIndex.SIZE
129         + members.length*(EndPointImpl.SIZE + IncarnationId.SIZE);
130       changed = true;
131     }
132     for (int i = 0; i < members.length; i++) {
133       reachable[i] = members[i].getEndPoint();
134       incarnationId[i] = members[i].getIncarnationId();
135     }
136     return changed;
137   }
138 
139 
140   ////////////////////////////////////////////////////////////////////////////////////////////
141   // Methods for externalization
142   ////////////////////////////////////////////////////////////////////////////////////////////
143 
144   /**
145    *  Restores the content of this object from the marshalled data contained
146    *  in the specified input stream.
147    * 
148    *  @param in the stream to be read
149    */
150   public void readExternal(ObjectInput in)
151     throws IOException, ClassNotFoundException
152   {
153     routing = new RoutingTableEntry();
154     routing.readExternal(in);
155     int len = GroupIndex.unmarshal(in);
156     reachable = new EndPoint[len];
157     incarnationId = new int[len];
158     for (int i=0; i<len; i++){
159       reachable[i] = new EndPointImpl();
160       reachable[i].readExternal(in);  
161       incarnationId[i] = IncarnationId.unmarshal(in);
162     }
163   }   
164 
165 
166   /**
167    *  Marshals the content of this object to the specified output stream.
168    * 
169    *  @param out the stream to be written
170    */
171   public void writeExternal(ObjectOutput out)
172     throws IOException
173   {
174     routing.writeExternal(out);
175     GroupIndex.marshal(out, reachable.length);
176     for (int i=0; i<reachable.length; i++) {
177       reachable[i].writeExternal(out);
178       IncarnationId.marshal(out,incarnationId[i]);
179     }
180   }
181 
182 
183   ////////////////////////////////////////////////////////////////////////////////////////////
184   // Object methods
185   ////////////////////////////////////////////////////////////////////////////////////////////
186 
187   /**
188    *  Returns a string representation of this object
189    */
190   public String toString() 
191   {
192     StringBuilder buf = new StringBuilder("[TopologyEntry: routing=");
193     buf.append(routing);
194     buf.append(", size=");
195     buf.append(reachable.length);
196     buf.append(", reachable={");
197     for (int i = 0; i < reachable.length; i++) {
198       buf.append((i != 0) ? ", " : "");
199       buf.append(reachable[i]);
200       buf.append(":");
201       buf.append(incarnationId[i]);
202     }
203     buf.append("}]");
204     return buf.toString();
205   } 
206 
207 } // END TopologyEntry