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.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