JDK-8212619 : (bf) Add absolute bulk put and get methods
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.nio
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 13
  • Submitted: 2018-10-17
  • Updated: 2019-02-16
  • Resolved: 2019-02-16
Related Reports
CSR :  
Description
Summary
-------

Add methods to read a sequence of values from or write a sequence of values to a buffer starting at an absolute position in the buffer.

Problem
-------

The java.nio.$Type$Buffer classes, where $Type$ is in {Byte, Char, Double, Float, Int, Long, Short}, currently define methods to read or write a sequence of values of the corresponding type. They are referred to as "bulk" methods, specifically "bulk get" and "bulk put" methods. These methods operate relative to the current position of the buffer at the time of the get or put and hence are further termed "relative bulk" get and put.

The buffer classes also define "absolute" get and put methods but only ones which can read or write a single value. There is thus a lack of symmetry in the absolute versus the relative get and put methods. The absence of absolute bulk get and put methods makes it more difficult and expensive for the buffer classes to be used for example in a multi-threaded scenario. In such a scenario using the relative get and put methods is problematic due to the fact that these operations mutate the state of the buffer.

Solution
--------

Add absolute bulk get and put methods to the $Type$Buffer classes. The methods should be analogous in signature to the extant relative bulk get and put methods.

Specification
-------------
In the following $Type$ should be replaced with one of {Byte, Char, Double, Float, Int, Long, Short}, and $type$ with the corresponding primitive type {byte, char, double, float, int, long, short}.

```
    /**
     * Absolute bulk <i>get</i> method.
     *
     * <p> This method transfers {@code length} $type$s from this
     * buffer into the given array, starting at the given index in this
     * buffer and at the given offset in the array.  The position of this
     * buffer is unchanged.
     *
     * <p> An invocation of this method of the form
     * <code>src.get(index,&nbsp;dst,&nbsp;offset,&nbsp;length)</code>
     * has exactly the same effect as the following loop except that it first
     * checks the consistency of the supplied parameters and it is potentially
     * much more efficient:
     *
     * <pre>{@code
     *     for (int i = offset, j = index; i < offset + length; i++, j++)
     *         dst[i] = src.get(j);
     * }</pre>
     *
     * @param  index
     *         The index in this buffer from which the first $type$ will be
     *         read; must be non-negative and less than {@code limit()}
     *
     * @param  dst
     *         The destination array
     *
     * @param  offset
     *         The offset within the array of the first $type$ to be
     *         written; must be non-negative and less than
     *         {@code dst.length}
     *
     * @param  length
     *         The number of $type$s to be written to the given array;
     *         must be non-negative and no larger than the smaller of
     *         {@code limit() - index} and {@code dst.length - offset}
     *
     * @return  This buffer
     *
     * @throws  IndexOutOfBoundsException
     *          If the preconditions on the {@code index}, {@code offset}, and
     *          {@code length} parameters do not hold
     *
     * @since 13
     */
    public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {}

    /**
     * Absolute bulk <i>get</i> method.
     *
     * <p> This method transfers $type$s from this buffer into the given
     * destination array.  The position of this buffer is unchanged.  An
     * invocation of this method of the form
     * <code>src.get(index,&nbsp;dst)</code> behaves in exactly the same
     * way as the invocation:
     *
     * <pre>
     *     src.get(index, dst, 0, dst.length) </pre>
     *
     * @param  index
     *         The index in this buffer from which the first $type$ will be
     *         read; must be non-negative and less than {@code limit()}
     *
     * @param  dst
     *         The destination array
     *
     * @return  This buffer
     *
     * @throws  IndexOutOfBoundsException
     *          If {@code index} is negative, not smaller than {@code limit()},
     *          or {@code limit() - index < dst.length}
     *
     * @since 13
     */
    public $Type$Buffer get(int index, $type$[] dst) {}

    /**
     * Absolute bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
     *
     * <p> This method transfers {@code length} $type$s from the given
     * array, starting at the given offset in the array and at the given index
     * in this buffer.  The position of this buffer is unchanged.
     *
     * <p> An invocation of this method of the form
     * <code>dst.put(index,&nbsp;src,&nbsp;offset,&nbsp;length)</code>
     * has exactly the same effect as the following loop except that it first
     * checks the consistency of the supplied parameters and it is potentially
     * much more efficient:
     *
     * <pre>{@code
     *     for (int i = offset, j = index; i < offset + length; i++, j++)
     *         dst.put(j, src[i]);
     * }</pre>
     *
     * @param  index
     *         The index in this buffer at which the first $type$ will be
     *         written; must be non-negative and less than {@code limit()}
     *
     * @param  src
     *         The array from which $type$s are to be read
     *
     * @param  offset
     *         The offset within the array of the first $type$ to be read;
     *         must be non-negative and less than {@code src.length}
     *
     * @param  length
     *         The number of $type$s to be read from the given array;
     *         must be non-negative and no larger than the smaller of
     *         {@code limit() - index} and {@code src.length - offset}
     *
     * @return  This buffer
     *
     * @throws  IndexOutOfBoundsException
     *          If the preconditions on the {@code index}, {@code offset}, and
     *          {@code length} parameters do not hold
     *
     * @throws  ReadOnlyBufferException
     *          If this buffer is read-only
     *
     * @since 13
     */
    public $Type$Buffer put(int index, $type$[] src, int offset, int length) {}

    /**
     * Absolute bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
     *
     * <p> This method copies $type$s into this buffer from the given source
     * array.  The position of this buffer is unchanged.  An invocation of this
     * method of the form <code>dst.put(index,&nbsp;src)</code>
     * behaves in exactly the same way as the invocation:
     *
     * <pre>
     *     dst.put(index, src, 0, src.length); </pre>
     *
     * @param  index
     *         The index in this buffer at which the first $type$ will be
     *         written; must be non-negative and less than {@code limit()}
     *
     * @param  src
     *         The array from which $type$s are to be read
     *
     * @return  This buffer
     *
     * @throws  IndexOutOfBoundsException
     *          If {@code index} is negative, not smaller than {@code limit()},
     *          or {@code limit() - index < src.length}
     *
     * @throws  ReadOnlyBufferException
     *          If this buffer is read-only
     *
     * @since 13
     */
    public $Type$Buffer put(int index, $type$[] src) {}
```

Comments
Read over the review thread on nio-dev; moving to Approved.
16-02-2019