JDK-8248431 : (bf) Add absolute bulk put methods which accept a source Buffer
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.nio
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 16
  • Submitted: 2020-06-27
  • Updated: 2020-11-05
  • Resolved: 2020-11-05
Related Reports
CSR :  
Description
Summary
-------

Add a method to write a sequence of values to a buffer from another buffer starting at an absolute position in each buffer.

Problem
-------
The java.nio.$Type$Buffer classes, where $Type$ is in {Byte, Char, Double, Float, Int, Long, Short}, currently define a method to perform a relative bulk put into a buffer of a sequence of values from another buffer. This method operates with respect to the current positions of the buffers and the positions are updated accordingly before the method returns. There is however no method to write a sequence of values from one buffer into another starting at absolute offsets in the source and target buffers and without affecting the position of either buffer. This is asymmetric with the bulk methods which write into the buffer from a source array: there are methods in that case to perform the write either relative to the buffer's position (relative bulk put) or without affecting the position (absolute bulk put).

Solution
--------

Add to the $Type$Buffer classes an absolute bulk put method which accepts a $Type$Buffer as its data source.

Specification
-------------
The normative version of the proposed change is in the attached specdiff and webrev archives. The following is an example for ByteBuffer:

```
public ByteBuffer put���(int index, ByteBuffer src, int offset, int length)

Absolute bulk put method  (optional operation).

This method transfers length bytes into this buffer from the given source buffer, starting at the given offset in the source buffer and the given index in this buffer. The positions of both buffers are unchanged.

In other words, an invocation of this method of the form dst.put(index, src, offset, length) has exactly the same effect as the loop


 for (int i = offset, j = index; i < offset + length; i++, j++)
     dst.put(j, src.get(i));
 

except that it first checks the consistency of the supplied parameters and it is potentially much more efficient. If this buffer and the source buffer share the same backing array or memory, then the result will be as if the source elements were first copied to an intermediate location before being written into this buffer.

Parameters:
    index - The index in this buffer at which the first byte will be written; must be non-negative and less than limit()
    src - The buffer from which bytes are to be read
    offset - The index within the source buffer of the first byte to be read; must be non-negative and less than src.limit()
    length - The number of bytes to be read from the given buffer; must be non-negative and no larger than the smaller of limit() - index and src.limit() - offset
Returns:
    This buffer
Throws:
    IndexOutOfBoundsException - If the preconditions on the index, offset, and length parameters do not hold
    ReadOnlyBufferException - If this buffer is read-only
Since:
    16 
```


Comments
Thanks for the additional information; moving to Approved.
05-11-2020

I understand the comment now and concur that it is relevant but not applicable to the current circumstance. For context, I should note that the relative-position counterpart of this absolute-position bulk put buffer method used to devolve to just such a loop for the unoptimized case. This was however problematic leading to issue JDK-8245121 which was since fixed.
04-11-2020

Right; to clarify my comment: In a difference circumstance (adding a method to an existing interface that could be implemented by users), the solution I'd recommend is to have add a default method with a possibly slow but correct implementation that could be overridden in implementing classes. Some details differ here (abstract class, controlled subclassing), but I though the question was worth raising before approving the request.
04-11-2020

By "loop in question" do you mean that included in the specification? If so, no.
04-11-2020

Moving to Provisional, not Approved. Should the new method have a default method which uses a variant of the loop in question? Since the FooBuffer classes are not generally subclassable, I suppose we don't have the full set of compatibility concerns as we would for adding a method to an existing interface.
04-11-2020

Some verbiage could be added to the class level specification, and possibly to the specifications of the pertinent methods, but if so I think it should be the subject of a separate issue.
04-11-2020

The method looks okay although we should really encourage the people looking for this in the context of off-heap memory to look at the MemorySegment API.
04-11-2020