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.daemon;
20  
21  
22  import java.io.IOException;
23  import java.io.ObjectInput;
24  import java.util.Collection;
25  import java.util.Iterator;
26  
27  import jgroup.core.EndPoint;
28  import jgroup.relacs.mss.MssConstants;
29  import jgroup.relacs.types.EndPointImpl;
30  import jgroup.relacs.types.GroupId;
31  import jgroup.relacs.types.GroupIndex;
32  import jgroup.util.MsgFactory;
33  import jgroup.util.OutMessage;
34  
35  
36  /**
37   *  The <code>MsgGroup</code> class
38   *
39   *  @author Alberto Montresor
40   *  @author Hein Meling
41   *  @since Jgroup 0.1
42   */
43  final class MsgGroup
44    implements MssConstants, DaemonMsg
45  {
46  
47    ////////////////////////////////////////////////////////////////////////////////////////////
48    // Position constants
49    ////////////////////////////////////////////////////////////////////////////////////////////
50  
51    private static final int START       = MSS_HEADER_SIZE;
52  
53  
54    ////////////////////////////////////////////////////////////////////////////////////////////
55    // Unique message instance
56    ////////////////////////////////////////////////////////////////////////////////////////////
57  
58    /**
59     * As these messages are never stored by the daemon, a single message
60     * instance is sufficient.  In this way, we save the costs of
61     * allocating and garbage collecting messages.
62     */
63    private static MsgGroup msg = new MsgGroup();
64  
65    /** The marshalled message data (also static for same reason as above) */
66    private static OutMessage outmsg;
67  
68  
69    ////////////////////////////////////////////////////////////////////////////////////////////
70    // Fields
71    ////////////////////////////////////////////////////////////////////////////////////////////
72  
73    /** List of host identifiers associated with the group */
74    EndPoint[] hosts;
75  
76  
77    ////////////////////////////////////////////////////////////////////////////////////////////
78    // Methods
79    ////////////////////////////////////////////////////////////////////////////////////////////
80  
81    /**
82     *  Returns a <code>MsgGroup</code> object that contains the decoding
83     *  of the m-received input stream.
84     *
85     *  @param msgstream   the message input stream to decode
86     */
87    static MsgGroup unmarshal(ObjectInput msgstream)
88      throws IOException, ClassNotFoundException
89    {
90      int len  = GroupIndex.unmarshal(msgstream);
91      msg.hosts = new EndPoint[len];
92      for (int i=0; i<len; i++) {
93        msg.hosts[i] = new EndPointImpl();
94        msg.hosts[i].readExternal(msgstream);
95      }
96  
97      return msg;
98    }
99  
100 
101   /**
102    *  Returns a output stream containing the encoding of a
103    *  <code>MsgGroup</code> message.
104    *
105    *  @param     gid       group identifier
106    */
107   static MsgGroup marshal(int gid, Collection list, int nreceivers)
108     throws IOException
109   {
110     // Allocates data buffer
111     int size = START + GroupId.SIZE + GroupIndex.SIZE + list.size() * EndPointImpl.SIZE;
112     outmsg = MsgFactory.get(size, nreceivers);
113     outmsg.seek(START);
114 
115     // Writes group id and number of hosts
116     GroupId.marshal(outmsg, gid);
117     GroupIndex.marshal(outmsg, list.size());
118 
119     // Writes hosts
120     Iterator iterator = list.iterator();
121     while (iterator.hasNext()) {
122       HostData scan = (HostData) iterator.next();
123       scan.getEndPoint().writeExternal(outmsg);
124     }
125     return msg;
126   }
127 
128 
129   ////////////////////////////////////////////////////////////////////////////////////////////
130   // Methods from DaemonMsg
131   ////////////////////////////////////////////////////////////////////////////////////////////
132 
133   public int size()
134   {
135     /* Note; it is ok to use the outmsg size since MsgGroup will never be
136      * forwarded or resent (it is not queued). */
137     return outmsg.size();
138   }
139 
140   public OutMessage getOutMessage()
141   {
142     return outmsg;
143   }
144 
145 
146   ////////////////////////////////////////////////////////////////////////////////////////////
147   // Methods from Object
148   ////////////////////////////////////////////////////////////////////////////////////////////
149 
150   /**
151    *  Returns a string representation of this object
152    */
153   public String toString()
154   {
155     StringBuilder buffer = new StringBuilder();
156     buffer.append("[MsgGroup: hosts={");
157     for (int i=0; i < hosts.length; i++) {
158       buffer.append(hosts[i]);
159       if (i < hosts.length-1)
160         buffer.append(", ");
161     }
162     buffer.append("}]");
163     return buffer.toString();
164   }
165 
166 } // END MsgGroup