View Javadoc
1   //******************************************************************************
2   //
3   // File:    Buf.java
4   // Package: edu.rit.mp
5   // Unit:    Class edu.rit.mp.Buf
6   //
7   // This Java source file is copyright (C) 2007 by Alan Kaminsky. All rights
8   // reserved. For further information, contact the author, Alan Kaminsky, at
9   // ark@cs.rit.edu.
10  //
11  // This Java source file is part of the Parallel Java Library ("PJ"). PJ is free
12  // software; you can redistribute it and/or modify it under the terms of the GNU
13  // General Public License as published by the Free Software Foundation; either
14  // version 3 of the License, or (at your option) any later version.
15  //
16  // PJ is distributed in the hope that it will be useful, but WITHOUT ANY
17  // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18  // A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19  //
20  // Linking this library statically or dynamically with other modules is making a
21  // combined work based on this library. Thus, the terms and conditions of the GNU
22  // General Public License cover the whole combination.
23  //
24  // As a special exception, the copyright holders of this library give you
25  // permission to link this library with independent modules to produce an
26  // executable, regardless of the license terms of these independent modules, and
27  // to copy and distribute the resulting executable under terms of your choice,
28  // provided that you also meet, for each linked independent module, the terms
29  // and conditions of the license of that module. An independent module is a module
30  // which is not derived from or based on this library. If you modify this library,
31  // you may extend this exception to your version of the library, but you are not
32  // obligated to do so. If you do not wish to do so, delete this exception
33  // statement from your version.
34  //
35  // A copy of the GNU General Public License is provided in the file gpl.txt. You
36  // may also obtain a copy of the GNU General Public License on the World Wide
37  // Web at http://www.gnu.org/licenses/gpl.html.
38  //
39  //******************************************************************************
40  package edu.rit.mp;
41  
42  import java.io.IOException;
43  import java.nio.ByteBuffer;
44  
45  import edu.rit.pj.reduction.Op;
46  
47  /**
48   * Class Buf is the abstract base class for a buffer of items sent or received
49   * using the Message Protocol (MP).
50   * <P>
51   * A buffer may be used to send one or more messages at the same time in
52   * multiple threads. If a buffer is being used to send a message or messages,
53   * the buffer must not be used to receive a message at the same time.
54   * <P>
55   * A buffer may be used to receive one message at a time. If a buffer is being
56   * used to receive a message, the buffer must not be used to receive another
57   * message in a different thread, and the buffer must not be used to send a
58   * message or messages.
59   * <P>
60   * A buffer is a conduit for retrieving and storing data in some underlying data
61   * structure. If the underlying data structure is multiple thread safe, then one
62   * thread can be retrieving or storing data via the buffer at the same time as
63   * other threads are accessing the data structure. If the underlying data
64   * structure is not multiple thread safe, then other threads must not access the
65   * data structure while one thread is retrieving or storing data via the buffer.
66   *
67   * @author Alan Kaminsky
68   * @version 03-May-2008
69   */
70  public abstract class Buf {
71  
72  // Hidden data members.
73      /**
74       * Number of items in this buffer.
75       */
76      protected final int myLength;
77  
78      // Type and length sent or received in a message.
79      byte myMessageType;
80      int myMessageLength;
81  
82  // Hidden constructors.
83      /**
84       * Construct a new buffer.
85       *
86       * @param theType Item type.
87       * @param theLength Number of items.
88       *
89       * @exception IllegalArgumentException (unchecked exception) Thrown if
90       * <code>theLength</code> &lt; 0.
91       */
92      Buf(byte theType,
93              int theLength) {
94          if (theLength < 0) {
95              throw new IllegalArgumentException("edu.rit.mp.Buf(): theLength = " + theLength + " illegal");
96          }
97          myLength = theLength;
98          myMessageType = theType;
99          myMessageLength = theLength;
100     }
101 
102 // Exported operations.
103     /**
104      * Obtain the number of items in this buffer.
105      *
106      * @return Number of items.
107      */
108     public final int length() {
109         return myLength;
110     }
111 
112     /**
113      * Copy items from the given buffer to this buffer. The number of items
114      * copied is this buffer's length or <code>theSrc</code>'s length, whichever is
115      * smaller. If <code>theSrc</code> is this buffer, the <code>copy()</code> method
116      * does nothing.
117      *
118      * @param theSrc Source of items to copy into this buffer.
119      * @exception ClassCastException (unchecked exception) Thrown if
120      * <code>theSrc</code>'s item data type is not the same as this buffer's item
121      * data type.
122      */
123     public abstract void copy(Buf theSrc);
124 
125     /**
126      * Fill this buffer with the given item. The <code>item</code> is assigned to
127      * each element in this buffer.
128      * <P>
129      * If this buffer's item data type is a primitive type, the <code>item</code>
130      * must be an instance of the corresponding primitive wrapper class -- class
131      * Integer for type <code>int</code>, class Double for type <code>double</code>, and
132      * so on. If the <code>item</code> is null, the item data type's default initial
133      * value is assigned to each element in this buffer.
134      * <P>
135      * If this buffer's item data type is a nonprimitive type, the <code>item</code>
136      * must be an instance of the item class or a subclass thereof. The
137      * <code>item</code> may be null. Note that since <code>item</code> is
138      * <I>assigned</I> to every buffer element, every buffer element ends up
139      * referring to the same <code>item</code>.
140      *
141      * @param item Item.
142      * @exception ClassCastException (unchecked exception) Thrown if the
143      * <code>item</code>'s data type is not the same as this buffer's item data
144      * type.
145      */
146     public abstract void fill(Object item);
147 
148     /**
149      * Create a buffer for performing parallel reduction using the given binary
150      * operation. The results of the reduction are placed into this buffer.
151      * <P>
152      * Operations performed on the returned reduction buffer have the same
153      * effect as operations performed on this buffer, except whenever a source
154      * item <I>S</I> is put into a destination item <I>D</I> in this buffer,
155      * <I>D</I> is set to <I>D op S</I>, that is, the reduction of <I>D</I> and
156      * <I>S</I> using the given binary operation (rather than just setting
157      * <I>D</I> to <I>S</I>).
158      *
159      * @param op Binary operation.
160      * @exception ClassCastException (unchecked exception) Thrown if this
161      * buffer's element data type and the given binary operation's argument data
162      * type are not the same.
163      * @return a {@link edu.rit.mp.Buf} object.
164      */
165     public abstract Buf getReductionBuf(Op op);
166 
167     /**
168      * Create a temporary buffer with the same type of items and the same length
169      * as this buffer. The new buffer items are stored in a newly created array,
170      * separate from the storage for this buffer's items.
171      *
172      * @return a {@link edu.rit.mp.Buf} object.
173      */
174     public abstract Buf getTemporaryBuf();
175 
176 // Hidden operations.
177     /**
178      * Called by the I/O thread before sending message items using this buffer.
179      *
180      * @exception IOException Thrown if an I/O error occurred.
181      */
182     void preSend()
183             throws IOException {
184     }
185 
186     /**
187      * Send as many items as possible from this buffer to the given byte buffer.
188      * <P>
189      * The <code>sendItems()</code> method must not block the calling thread; if it
190      * does, all message I/O in MP will be blocked.
191      *
192      * @param i Index of first item to send, in the range 0 ..
193      * <code>length</code>-1.
194      * @param buffer Byte buffer.
195      * @return Number of items sent.
196      */
197     protected abstract int sendItems(int i,
198             ByteBuffer buffer);
199 
200     /**
201      * Called by the I/O thread after sending message items using this buffer.
202      *
203      * @exception IOException Thrown if an I/O error occurred.
204      */
205     void postSend()
206             throws IOException {
207     }
208 
209     /**
210      * Called by the I/O thread before receiving message items using this
211      * buffer.
212      *
213      * @param theReadLength Actual number of items in message.
214      *
215      * @exception IOException Thrown if an I/O error occurred.
216      */
217     void preReceive(int theReadLength)
218             throws IOException {
219     }
220 
221     /**
222      * Receive as many items as possible from the given byte buffer to this
223      * buffer.
224      * <P>
225      * The <code>receiveItems()</code> method must not block the calling thread; if
226      * it does, all message I/O in MP will be blocked.
227      *
228      * @param i Index of first item to receive, in the range 0 ..
229      * <code>length</code>-1.
230      * @param num Maximum number of items to receive.
231      * @param buffer Byte buffer.
232      * @return Number of items received.
233      */
234     protected abstract int receiveItems(int i,
235             int num,
236             ByteBuffer buffer);
237 
238     /**
239      * Skip as many items as possible from the given byte buffer.
240      *
241      * @param num Number of items to skip.
242      * @param buffer Buffer.
243      *
244      * @return Number of items actually skipped.
245      */
246     abstract int skipItems(int num,
247             ByteBuffer buffer);
248 
249     /**
250      * Called by the I/O thread after receiving message items using this buffer.
251      *
252      * @param theStatus Status object that will be returned for the message; its
253      * contents may be altered if necessary.
254      * @param theClassLoader Alternate class loader to be used when receiving
255      * objects, or null.
256      *
257      * @exception IOException Thrown if an I/O error occurred.
258      */
259     void postReceive(Status theStatus,
260             ClassLoader theClassLoader)
261             throws IOException {
262     }
263 
264 }