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  
20  package jgroup.relacs.daemon;
21  
22  import java.io.IOException;
23  import java.io.ObjectInput;
24  
25  import jgroup.core.MemberId;
26  import jgroup.relacs.mss.MssConstants;
27  import jgroup.relacs.types.Flag;
28  import jgroup.relacs.types.GroupId;
29  import jgroup.relacs.types.GroupIndex;
30  import jgroup.relacs.types.MemberIdImpl;
31  import jgroup.relacs.types.MessageId;
32  import jgroup.relacs.types.ViewId;
33  import jgroup.util.MsgFactory;
34  import jgroup.util.OutMessage;
35  
36  /**
37   *
38   * @author  Alberto Montresor
39   * @since   Jgroup 0.8
40   */
41  final class MsgResult
42    implements MssConstants, DaemonMsg
43  {
44  
45    ////////////////////////////////////////////////////////////////////////////////////////////
46    // Position constants
47    ////////////////////////////////////////////////////////////////////////////////////////////
48  
49    private static final int START  = MSS_HEADER_SIZE;
50  
51  
52    ////////////////////////////////////////////////////////////////////////////////////////////
53    // Fields
54    ////////////////////////////////////////////////////////////////////////////////////////////
55  
56    /** Group identifier */
57    int gid;
58  
59    /** View identifier */
60    long vid;
61  
62    /** Message identifier */
63    int mid;
64    
65    /**
66     * Identifier of the sender of the message to which this message is a
67     * response.
68     */
69    MemberId sender;
70    
71    /** Number of messages delivered by all local members */
72    int dlvr;
73    
74    /** Host index in the view */
75    int hpos;
76    
77    /** Member index in the view */
78    int vpos;
79    
80    /** Result value */
81    Object result;         
82  
83    /** The marshalled message stream for this object */
84    private OutMessage outmsg;
85  
86  
87    ////////////////////////////////////////////////////////////////////////////////////////////
88    // Constructors
89    ////////////////////////////////////////////////////////////////////////////////////////////
90  
91    /**
92     *  Default constructors used to create an empty ResultMessage in the
93     *  decoding process.
94     */
95    MsgResult()
96    {
97    }
98    
99    /**
100    *  Default constructors used to create an empty ResultMessage in the
101    *  decoding process.
102    */
103   MsgResult(int gid, long vid, int mid, MemberId sender, int dlvr, int hpos, int vpos, 
104     Object result)
105   {
106     this.gid = gid;
107     this.vid = vid;
108     this.mid = mid;
109     this.sender = sender;
110     this.dlvr = dlvr;
111     this.hpos = hpos;
112     this.vpos = vpos;
113     this.result = result;
114   }
115   
116   
117   ////////////////////////////////////////////////////////////////////////////////////////////
118   // Methods
119   ////////////////////////////////////////////////////////////////////////////////////////////
120 
121   /**
122    *  Returns an output stream containing the encoding of this message.
123    */
124   MsgResult marshal(int nreceivers)
125     throws IOException
126   {
127     outmsg = marshal(gid, vid, mid, sender, dlvr, hpos, vpos, result, nreceivers);
128     return this;
129   }
130   
131   
132   ////////////////////////////////////////////////////////////////////////////////////////////
133   // Static methods
134   ////////////////////////////////////////////////////////////////////////////////////////////
135 
136   /**
137    *  Returns a <code>MsgResult</code> object that contains the decoding
138    *  of an m-received input stream.
139    *
140    *  @param stream    the message input stream to decode
141    */
142   static MsgResult unmarshal(ObjectInput stream)
143     throws IOException, ClassNotFoundException
144   {
145     /*
146      * Currently, this message type cannot be a singleton since the
147      * SendBuffer class stores instances of MsgResult in its ackbuffer.
148      */
149     MsgResult msg = new MsgResult();
150 
151     msg.vid    = ViewId.unmarshal(stream);
152     msg.mid    = MessageId.unmarshal(stream);
153     msg.sender = new MemberIdImpl();
154     msg.sender.readExternal(stream);
155     msg.dlvr   = MessageId.unmarshal(stream);
156     msg.hpos   = GroupIndex.unmarshal(stream);
157     msg.vpos   = GroupIndex.unmarshal(stream);
158     // check if stream contains a result object.
159     if (Flag.unmarshal(stream)) {
160       msg.result = stream.readObject();
161     }
162     return msg;
163   }
164 
165   /**
166    *  Returns a output stream containing the encoding of a
167    *  <code>MsgResult</code> message.
168    *
169    *  @param     gid     group identifier
170    *  @param     vid     current view identifier
171    *  @param     mid     identifier of the original message to which this message is a response
172    *  @param     sender  identifier of the sender of the original message to which this message is
173    *    a response
174    *  @param     hpos    host index in the view
175    *  @param     mpos    member index in the view
176    *  @param     result  result value
177    */
178   private static OutMessage marshal(int gid, long vid, int mid, MemberId sender, int dlvr, int hpos,
179                             int vpos, Object result, int nreceivers)
180     throws IOException
181   {
182     OutMessage stream;
183 
184     // Allocates data buffer
185     if (result == null) {
186       int size = START + GroupId.SIZE + ViewId.SIZE + MessageId.SIZE * 2 + 
187                  GroupIndex.SIZE*2 + MemberIdImpl.SIZE + Flag.SIZE;
188       stream = MsgFactory.get(size, nreceivers);
189     } else {
190       stream = MsgFactory.get();
191     }
192     stream.seek(START);
193 
194     // Writes single data
195     GroupId.marshal(stream, gid);
196     ViewId.marshal(stream, vid);
197     MessageId.marshal(stream, mid);
198     sender.writeExternal(stream);
199     MessageId.marshal(stream, dlvr);
200     GroupIndex.marshal(stream, hpos);
201     GroupIndex.marshal(stream, vpos);
202     boolean hasResult = (result != null);
203     Flag.marshal(stream, hasResult);
204     if (hasResult) {
205       stream.writeObject(result);
206     }
207     return stream;
208   }
209 
210 
211   ////////////////////////////////////////////////////////////////////////////////////////////
212   // Methods from DaemonMsg
213   ////////////////////////////////////////////////////////////////////////////////////////////
214 
215   public int size()
216   {
217     /* Note; it is ok to use the outmsg size since MsgResult will never be
218      * forwarded or resent (it is queued, but only to deliver later, I think). */
219     return outmsg.size();
220   }
221 
222   public OutMessage getOutMessage()
223   {
224     return outmsg;
225   }
226 
227 
228   ////////////////////////////////////////////////////////////////////////////////////////////
229   // Methods from Object
230   ////////////////////////////////////////////////////////////////////////////////////////////
231 
232   /**
233    *  Returns a string representation of this object
234    */
235   public String toString()
236   {
237     StringBuilder buf = new StringBuilder();
238     buf.append("[MsgResult: gid=");
239     buf.append(gid);
240     buf.append(", vid=");
241     buf.append(vid);
242     buf.append(", mid=");
243     buf.append(mid);
244     buf.append(", sender=");
245     buf.append(sender);
246     buf.append(", dlvr=");
247     buf.append(dlvr);
248     buf.append(", hpos=");
249     buf.append(hpos);
250     buf.append(", vpos=");
251     buf.append(vpos);
252     buf.append(", result=");
253     buf.append(result);
254     return buf.toString();
255   }
256 
257 } // END MsgResult