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.util; 20 21 import jgroup.core.ConfigurationException; 22 import jgroup.relacs.mss.FCEntry; 23 import jgroup.relacs.mss.MsgRouting; 24 import jgroup.relacs.mss.MssConstants; 25 import jgroup.relacs.types.EndPointImpl; 26 import jgroup.relacs.types.GroupIndex; 27 import jgroup.relacs.types.MessageTag; 28 29 /** 30 * The <code>MsgFactory</code> is used to create messages valid for the 31 * Jgroup Mss layer. 32 * 33 * @author Alberto Montresor 34 * @author Hein Meling 35 * @since Jgroup 0.8 36 */ 37 public final class MsgFactory 38 implements MssConstants 39 { 40 41 //////////////////////////////////////////////////////////////////////////////////////////// 42 // Fields 43 //////////////////////////////////////////////////////////////////////////////////////////// 44 45 /** 46 * Constants for the message factory. 47 */ 48 private static int payload; 49 private static int header; 50 private static int trailer; 51 52 /* Static part of the message size */ 53 private static int msgJGsize = MessageTag.SIZE + GroupIndex.SIZE*2; 54 55 /** 56 * Static instance of the message factory. 57 */ 58 private static MsgFactory msgFactory; 59 60 61 //////////////////////////////////////////////////////////////////////////////////////////// 62 // Static initialization method 63 //////////////////////////////////////////////////////////////////////////////////////////// 64 65 public static void initMsgFactory(int payload, int numOfHosts, int numOfClusters) 66 throws ConfigurationException 67 { 68 /* 69 * We simply return if multiple initializations were issued. That 70 * is we assume all GroupManagers in the same JVM use the same 71 * TransportConfig object. 72 */ 73 if (msgFactory != null) 74 return; 75 int minPayload = computeMinPayload(numOfHosts, numOfClusters); 76 if (payload < minPayload) { 77 throw new ConfigurationException("The payload is too small for this distributed system: " 78 + minPayload + " is the smallest payload for the current configuration"); 79 } 80 msgFactory = new MsgFactory(payload, HEADER_SIZE, TRAILER_SIZE, numOfHosts); 81 } 82 83 /** 84 * Compute the minimal payload, since we don't want to fragment 85 * certain low level messages. Note that <code>MsgRouting</code> 86 * messages will always be larger than <code>MsgIamAlive</code> 87 * messages, thus we only need to return the largest possible payload 88 * that a routing message may introduce. 89 */ 90 private static int computeMinPayload(int numOfHosts, int numOfClusters) 91 { 92 return MsgRouting.getMaxSize(numOfHosts, numOfClusters); 93 } 94 95 96 //////////////////////////////////////////////////////////////////////////////////////////// 97 // Private constructor 98 //////////////////////////////////////////////////////////////////////////////////////////// 99 100 /** 101 * 102 */ 103 private MsgFactory(int payl, int headr, int trailr, int numOfHosts) 104 { 105 payload = payl; 106 header = headr; 107 trailer = trailr; 108 /* Compute partially the dynamic size of the message */ 109 msgJGsize += FCEntry.SIZE*numOfHosts; 110 } 111 112 113 //////////////////////////////////////////////////////////////////////////////////////////// 114 // Access methods 115 //////////////////////////////////////////////////////////////////////////////////////////// 116 117 /** 118 * 119 */ 120 public static OutMessage get() 121 { 122 return new OutMessage(payload, header, trailer); 123 } 124 125 126 /** 127 * 128 */ 129 public static OutMessage get(int size) 130 { 131 return new OutMessage(payload, header, trailer, size); 132 } 133 134 135 /** 136 * 137 */ 138 public static OutMessage get(int size, int nreceivers) 139 { 140 /* Finalize computing the dynamic size of the message */ 141 size += msgJGsize + EndPointImpl.SIZE*nreceivers; 142 return new OutMessage(payload, header, trailer, size); 143 } 144 145 } // END MsgFactory