Interface DirectAccessible


public interface DirectAccessible

Direct accessible array: an object that can be viewed as a Java array or a part of Java array.

Some AlgART arrays, built on Java arrays internally, implement this interface to provide quick access to their elements. Such arrays are called "direct accessible". In this library, direct accessible arrays are created by the SimpleMemoryModel class.

More precisely, a direct accessibly array is an object, for which the following conditions are fulfilled:

  1. it implements this DirectAccessible interface;
  2. its hasJavaArray() method returns true.

If you need quick access to some AlgART array, it's a good idea to create a special branch it the algorithm:

 if (array instanceof DirectAccessible && ((DirectAccessible) array).hasJavaArray()) {
     DirectAccessible da = (DirectAccessible) array;
     elements_type[] arr = (elements_type[]) da.javaArray();
         // here "elements_type" is "byte", "short", "Object", "String", etc.:
         // it should be the result of array.elementType()
     int ofs = da.javaArrayOffset();
     int len = da.javaArrayLength();
     // ... (access to elements arr[ofs]..arr[ofs+len-1])
 } else {
     // ... (access to elements via array.getXxx/setXxx methods)
 }
 

In some situations, the effect of such optimization is not very strong. For example, if the algorithm usually processes the AlgART array by large sequential blocks, loaded via Array.getData(long, Object) method, the optimization will be connected only with avoiding extra copying data in memory, and usually will not exceed 5-10%. In these cases, if you don't need to change the array elements, you should check, in addition, whether the array is copy-on-next-write:

 if (array instanceof DirectAccessible && !array.isCopyOnNextWrite() && ((DirectAccessible) array).hasJavaArray()) {
     DirectAccessible da = (DirectAccessible) array;
     elements_type[] arr = (elements_type[]) da.javaArray();
     int ofs = da.javaArrayOffset();
     int len = da.javaArrayLength();
     // ... (access to elements arr[ofs]..arr[ofs+len-1])
 } else {
     // ... (access to elements via array.get/set methods)
 }
 

Without the additional check, the call of javaArray() method will lead to cloning all internal storage, that can require a lot of memory and time almost without the benefit.

In other situations, the advantage of this optimization can be great, up to 10–100 times — usually in algorithms, which need random access to array elements, alike sorting algorithms, Fourier transform, scanning boundaries of particles on images, etc. In such cases, there is no reasons to check the copy-on-next-write flag.

Warning: immutable arrays, created by asImmutable() method, never can be directly accessed via this interface: they either do not implement this interface, or their hasJavaArray() method returns false. However, if you trust the method processing an AlgART array, you can use asTrustedImmutable() method: "trusted" immutable arrays can implement this interface.

Warning: if an AlgART array implements DirectAccessible interface, it still can be impossible to create its array-view via javaArray() method: you must also call hasJavaArray() to be ensured that array-view is really possible.

Note: bit arrays in this package never implement DirectAccessible interface. According the contract, the Java array returned by javaArray() method must contain elements of the same type as the AlgART array, but the bits in bit AlgART arrays are packed and cannot be viewed as boolean[] array. However, you can use data buffers for direct block access to bit arrays.

Author:
Daniel Alievsky
See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    Returns true if, and only if, this object (usually AlgART array) is backed by an accessible Java array, that can be get by javaArray() method.
    Returns an array-view of this object: a pointer to internal Java array containing all content of this object (usually - all elements in this AlgART array).
    int
    Returns the actual number of elements in the Java array returned by javaArray() call, corresponding to all elements of this object.
    int
    Returns the start offset in the Java array returned by javaArray() call, corresponding to the first element of this object.
  • Method Details

    • hasJavaArray

      boolean hasJavaArray()
      Returns true if, and only if, this object (usually AlgART array) is backed by an accessible Java array, that can be get by javaArray() method. If (and only if) this method returns false, then javaArray() method throws NoJavaArrayException.
      Returns:
      true if this object is mutable and it is backed by an accessible Java array.
    • javaArray

      Object javaArray()
      Returns an array-view of this object: a pointer to internal Java array containing all content of this object (usually - all elements in this AlgART array). If there is no such an array, or access to it is disabled due to some reasons (for example, this AlgART array is immutable), throws NoJavaArrayException.

      Returned array can contain extra elements besides the content of this object. Really, this object (usually AlgART array) corresponds to elements #javaArrayOffset()..#javaArrayOffset()+javaArrayLength()-1 of the returned array. Changes to this range of the returned array "write through" to this object.

      If modifications of this AlgART array characteristics lead to reallocation of the internal storage, then the returned Java array ceases to be a view of this array. The only possible reasons for reallocation are the following: calling MutableArray.length(long), MutableArray.ensureCapacity(long) or MutableArray.trim() methods for this array, or any modification of this array in a case when this array is copy-on-next-write.

      It this object is an AlgART array, the type of returned Java array is always one of the following:

      Returns:
      a pointer to internal Java array containing all content of this object.
      Throws:
      NoJavaArrayException - if this object cannot be viewed as a Java array.
    • javaArrayOffset

      int javaArrayOffset()
      Returns the start offset in the Java array returned by javaArray() call, corresponding to the first element of this object.

      The result is undefined if this object is not backed by an accessible Java array. However, if this object is an immutable view of another mutable object a, then this method returns the same result as a.javaArrayOffset().

      Unlike javaArray() method, and unlike java.nio.ByteBuffer.arrayOffset(), this method does not throw any exceptions.

      Returns:
      the start offset in the array returned by javaArray() call.
    • javaArrayLength

      int javaArrayLength()
      Returns the actual number of elements in the Java array returned by javaArray() call, corresponding to all elements of this object. If this object is an AlgART array a, equivalent to (int)a.length().

      The result is undefined if this object is not backed by an accessible Java array. However, if this object is an immutable view of another mutable object a, then this method returns the same result as a.arrayLength().

      Unlike javaArray() method, this method does not throw any exceptions.

      Returns:
      the actual number of elements in the array returned by javaArray() call.