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