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