Strided1DNIOBuffer (Jython API documentation)
Date: 2020-03-21

org.python.core.buffer

## Class Strided1DNIOBuffer

- java.lang.Object
- - org.python.core.buffer.BaseBuffer
  - - org.python.core.buffer.Base1DBuffer
    - - org.python.core.buffer.BaseNIOBuffer
      - - org.python.core.buffer.Strided1DNIOBuffer

- All Implemented Interfaces:
    java.lang.AutoCloseable, BufferProtocol, PyBUF, PyBuffer

      public class Strided1DNIOBuffer
      extends BaseNIOBuffer

  Read-only buffer API over a one-dimensional `java.nio.ByteBuffer` of one-byte items, that are evenly-spaced in that store. The buffer has `storage`, `index0` and `length` properties in the usual way, designating a slice (or all) of a byte array, but also a `stride` property (equal to `getStrides()[0]`).

  Let the underlying buffer be the byte sequence u(i) for i=0..N-1, let x be the `Strided1DNIOBuffer`, and let the stride be p. The storage works as follows. Designate by x(j), for j=0..L-1, the byte at index j, that is, the byte retrieved by `x.byteAt(j)`. Thus, we store x(j) at u(a+pj), that is, x(0) = u(a). When we construct such a buffer, we have to supply a = `index0`, L = `count`, and p = `stride` as the constructor arguments. The last item in the slice x(L-1) is stored at u(a+p(L-1)). For the simple case of positive stride, constructor argument `index0` is the low index of the range occupied by the data. When the stride is negative, that is to say p<0, and L>1, this will be to the left of u(a), and the constructor argument `index0` is not then the low index of the range occupied by the data. Clearly both these indexes must be in the range 0 to N-1 inclusive, a rule enforced by the constructors (unless L=0, when it is assumed no array access will take place).

  The class may be used by exporters to create a strided slice (e.g. to export the diagonal of a matrix) and in particular by other buffers to create strided slices of themselves, such as to create the `memoryview` that is returned as an extended slice of a `memoryview`.

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from interface org.python.core.PyBuffer

      `PyBuffer.Pointer`

  - ### Field Summary

    - ### Fields inherited from interface org.python.core.PyBUF

      `ANY_CONTIGUOUS, AS_ARRAY, C_CONTIGUOUS, CONTIG, CONTIG_RO, CONTIGUITY, F_CONTIGUOUS, FORMAT, FULL, FULL_RO, INDIRECT, IS_C_CONTIGUOUS, IS_F_CONTIGUOUS, MAX_NDIM, NAVIGATION, ND, RECORDS, RECORDS_RO, SIMPLE, STRIDED, STRIDED_RO, STRIDES, WRITABLE`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `Strided1DNIOBuffer(int flags, BufferProtocol obj, java.nio.ByteBuffer storage, int index0, int count, int stride)` Provide an instance of `Strided1DNIOBuffer` on a particular `ByteBuffer` specifying a starting index, the number of items in the result, and a byte-indexing stride.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `int` | `byteIndex(int index)` Convert an item index (for a one-dimensional buffer) to an absolute byte index in the storage shared by the exporter.
    `PyBuffer` | `getBufferSlice(int flags, int start, int count, int stride)` Get a `PyBuffer` that represents a slice of the current one described in terms of a start index, number of items to include in the slice, and the stride in the current buffer.

    - ### Methods inherited from class org.python.core.buffer.BaseNIOBuffer

      `byteIndex, copyFrom, copyTo, copyTo, getBuf`

    - ### Methods inherited from class org.python.core.buffer.Base1DBuffer

      `getLen, isContiguous`

    - ### Methods inherited from class org.python.core.buffer.BaseBuffer

      `byteAt, byteAt, close, copyFrom, copyTo, getBuffer, getBufferAgain, getBufferSlice, getFormat, getItemsize, getNdim, getNIOByteBuffer, getObj, getPointer, getPointer, getShape, getStrides, getSuboffsets, hasArray, intAt, intAt, isReadonly, isReleased, release, storeAt, storeAt, toString`

    - ### Methods inherited from class java.lang.Object

      `equals, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Constructor Detail

    - #### Strided1DNIOBuffer

          public Strided1DNIOBuffer(int flags,
                                    BufferProtocol obj,
                                    java.nio.ByteBuffer storage,
                                    int index0,
                                    int count,
                                    int stride)
                             throws java.lang.ArrayIndexOutOfBoundsException,
                                    java.lang.NullPointerException,
                                    PyException

      Provide an instance of `Strided1DNIOBuffer` on a particular `ByteBuffer` specifying a starting index, the number of items in the result, and a byte-indexing stride. The result of `byteAt(i)` will be equal to `storage.get(index0+stride*i)` (whatever the sign of `stride`), valid for `0<=i<count`. The constructor checks that all these indices lie within the `storage` (unless `count=0`). No reference will be kept to the `ByteBuffer` passed in. (It is duplicated.)

      The constructed `PyBuffer` meets the consumer's expectations as expressed in the `flags` argument, or an exception will be thrown if these are incompatible with the type (e.g. the consumer does not specify that it understands the strides array). Note that the actual range in the `storage` array, the lowest and highest index, is not explicitly passed, but is implicit in `index0`, `count` and `stride`. The constructor checks that these indices lie within the `storage` array (unless `count=0`).

      Parameters:
        `flags` - consumer requirements
        `obj` - exporting object (or `null`)
        `storage` - `ByteBuffer` wrapping exported data
        `index0` - index into storage of item[0]
        `count` - number of items in the slice
        `stride` - in between successive elements of the new PyBuffer
      Throws:
        `java.lang.NullPointerException` - if `storage` is null
        `java.lang.ArrayIndexOutOfBoundsException` - if `index0`, `count` and `stride` are inconsistent with `storage.length`
        `PyException` - `BufferError` when expectations do not correspond with the type

  - ### Method Detail

    - #### byteIndex

          public final int byteIndex(int index)
                              throws java.lang.IndexOutOfBoundsException

      Description copied from interface: `PyBuffer`
      Convert an item index (for a one-dimensional buffer) to an absolute byte index in the storage shared by the exporter. The storage exported as a `PyBuffer` is a linearly-indexed sequence of bytes, although it may not actually be a heap-allocated Java `byte[]` object. The purpose of this method is to allow the exporter to define the relationship between the item index (as used in `PyBuffer.byteAt(int)`) and the byte-index (as used with the `ByteBuffer` returned by `PyBuffer.getNIOByteBuffer()`). See `PyBuffer.byteIndex(int[])` for discussion of the multi-dimensional case.
      Specified by:
        `byteIndex` in interface `PyBuffer`
      Overrides:
        `byteIndex` in class `BaseBuffer`
      Parameters:
        `index` - item-index from consumer
      Returns:
        corresponding byte-index in actual storage
      Throws:
        `java.lang.IndexOutOfBoundsException`

    - #### getBufferSlice

          public PyBuffer getBufferSlice(int flags,
                                         int start,
                                         int count,
                                         int stride)

      Get a `PyBuffer` that represents a slice of the current one described in terms of a start index, number of items to include in the slice, and the stride in the current buffer. A consumer that obtains a `PyBuffer` with `getBufferSlice` must release it with `PyBuffer.release()` just as if it had been obtained with `PyBuffer.getBuffer(int)`

      Suppose that x(i) denotes the ith element of the current buffer, that is, the byte retrieved by `this.byteAt(i)` or the unit indicated by `this.getPointer(i)`. A request for a slice where `start` = s, `count` = N and `stride` = m, results in a buffer y such that y(k) = x(s+km) where k=0..(N-1). In Python terms, this is the slice x[s : s+(N-1)m+1 : m] (if m>0) or the slice x[s : s+(N-1)m-1 : m] (if m<0). Implementations should check that this range is entirely within the current buffer.

      In a simple buffer backed by a contiguous byte array, the result is a strided PyBuffer on the same storage but where the offset is adjusted by s and the stride is as supplied. If the current buffer is already strided and/or has an item size larger than single bytes, the new `start` index, `count` and `stride` will be translated from the arguments given, through this buffer's stride and item size. The caller always expresses `start` and `strides` in terms of the abstract view of this buffer.

      `Strided1DNIOBuffer` provides an implementation for slicing already-strided bytes in one dimension. In that case, x(i) = u(r+ip) for i = 0..L-1 where u is the underlying buffer, and r, p and L are the start, stride and count with which x was created from u. Thus y(k) = u(r+sp+kmp), that is, the composite `index0` is r+sp and the composite `stride` is mp.

      Parameters:
        `flags` - specifying features demanded and the navigational capabilities of the consumer
        `start` - index in the current buffer
        `count` - number of items in the required slice
        `stride` - index-distance in the current buffer between consecutive items in the slice
      Returns:
        a buffer representing the slice

Jython homepage