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