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