1 //******************************************************************************
2 //
3 // File: FloatBuf.java
4 // Package: edu.rit.mp
5 // Unit: Class edu.rit.mp.FloatBuf
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.EmptyFloatBuf;
45 import edu.rit.mp.buf.FloatArrayBuf;
46 import edu.rit.mp.buf.FloatArrayBuf_1;
47 import edu.rit.mp.buf.FloatItemBuf;
48 import edu.rit.mp.buf.FloatMatrixBuf;
49 import edu.rit.mp.buf.FloatMatrixBuf_1;
50 import edu.rit.mp.buf.SharedFloatArrayBuf;
51 import edu.rit.mp.buf.SharedFloatArrayBuf_1;
52 import edu.rit.mp.buf.SharedFloatBuf;
53 import edu.rit.pj.reduction.SharedFloat;
54 import edu.rit.pj.reduction.SharedFloatArray;
55 import edu.rit.util.Arrays;
56 import edu.rit.util.Range;
57
58 /**
59 * Class FloatBuf is the abstract base class for a buffer of float items sent or
60 * received using the Message Protocol (MP). In a message, a float item is
61 * represented as four bytes, most significant byte first.
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 FloatBuf, call one of the following static factory methods:
80 * <UL>
81 * <LI><code>emptyBuffer()</code>
82 * <LI><code>buffer()</code>
83 * <LI><code>buffer (float)</code>
84 * <LI><code>buffer (float[])</code>
85 * <LI><code>sliceBuffer (float[], Range)</code>
86 * <LI><code>sliceBuffers (float[], Range[])</code>
87 * <LI><code>buffer (float[][])</code>
88 * <LI><code>rowSliceBuffer (float[][], Range)</code>
89 * <LI><code>rowSliceBuffers (float[][], Range[])</code>
90 * <LI><code>colSliceBuffer (float[][], Range)</code>
91 * <LI><code>colSliceBuffers (float[][], Range[])</code>
92 * <LI><code>patchBuffer (float[][], Range, Range)</code>
93 * <LI><code>patchBuffers (float[][], Range[], Range[])</code>
94 * <LI><code>buffer (SharedFloat)</code>
95 * <LI><code>buffer (SharedFloatArray)</code>
96 * <LI><code>sliceBuffer (SharedFloatArray, Range)</code>
97 * <LI><code>sliceBuffers (SharedFloatArray, Range[])</code>
98 * </UL>
99 *
100 * @author Alan Kaminsky
101 * @version 03-May-2008
102 */
103 public abstract class FloatBuf
104 extends Buf {
105
106 // Hidden constructors.
107 /**
108 * Construct a new float buffer.
109 *
110 * @param theLength Number of items.
111 * @exception IllegalArgumentException (unchecked exception) Thrown if
112 * <code>theLength</code> < 0.
113 */
114 protected FloatBuf(int theLength) {
115 super(Constants.TYPE_FLOAT, 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 float.
122 *
123 * @return Empty buffer.
124 */
125 public static FloatBuf emptyBuffer() {
126 return new EmptyFloatBuf();
127 }
128
129 /**
130 * Create a buffer for a float item. The item is stored in the
131 * <code>item</code> field of the buffer.
132 *
133 * @return Buffer.
134 */
135 public static FloatItemBuf buffer() {
136 return new FloatItemBuf();
137 }
138
139 /**
140 * Create a buffer for a float 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 FloatItemBuf buffer(float item) {
147 return new FloatItemBuf(item);
148 }
149
150 /**
151 * Create a buffer for the entire given float 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 FloatBuf buffer(float[] theArray) {
160 if (theArray == null) {
161 throw new NullPointerException("FloatBuf.buffer(): theArray is null");
162 }
163 int nr = Arrays.length(theArray);
164 return new FloatArrayBuf_1(theArray, new Range(0, nr - 1));
165 }
166
167 /**
168 * Create a buffer for one slice of the given float 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 FloatBuf sliceBuffer(float[] theArray,
182 Range theRange) {
183 if (theArray == null) {
184 throw new NullPointerException("FloatBuf.sliceBuffer(): theArray is null");
185 }
186 int nr = Arrays.length(theArray);
187 if (0 > theRange.lb() || theRange.ub() >= nr) {
188 throw new IndexOutOfBoundsException("FloatBuf.sliceBuffer(): theArray index range = 0.."
189 + (nr - 1) + ", theRange = " + theRange);
190 }
191 if (theRange.stride() == 1) {
192 return new FloatArrayBuf_1(theArray, theRange);
193 } else {
194 return new FloatArrayBuf(theArray, theRange);
195 }
196 }
197
198 /**
199 * Create an array of buffers for multiple slices of the given float array.
200 * 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 FloatBuf[] sliceBuffers(float[] theArray,
216 Range[] theRanges) {
217 int n = theRanges.length;
218 FloatBuf[] result = new FloatBuf[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 float matrix. The returned buffer
227 * encompasses all the rows and all the columns in
228 * <code>theMatrix</code>.
229 *
230 * @param theMatrix Matrix.
231 * @return Buffer.
232 * @exception NullPointerException (unchecked exception) Thrown if
233 * <code>theMatrix</code> is null.
234 */
235 public static FloatBuf buffer(float[][] theMatrix) {
236 if (theMatrix == null) {
237 throw new NullPointerException("FloatBuf.buffer(): theMatrix is null");
238 }
239 int nr = Arrays.rowLength(theMatrix);
240 int nc = Arrays.colLength(theMatrix, 0);
241 return new FloatMatrixBuf_1(theMatrix, new Range(0, nr - 1), new Range(0, nc - 1));
242 }
243
244 /**
245 * Create a buffer for one row slice of the given float matrix. The returned
246 * buffer encompasses <code>theRowRange</code> of rows, and all the columns, in
247 * <code>theMatrix</code>. The range's stride may be 1 or greater 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 FloatBuf rowSliceBuffer(float[][] theMatrix,
259 Range theRowRange) {
260 if (theMatrix == null) {
261 throw new NullPointerException("FloatBuf.rowSliceBuffer(): theMatrix is null");
262 }
263 int nr = Arrays.rowLength(theMatrix);
264 if (0 > theRowRange.lb() || theRowRange.ub() >= nr) {
265 throw new IndexOutOfBoundsException("FloatBuf.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 FloatMatrixBuf_1(theMatrix, theRowRange, new Range(0, nc - 1));
271 } else {
272 return new FloatMatrixBuf(theMatrix, theRowRange, new Range(0, nc - 1));
273 }
274 }
275
276 /**
277 * Create an array of buffers for multiple row slices of the given float
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 FloatBuf[] rowSliceBuffers(float[][] theMatrix,
295 Range[] theRowRanges) {
296 int n = theRowRanges.length;
297 FloatBuf[] result = new FloatBuf[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 float 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 FloatBuf colSliceBuffer(float[][] theMatrix,
320 Range theColRange) {
321 if (theMatrix == null) {
322 throw new NullPointerException("FloatBuf.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("FloatBuf.colSliceBuffer(): theMatrix column index range = 0.."
328 + (nc - 1) + ", theColRange = " + theColRange);
329 }
330 if (theColRange.stride() == 1) {
331 return new FloatMatrixBuf_1(theMatrix, new Range(0, nr - 1), theColRange);
332 } else {
333 return new FloatMatrixBuf(theMatrix, new Range(0, nr - 1), theColRange);
334 }
335 }
336
337 /**
338 * Create an array of buffers for multiple column slices of the given float
339 * 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.
344 *
345 * @param theMatrix Matrix.
346 * @param theColRanges Array of ranges of columns to include.
347 * @return Array of buffers.
348 * @exception NullPointerException (unchecked exception) Thrown if
349 * <code>theMatrix</code> is null or
350 * <code>theColRanges</code> or any element thereof is null.
351 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
352 * <code>theMatrix</code>'s allocation does not include any element of
353 * <code>theColRanges</code>.
354 */
355 public static FloatBuf[] colSliceBuffers(float[][] theMatrix,
356 Range[] theColRanges) {
357 int n = theColRanges.length;
358 FloatBuf[] result = new FloatBuf[n];
359 for (int i = 0; i < n; ++i) {
360 result[i] = colSliceBuffer(theMatrix, theColRanges[i]);
361 }
362 return result;
363 }
364
365 /**
366 * Create a buffer for one patch of the given float matrix. The returned
367 * buffer encompasses <code>theRowRange</code> of rows, and <code>theColRange</code>
368 * of columns, in <code>theMatrix</code>. Each range's stride may be 1 or
369 * greater than 1.
370 *
371 * @param theMatrix Matrix.
372 * @param theRowRange Range of rows to include.
373 * @param theColRange Range of columns to include.
374 * @return Buffer.
375 * @exception NullPointerException (unchecked exception) Thrown if
376 * <code>theMatrix</code> is null,
377 * <code>theRowRange</code> is null, or <code>theColRange</code> is null.
378 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
379 * <code>theMatrix</code>'s allocation does not include <code>theRowRange</code> and
380 * <code>theColRange</code>.
381 */
382 public static FloatBuf patchBuffer(float[][] theMatrix,
383 Range theRowRange,
384 Range theColRange) {
385 if (theMatrix == null) {
386 throw new NullPointerException("FloatBuf.patchBuffer(): theMatrix is null");
387 }
388 int nr = Arrays.rowLength(theMatrix);
389 if (0 > theRowRange.lb() || theRowRange.ub() >= nr) {
390 throw new IndexOutOfBoundsException("FloatBuf.patchBuffer(): theMatrix row index range = 0.."
391 + (nr - 1) + ", theRowRange = " + theRowRange);
392 }
393 int nc = Arrays.colLength(theMatrix, theRowRange.lb());
394 if (0 > theColRange.lb() || theColRange.ub() >= nc) {
395 throw new IndexOutOfBoundsException("FloatBuf.patchBuffer(): theMatrix column index range = 0.."
396 + (nc - 1) + ", theColRange = " + theColRange);
397 }
398 if (theRowRange.stride() == 1 && theColRange.stride() == 1) {
399 return new FloatMatrixBuf_1(theMatrix, theRowRange, theColRange);
400 } else {
401 return new FloatMatrixBuf(theMatrix, theRowRange, theColRange);
402 }
403 }
404
405 /**
406 * Create an array of buffers for multiple patches of the given float
407 * matrix. The length of the returned buffer array is equal to the length of
408 * <code>theRowRanges</code> times the length of <code>theColRanges</code>. Each
409 * element of the returned buffer array encompasses the rows given in one
410 * element of <code>theRowRanges</code> array, and the columns given in one
411 * element of <code>theColRanges</code> array, in all possible combinations, of
412 * <code>theMatrix</code>. Each range's stride may be 1 or greater than 1.
413 *
414 * @param theMatrix Matrix.
415 * @param theRowRanges Array of ranges of rows to include.
416 * @param theColRanges Array of ranges of columns to include.
417 * @return Array of buffers.
418 * @exception NullPointerException (unchecked exception) Thrown if
419 * <code>theMatrix</code> is null,
420 * <code>theRowRanges</code> or any element thereof is null, or
421 * <code>theColRanges</code> or any element thereof is null.
422 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
423 * <code>theMatrix</code>'s allocation does not include any element of
424 * <code>theRowRanges</code> or
425 * <code>theColRanges</code>.
426 */
427 public static FloatBuf[] patchBuffers(float[][] theMatrix,
428 Range[] theRowRanges,
429 Range[] theColRanges) {
430 int m = theRowRanges.length;
431 int n = theColRanges.length;
432 FloatBuf[] result = new FloatBuf[m * n];
433 int k = 0;
434 for (int i = 0; i < m; ++i) {
435 Range rowrange = theRowRanges[i];
436 for (int j = 0; j < n; ++j) {
437 result[k++]
438 = patchBuffer(theMatrix, rowrange, theColRanges[j]);
439 }
440 }
441 return result;
442 }
443
444 /**
445 * Create a buffer for a shared float item. The item is wrapped in an
446 * instance of class {@linkplain edu.rit.pj.reduction.SharedFloat
447 * SharedFloat}. Use the methods of the SharedFloat object to access the
448 * actual item.
449 *
450 * @param item SharedFloat object that wraps the item.
451 * @exception NullPointerException (unchecked exception) Thrown if
452 * <code>item</code> is null.
453 * @return a {@link edu.rit.mp.FloatBuf} object.
454 */
455 public static FloatBuf buffer(SharedFloat item) {
456 if (item == null) {
457 throw new NullPointerException("FloatBuf.buffer(): item is null");
458 }
459 return new SharedFloatBuf(item);
460 }
461
462 /**
463 * Create a buffer for the entire given shared float array. The returned
464 * buffer encompasses all the elements in <code>theArray</code>.
465 *
466 * @param theArray Array.
467 * @return Buffer.
468 * @exception NullPointerException (unchecked exception) Thrown if
469 * <code>theArray</code> is null.
470 */
471 public static FloatBuf buffer(SharedFloatArray theArray) {
472 if (theArray == null) {
473 throw new NullPointerException("FloatBuf.buffer(): theArray is null");
474 }
475 int nr = theArray.length();
476 return new SharedFloatArrayBuf_1(theArray, new Range(0, nr - 1));
477 }
478
479 /**
480 * Create a buffer for one slice of the given shared float array. The
481 * returned buffer encompasses <code>theRange</code> of elements in
482 * <code>theArray</code>. The range's stride may be 1 or greater than 1.
483 *
484 * @param theArray Array.
485 * @param theRange Range of elements to include.
486 * @return Buffer.
487 * @exception NullPointerException (unchecked exception) Thrown if
488 * <code>theArray</code> is null or
489 * <code>theRange</code> is null.
490 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
491 * <code>theArray</code> does not include all the indexes in <code>theRange</code>.
492 */
493 public static FloatBuf sliceBuffer(SharedFloatArray theArray,
494 Range theRange) {
495 if (theArray == null) {
496 throw new NullPointerException("FloatBuf.sliceBuffer(): theArray is null");
497 }
498 int nr = theArray.length();
499 if (0 > theRange.lb() || theRange.ub() >= nr) {
500 throw new IndexOutOfBoundsException("FloatBuf.sliceBuffer(): theArray index range = 0.."
501 + (nr - 1) + ", theRange = " + theRange);
502 }
503 if (theRange.stride() == 1) {
504 return new SharedFloatArrayBuf_1(theArray, theRange);
505 } else {
506 return new SharedFloatArrayBuf(theArray, theRange);
507 }
508 }
509
510 /**
511 * Create an array of buffers for multiple slices of the given shared float
512 * array. The returned buffer array has the same length as
513 * <code>theRanges</code>. Each element [<I>i</I>] of the returned buffer array
514 * encompasses the elements of <code>theArray</code> specified by
515 * <code>theRanges[i]</code>. Each range's stride may be 1 or greater than 1.
516 *
517 * @param theArray Array.
518 * @param theRanges Array of ranges of elements to include.
519 * @return Array of buffers.
520 * @exception NullPointerException (unchecked exception) Thrown if
521 * <code>theArray</code> is null or
522 * <code>theRanges</code> or any element thereof is null.
523 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
524 * <code>theArray</code>'s allocation does not include any element of
525 * <code>theRanges</code>.
526 */
527 public static FloatBuf[] sliceBuffers(SharedFloatArray theArray,
528 Range[] theRanges) {
529 int n = theRanges.length;
530 FloatBuf[] result = new FloatBuf[n];
531 for (int i = 0; i < n; ++i) {
532 result[i] = sliceBuffer(theArray, theRanges[i]);
533 }
534 return result;
535 }
536
537 /**
538 * Obtain the given item from this buffer.
539 * <P>
540 * The <code>get()</code> method must not block the calling thread; if it does,
541 * all message I/O in MP will be blocked.
542 *
543 * @param i Item index in the range 0 .. <code>length()</code>-1.
544 * @return Item at index <code>i</code>.
545 */
546 public abstract float get(int i);
547
548 /**
549 * Store the given item in this buffer.
550 * <P>
551 * The <code>put()</code> method must not block the calling thread; if it does,
552 * all message I/O in MP will be blocked.
553 *
554 * @param i Item index in the range 0 .. <code>length()</code>-1.
555 * @param item Item to be stored at index <code>i</code>.
556 */
557 public abstract void put(int i,
558 float item);
559
560 /**
561 * {@inheritDoc}
562 *
563 * Copy items from the given buffer to this buffer. The number of items
564 * copied is this buffer's length or <code>theSrc</code>'s length, whichever is
565 * smaller. If <code>theSrc</code> is this buffer, the <code>copy()</code> method
566 * does nothing.
567 * <P>
568 * The default implementation of the <code>copy()</code> method calls the
569 * <code>defaultCopy()</code> method. A subclass can override the
570 * <code>copy()</code> method to use a more efficient algorithm.
571 * @exception ClassCastException (unchecked exception) Thrown if
572 * <code>theSrc</code>'s item data type is not the same as this buffer's item
573 * data type.
574 */
575 public void copy(Buf theSrc) {
576 if (theSrc != this) {
577 defaultCopy((FloatBuf) theSrc, this);
578 }
579 }
580
581 /**
582 * {@inheritDoc}
583 *
584 * Fill this buffer with the given item. The <code>item</code> is assigned to
585 * each element in this buffer.
586 * <P>
587 * The <code>item</code> must be an instance of class Float. If the
588 * <code>item</code> is null, 0.0f is assigned to each element in this buffer.
589 * @exception ClassCastException (unchecked exception) Thrown if the
590 * <code>item</code>'s data type is not the same as this buffer's item data
591 * type.
592 */
593 public void fill(Object item) {
594 float value = item == null ? 0.0f : ((Float) item).floatValue();
595 for (int i = 0; i < myLength; ++i) {
596 put(i, value);
597 }
598 }
599
600 /**
601 * Create a temporary buffer with the same type of items and the same length
602 * as this buffer. The new buffer items are stored in a newly created array,
603 * separate from the storage for this buffer's items.
604 *
605 * @return a {@link edu.rit.mp.Buf} object.
606 */
607 public Buf getTemporaryBuf() {
608 return buffer(new float[myLength]);
609 }
610
611 // Hidden operations.
612 /**
613 * Skip as many items as possible from the given byte buffer.
614 *
615 * @param num Number of items to skip.
616 * @param buffer Buffer.
617 *
618 * @return Number of items actually skipped.
619 */
620 int skipItems(int num,
621 ByteBuffer buffer) {
622 int n = Math.min(num, buffer.remaining() / 4);
623 buffer.position(buffer.position() + 4 * n);
624 return n;
625 }
626
627 /**
628 * Copy items from the given source buffer to the given destination buffer.
629 * The number of items copied is <code>theSrc</code>'s length or
630 * <code>theDst</code>'s length, whichever is smaller. Each item is copied
631 * individually using the <code>get()</code> and <code>put()</code> methods. It is
632 * assumed that <code>theSrc</code> is not the same as <code>theDst</code>.
633 *
634 * @param theSrc Source of items to copy.
635 * @param theDst Destination of items to copy.
636 */
637 protected static void defaultCopy(FloatBuf theSrc,
638 FloatBuf theDst) {
639 int n = Math.min(theSrc.myLength, theDst.myLength);
640 for (int i = 0; i < n; ++i) {
641 theDst.put(i, theSrc.get(i));
642 }
643 }
644
645 }