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