View Javadoc
1   //******************************************************************************
2   //
3   // File:    Unsigned8BitIntegerBuf.java
4   // Package: edu.rit.mp
5   // Unit:    Class edu.rit.mp.Unsigned8BitIntegerBuf
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.nio.ByteBuffer;
43  
44  import edu.rit.mp.buf.EmptyUnsigned8BitIntegerBuf;
45  import edu.rit.mp.buf.SharedUnsigned8BitIntegerArrayBuf;
46  import edu.rit.mp.buf.SharedUnsigned8BitIntegerArrayBuf_1;
47  import edu.rit.mp.buf.SharedUnsigned8BitIntegerBuf;
48  import edu.rit.mp.buf.Unsigned8BitIntegerArrayBuf;
49  import edu.rit.mp.buf.Unsigned8BitIntegerArrayBuf_1;
50  import edu.rit.mp.buf.Unsigned8BitIntegerItemBuf;
51  import edu.rit.mp.buf.Unsigned8BitIntegerMatrixBuf;
52  import edu.rit.mp.buf.Unsigned8BitIntegerMatrixBuf_1;
53  import edu.rit.pj.reduction.SharedInteger;
54  import edu.rit.pj.reduction.SharedIntegerArray;
55  import edu.rit.util.Arrays;
56  import edu.rit.util.Range;
57  
58  /**
59   * Class Unsigned8BitIntegerBuf is the abstract base class for a buffer of
60   * unsigned 8-bit integer items sent or received using the Message Protocol
61   * (MP). In a message, an unsigned 8-bit integer item is represented as one
62   * byte. The range of values that can be represented is 0 .. 255.
63   * <P>
64   * A buffer may be used to send one or more messages at the same time in
65   * multiple threads. If a buffer is being used to send a message or messages,
66   * the buffer must not be used to receive a message at the same time.
67   * <P>
68   * A buffer may be used to receive one message at a time. If a buffer is being
69   * used to receive a message, the buffer must not be used to receive another
70   * message in a different thread, and the buffer must not be used to send a
71   * message or messages.
72   * <P>
73   * A buffer is a conduit for retrieving and storing data in some underlying data
74   * structure. If the underlying data structure is multiple thread safe, then one
75   * thread can be retrieving or storing data via the buffer at the same time as
76   * other threads are accessing the data structure. If the underlying data
77   * structure is not multiple thread safe, then other threads must not access the
78   * data structure while one thread is retrieving or storing data via the buffer.
79   * <P>
80   * To create an Unsigned8BitIntegerBuf, call one of the following static factory
81   * methods:
82   * <UL>
83   * <LI><code>emptyBuffer()</code>
84   * <LI><code>buffer()</code>
85   * <LI><code>buffer (int)</code>
86   * <LI><code>buffer (int[])</code>
87   * <LI><code>sliceBuffer (int[], Range)</code>
88   * <LI><code>sliceBuffers (int[], Range[])</code>
89   * <LI><code>buffer (int[][])</code>
90   * <LI><code>rowSliceBuffer (int[][], Range)</code>
91   * <LI><code>rowSliceBuffers (int[][], Range[])</code>
92   * <LI><code>colSliceBuffer (int[][], Range)</code>
93   * <LI><code>colSliceBuffers (int[][], Range[])</code>
94   * <LI><code>patchBuffer (int[][], Range, Range)</code>
95   * <LI><code>patchBuffers (int[][], Range[], Range[])</code>
96   * <LI><code>buffer (SharedInteger)</code>
97   * <LI><code>buffer (SharedIntegerArray)</code>
98   * <LI><code>sliceBuffer (SharedIntegerArray, Range)</code>
99   * <LI><code>sliceBuffers (SharedIntegerArray, Range[])</code>
100  * </UL>
101  *
102  * @author Alan Kaminsky
103  * @version 03-May-2008
104  */
105 public abstract class Unsigned8BitIntegerBuf
106         extends Buf {
107 
108 // Hidden constructors.
109     /**
110      * Construct a new signed 8-bit integer buffer.
111      *
112      * @param theLength Number of items.
113      * @exception IllegalArgumentException (unchecked exception) Thrown if
114      * <code>theLength</code> &lt; 0.
115      */
116     protected Unsigned8BitIntegerBuf(int theLength) {
117         super(Constants.TYPE_SIGNED_8_BIT_INTEGER, theLength);
118     }
119 
120 // Exported operations.
121     /**
122      * Create an empty buffer. The buffer's length is 0. The buffer's item type
123      * is unsigned 8-bit integer.
124      *
125      * @return Empty buffer.
126      */
127     public static Unsigned8BitIntegerBuf emptyBuffer() {
128         return new EmptyUnsigned8BitIntegerBuf();
129     }
130 
131     /**
132      * Create a buffer for an integer item. The item is stored in the
133      * <code>item</code> field of the buffer.
134      *
135      * @return Buffer.
136      */
137     public static Unsigned8BitIntegerItemBuf buffer() {
138         return new Unsigned8BitIntegerItemBuf();
139     }
140 
141     /**
142      * Create a buffer for an integer item with the given initial value. The
143      * item is stored in the <code>item</code> field of the buffer.
144      *
145      * @param item Initial value of the <code>item</code> field.
146      * @return Buffer.
147      */
148     public static Unsigned8BitIntegerItemBuf buffer(int item) {
149         return new Unsigned8BitIntegerItemBuf(item);
150     }
151 
152     /**
153      * Create a buffer for the entire given integer array. The returned buffer
154      * encompasses all the elements in <code>theArray</code>.
155      *
156      * @param theArray Array.
157      * @return Buffer.
158      * @exception NullPointerException (unchecked exception) Thrown if
159      * <code>theArray</code> is null.
160      */
161     public static Unsigned8BitIntegerBuf buffer(int[] theArray) {
162         if (theArray == null) {
163             throw new NullPointerException("Unsigned8BitIntegerBuf.buffer(): theArray is null");
164         }
165         int nr = Arrays.length(theArray);
166         return new Unsigned8BitIntegerArrayBuf_1(theArray, new Range(0, nr - 1));
167     }
168 
169     /**
170      * Create a buffer for one slice of the given integer array. The returned
171      * buffer encompasses <code>theRange</code> of elements in <code>theArray</code>.
172      * The range's stride may be 1 or greater than 1.
173      *
174      * @param theArray Array.
175      * @param theRange Range of elements to include.
176      * @return Buffer.
177      * @exception NullPointerException (unchecked exception) Thrown if
178      * <code>theArray</code> is null or
179      * <code>theRange</code> is null.
180      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
181      * <code>theArray</code> does not include all the indexes in <code>theRange</code>.
182      */
183     public static Unsigned8BitIntegerBuf sliceBuffer(int[] theArray,
184             Range theRange) {
185         if (theArray == null) {
186             throw new NullPointerException("Unsigned8BitIntegerBuf.sliceBuffer(): theArray is null");
187         }
188         int nr = Arrays.length(theArray);
189         if (0 > theRange.lb() || theRange.ub() >= nr) {
190             throw new IndexOutOfBoundsException("Unsigned8BitIntegerBuf.sliceBuffer(): theArray index range = 0.."
191                     + (nr - 1) + ", theRange = " + theRange);
192         }
193         if (theRange.stride() == 1) {
194             return new Unsigned8BitIntegerArrayBuf_1(theArray, theRange);
195         } else {
196             return new Unsigned8BitIntegerArrayBuf(theArray, theRange);
197         }
198     }
199 
200     /**
201      * Create an array of buffers for multiple slices of the given integer
202      * array. The returned buffer array has the same length as
203      * <code>theRanges</code>. Each element [<I>i</I>] of the returned buffer array
204      * encompasses the elements of <code>theArray</code> specified by
205      * <code>theRanges[i]</code>. Each range's stride may be 1 or greater than 1.
206      *
207      * @param theArray Array.
208      * @param theRanges Array of ranges of elements to include.
209      * @return Array of buffers.
210      * @exception NullPointerException (unchecked exception) Thrown if
211      * <code>theArray</code> is null or
212      * <code>theRanges</code> or any element thereof is null.
213      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
214      * <code>theArray</code>'s allocation does not include any element of
215      * <code>theRanges</code>.
216      */
217     public static Unsigned8BitIntegerBuf[] sliceBuffers(int[] theArray,
218             Range[] theRanges) {
219         int n = theRanges.length;
220         Unsigned8BitIntegerBuf[] result = new Unsigned8BitIntegerBuf[n];
221         for (int i = 0; i < n; ++i) {
222             result[i] = sliceBuffer(theArray, theRanges[i]);
223         }
224         return result;
225     }
226 
227     /**
228      * Create a buffer for the entire given integer matrix. The returned buffer
229      * encompasses all the rows and all the columns in
230      * <code>theMatrix</code>.
231      *
232      * @param theMatrix Matrix.
233      * @return Buffer.
234      * @exception NullPointerException (unchecked exception) Thrown if
235      * <code>theMatrix</code> is null.
236      */
237     public static Unsigned8BitIntegerBuf buffer(int[][] theMatrix) {
238         if (theMatrix == null) {
239             throw new NullPointerException("Unsigned8BitIntegerBuf.buffer(): theMatrix is null");
240         }
241         int nr = Arrays.rowLength(theMatrix);
242         int nc = Arrays.colLength(theMatrix, 0);
243         return new Unsigned8BitIntegerMatrixBuf_1(theMatrix, new Range(0, nr - 1), new Range(0, nc - 1));
244     }
245 
246     /**
247      * Create a buffer for one row slice of the given integer matrix. The
248      * returned buffer encompasses <code>theRowRange</code> of rows, and all the
249      * columns, in <code>theMatrix</code>. The range's stride may be 1 or greater
250      * than 1.
251      *
252      * @param theMatrix Matrix.
253      * @param theRowRange Range of rows to include.
254      * @return Buffer.
255      * @exception NullPointerException (unchecked exception) Thrown if
256      * <code>theMatrix</code> is null or
257      * <code>theRowRange</code> is null.
258      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
259      * <code>theMatrix</code>'s allocation does not include <code>theRowRange</code>.
260      */
261     public static Unsigned8BitIntegerBuf rowSliceBuffer(int[][] theMatrix,
262             Range theRowRange) {
263         if (theMatrix == null) {
264             throw new NullPointerException("Unsigned8BitIntegerBuf.rowSliceBuffer(): theMatrix is null");
265         }
266         int nr = Arrays.rowLength(theMatrix);
267         if (0 > theRowRange.lb() || theRowRange.ub() >= nr) {
268             throw new IndexOutOfBoundsException("Unsigned8BitIntegerBuf.rowSliceBuffer(): theMatrix row index range = 0.."
269                     + (nr - 1) + ", theRowRange = " + theRowRange);
270         }
271         int nc = Arrays.colLength(theMatrix, theRowRange.lb());
272         if (theRowRange.stride() == 1) {
273             return new Unsigned8BitIntegerMatrixBuf_1(theMatrix, theRowRange, new Range(0, nc - 1));
274         } else {
275             return new Unsigned8BitIntegerMatrixBuf(theMatrix, theRowRange, new Range(0, nc - 1));
276         }
277     }
278 
279     /**
280      * Create an array of buffers for multiple row slices of the given integer
281      * matrix. The returned buffer array has the same length as
282      * <code>theRowRanges</code>. Each element [<I>i</I>] of the returned buffer
283      * array encompasses the rows of <code>theMatrix</code> specified by
284      * <code>theRowRanges[i]</code> and all the columns of <code>theMatrix</code>. Each
285      * range's stride may be 1 or greater than 1.
286      *
287      * @param theMatrix Matrix.
288      * @param theRowRanges Array of ranges of rows to include.
289      * @return Array of buffers.
290      * @exception NullPointerException (unchecked exception) Thrown if
291      * <code>theMatrix</code> is null or
292      * <code>theRowRanges</code> or any element thereof is null.
293      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
294      * <code>theMatrix</code>'s allocation does not include any element of
295      * <code>theRowRanges</code>.
296      */
297     public static Unsigned8BitIntegerBuf[] rowSliceBuffers(int[][] theMatrix,
298             Range[] theRowRanges) {
299         int n = theRowRanges.length;
300         Unsigned8BitIntegerBuf[] result = new Unsigned8BitIntegerBuf[n];
301         for (int i = 0; i < n; ++i) {
302             result[i] = rowSliceBuffer(theMatrix, theRowRanges[i]);
303         }
304         return result;
305     }
306 
307     /**
308      * Create a buffer for one column slice of the given integer matrix. The
309      * returned buffer encompasses all the rows, and <code>theColRange</code> of
310      * columns, in <code>theMatrix</code>. The range's stride may be 1 or greater
311      * than 1.
312      *
313      * @param theMatrix Matrix.
314      * @param theColRange Range of columns to include.
315      * @return Buffer.
316      * @exception NullPointerException (unchecked exception) Thrown if
317      * <code>theMatrix</code> is null or
318      * <code>theColRange</code> is null.
319      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
320      * <code>theMatrix</code>'s allocation does not include <code>theColRange</code>.
321      */
322     public static Unsigned8BitIntegerBuf colSliceBuffer(int[][] theMatrix,
323             Range theColRange) {
324         if (theMatrix == null) {
325             throw new NullPointerException("Unsigned8BitIntegerBuf.colSliceBuffer(): theMatrix is null");
326         }
327         int nr = Arrays.rowLength(theMatrix);
328         int nc = Arrays.colLength(theMatrix, 0);
329         if (0 > theColRange.lb() || theColRange.ub() >= nc) {
330             throw new IndexOutOfBoundsException("Unsigned8BitIntegerBuf.colSliceBuffer(): theMatrix column index range = 0.."
331                     + (nc - 1) + ", theColRange = " + theColRange);
332         }
333         if (theColRange.stride() == 1) {
334             return new Unsigned8BitIntegerMatrixBuf_1(theMatrix, new Range(0, nr - 1), theColRange);
335         } else {
336             return new Unsigned8BitIntegerMatrixBuf(theMatrix, new Range(0, nr - 1), theColRange);
337         }
338     }
339 
340     /**
341      * Create an array of buffers for multiple column slices of the given
342      * integer matrix. The returned buffer array has the same length as
343      * <code>theColRanges</code>. Each element [<I>i</I>] of the returned buffer
344      * array encompasses all the rows of <code>theMatrix</code> and the columns of
345      * <code>theMatrix</code> specified by <code>theColRanges[i]</code>. Each range's
346      * stride may be 1 or greater than 1.
347      *
348      * @param theMatrix Matrix.
349      * @param theColRanges Array of ranges of columns to include.
350      * @return Array of buffers.
351      * @exception NullPointerException (unchecked exception) Thrown if
352      * <code>theMatrix</code> is null or
353      * <code>theColRanges</code> or any element thereof is null.
354      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
355      * <code>theMatrix</code>'s allocation does not include any element of
356      * <code>theColRanges</code>.
357      */
358     public static Unsigned8BitIntegerBuf[] colSliceBuffers(int[][] theMatrix,
359             Range[] theColRanges) {
360         int n = theColRanges.length;
361         Unsigned8BitIntegerBuf[] result = new Unsigned8BitIntegerBuf[n];
362         for (int i = 0; i < n; ++i) {
363             result[i] = colSliceBuffer(theMatrix, theColRanges[i]);
364         }
365         return result;
366     }
367 
368     /**
369      * Create a buffer for one patch of the given integer matrix. The returned
370      * buffer encompasses <code>theRowRange</code> of rows, and <code>theColRange</code>
371      * of columns, in <code>theMatrix</code>. Each range's stride may be 1 or
372      * greater than 1.
373      *
374      * @param theMatrix Matrix.
375      * @param theRowRange Range of rows to include.
376      * @param theColRange Range of columns to include.
377      * @return Buffer.
378      * @exception NullPointerException (unchecked exception) Thrown if
379      * <code>theMatrix</code> is null,
380      * <code>theRowRange</code> is null, or <code>theColRange</code> is null.
381      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
382      * <code>theMatrix</code>'s allocation does not include <code>theRowRange</code> and
383      * <code>theColRange</code>.
384      */
385     public static Unsigned8BitIntegerBuf patchBuffer(int[][] theMatrix,
386             Range theRowRange,
387             Range theColRange) {
388         if (theMatrix == null) {
389             throw new NullPointerException("Unsigned8BitIntegerBuf.patchBuffer(): theMatrix is null");
390         }
391         int nr = Arrays.rowLength(theMatrix);
392         if (0 > theRowRange.lb() || theRowRange.ub() >= nr) {
393             throw new IndexOutOfBoundsException("Unsigned8BitIntegerBuf.patchBuffer(): theMatrix row index range = 0.."
394                     + (nr - 1) + ", theRowRange = " + theRowRange);
395         }
396         int nc = Arrays.colLength(theMatrix, theRowRange.lb());
397         if (0 > theColRange.lb() || theColRange.ub() >= nc) {
398             throw new IndexOutOfBoundsException("Unsigned8BitIntegerBuf.patchBuffer(): theMatrix column index range = 0.."
399                     + (nc - 1) + ", theColRange = " + theColRange);
400         }
401         if (theRowRange.stride() == 1 && theColRange.stride() == 1) {
402             return new Unsigned8BitIntegerMatrixBuf_1(theMatrix, theRowRange, theColRange);
403         } else {
404             return new Unsigned8BitIntegerMatrixBuf(theMatrix, theRowRange, theColRange);
405         }
406     }
407 
408     /**
409      * Create an array of buffers for multiple patches of the given integer
410      * matrix. The length of the returned buffer array is equal to the length of
411      * <code>theRowRanges</code> times the length of <code>theColRanges</code>. Each
412      * element of the returned buffer array encompasses the rows given in one
413      * element of <code>theRowRanges</code> array, and the columns given in one
414      * element of <code>theColRanges</code> array, in all possible combinations, of
415      * <code>theMatrix</code>. Each range's stride may be 1 or greater than 1.
416      *
417      * @param theMatrix Matrix.
418      * @param theRowRanges Array of ranges of rows to include.
419      * @param theColRanges Array of ranges of columns to include.
420      * @return Array of buffers.
421      * @exception NullPointerException (unchecked exception) Thrown if
422      * <code>theMatrix</code> is null,
423      * <code>theRowRanges</code> or any element thereof is null, or
424      * <code>theColRanges</code> or any element thereof is null.
425      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
426      * <code>theMatrix</code>'s allocation does not include any element of
427      * <code>theRowRanges</code> or
428      * <code>theColRanges</code>.
429      */
430     public static Unsigned8BitIntegerBuf[] patchBuffers(int[][] theMatrix,
431             Range[] theRowRanges,
432             Range[] theColRanges) {
433         int m = theRowRanges.length;
434         int n = theColRanges.length;
435         Unsigned8BitIntegerBuf[] result = new Unsigned8BitIntegerBuf[m * n];
436         int k = 0;
437         for (int i = 0; i < m; ++i) {
438             Range rowrange = theRowRanges[i];
439             for (int j = 0; j < n; ++j) {
440                 result[k++]
441                         = patchBuffer(theMatrix, rowrange, theColRanges[j]);
442             }
443         }
444         return result;
445     }
446 
447     /**
448      * Create a buffer for a shared integer item. The item is wrapped in an
449      * instance of class {@linkplain edu.rit.pj.reduction.SharedInteger
450      * SharedInteger}. Use the methods of the SharedInteger object to access the
451      * actual item.
452      *
453      * @param item SharedInteger object that wraps the item.
454      * @exception NullPointerException (unchecked exception) Thrown if
455      * <code>item</code> is null.
456      * @return a {@link edu.rit.mp.Unsigned8BitIntegerBuf} object.
457      */
458     public static Unsigned8BitIntegerBuf buffer(SharedInteger item) {
459         if (item == null) {
460             throw new NullPointerException("Unsigned8BitIntegerBuf.buffer(): item is null");
461         }
462         return new SharedUnsigned8BitIntegerBuf(item);
463     }
464 
465     /**
466      * Create a buffer for the entire given shared integer array. The returned
467      * buffer encompasses all the elements in <code>theArray</code>.
468      *
469      * @param theArray Array.
470      * @return Buffer.
471      * @exception NullPointerException (unchecked exception) Thrown if
472      * <code>theArray</code> is null.
473      */
474     public static Unsigned8BitIntegerBuf buffer(SharedIntegerArray theArray) {
475         if (theArray == null) {
476             throw new NullPointerException("Unsigned8BitIntegerBuf.buffer(): theArray is null");
477         }
478         int nr = theArray.length();
479         return new SharedUnsigned8BitIntegerArrayBuf_1(theArray, new Range(0, nr - 1));
480     }
481 
482     /**
483      * Create a buffer for one slice of the given shared integer array. The
484      * returned buffer encompasses <code>theRange</code> of elements in
485      * <code>theArray</code>. The range's stride may be 1 or greater than 1.
486      *
487      * @param theArray Array.
488      * @param theRange Range of elements to include.
489      * @return Buffer.
490      * @exception NullPointerException (unchecked exception) Thrown if
491      * <code>theArray</code> is null or
492      * <code>theRange</code> is null.
493      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
494      * <code>theArray</code> does not include all the indexes in <code>theRange</code>.
495      */
496     public static Unsigned8BitIntegerBuf sliceBuffer(SharedIntegerArray theArray,
497             Range theRange) {
498         if (theArray == null) {
499             throw new NullPointerException("Unsigned8BitIntegerBuf.sliceBuffer(): theArray is null");
500         }
501         int nr = theArray.length();
502         if (0 > theRange.lb() || theRange.ub() >= nr) {
503             throw new IndexOutOfBoundsException("Unsigned8BitIntegerBuf.sliceBuffer(): theArray index range = 0.."
504                     + (nr - 1) + ", theRange = " + theRange);
505         }
506         if (theRange.stride() == 1) {
507             return new SharedUnsigned8BitIntegerArrayBuf_1(theArray, theRange);
508         } else {
509             return new SharedUnsigned8BitIntegerArrayBuf(theArray, theRange);
510         }
511     }
512 
513     /**
514      * Create an array of buffers for multiple slices of the given shared
515      * integer array. The returned buffer array has the same length as
516      * <code>theRanges</code>. Each element [<I>i</I>] of the returned buffer array
517      * encompasses the elements of <code>theArray</code> specified by
518      * <code>theRanges[i]</code>. Each range's stride may be 1 or greater than 1.
519      *
520      * @param theArray Array.
521      * @param theRanges Array of ranges of elements to include.
522      * @return Array of buffers.
523      * @exception NullPointerException (unchecked exception) Thrown if
524      * <code>theArray</code> is null or
525      * <code>theRanges</code> or any element thereof is null.
526      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
527      * <code>theArray</code>'s allocation does not include any element of
528      * <code>theRanges</code>.
529      */
530     public static Unsigned8BitIntegerBuf[] sliceBuffers(SharedIntegerArray theArray,
531             Range[] theRanges) {
532         int n = theRanges.length;
533         Unsigned8BitIntegerBuf[] result = new Unsigned8BitIntegerBuf[n];
534         for (int i = 0; i < n; ++i) {
535             result[i] = sliceBuffer(theArray, theRanges[i]);
536         }
537         return result;
538     }
539 
540     /**
541      * Obtain the given item from this buffer.
542      * <P>
543      * The <code>get()</code> method must not block the calling thread; if it does,
544      * all message I/O in MP will be blocked.
545      *
546      * @param i Item index in the range 0 .. <code>length()</code>-1.
547      * @return Item at index <code>i</code>.
548      */
549     public abstract int get(int i);
550 
551     /**
552      * Store the given item in this buffer.
553      * <P>
554      * The <code>put()</code> method must not block the calling thread; if it does,
555      * all message I/O in MP will be blocked.
556      *
557      * @param i Item index in the range 0 .. <code>length()</code>-1.
558      * @param item Item to be stored at index <code>i</code>.
559      */
560     public abstract void put(int i,
561             int item);
562 
563     /**
564      * {@inheritDoc}
565      *
566      * Copy items from the given buffer to this buffer. The number of items
567      * copied is this buffer's length or <code>theSrc</code>'s length, whichever is
568      * smaller. If <code>theSrc</code> is this buffer, the <code>copy()</code> method
569      * does nothing.
570      * <P>
571      * The default implementation of the <code>copy()</code> method calls the
572      * <code>defaultCopy()</code> method. A subclass can override the
573      * <code>copy()</code> method to use a more efficient algorithm.
574      * @exception ClassCastException (unchecked exception) Thrown if
575      * <code>theSrc</code>'s item data type is not the same as this buffer's item
576      * data type.
577      */
578     public void copy(Buf theSrc) {
579         if (theSrc != this) {
580             defaultCopy((Unsigned8BitIntegerBuf) theSrc, this);
581         }
582     }
583 
584     /**
585      * {@inheritDoc}
586      *
587      * Fill this buffer with the given item. The <code>item</code> is assigned to
588      * each element in this buffer.
589      * <P>
590      * The <code>item</code> must be an instance of class Integer. If the
591      * <code>item</code> is null, 0 is assigned to each element in this buffer.
592      * @exception ClassCastException (unchecked exception) Thrown if the
593      * <code>item</code>'s data type is not the same as this buffer's item data
594      * type.
595      */
596     public void fill(Object item) {
597         int value = item == null ? 0 : ((Integer) item).intValue();
598         for (int i = 0; i < myLength; ++i) {
599             put(i, value);
600         }
601     }
602 
603     /**
604      * Create a temporary buffer with the same type of items and the same length
605      * as this buffer. The new buffer items are stored in a newly created array,
606      * separate from the storage for this buffer's items.
607      *
608      * @return a {@link edu.rit.mp.Buf} object.
609      */
610     public Buf getTemporaryBuf() {
611         return buffer(new int[myLength]);
612     }
613 
614 // Hidden operations.
615     /**
616      * Skip as many items as possible from the given byte buffer.
617      *
618      * @param num Number of items to skip.
619      * @param buffer Buffer.
620      *
621      * @return Number of items actually skipped.
622      */
623     int skipItems(int num,
624             ByteBuffer buffer) {
625         int n = Math.min(num, buffer.remaining());
626         buffer.position(buffer.position() + n);
627         return n;
628     }
629 
630     /**
631      * Copy items from the given source buffer to the given destination buffer.
632      * The number of items copied is <code>theSrc</code>'s length or
633      * <code>theDst</code>'s length, whichever is smaller. Each item is copied
634      * individually using the <code>get()</code> and <code>put()</code> methods. It is
635      * assumed that <code>theSrc</code> is not the same as <code>theDst</code>.
636      *
637      * @param theSrc Source of items to copy.
638      * @param theDst Destination of items to copy.
639      */
640     protected static void defaultCopy(Unsigned8BitIntegerBuf theSrc,
641             Unsigned8BitIntegerBuf theDst) {
642         int n = Math.min(theSrc.myLength, theDst.myLength);
643         for (int i = 0; i < n; ++i) {
644             theDst.put(i, theSrc.get(i));
645         }
646     }
647 
648 }