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:
- it implements this
DirectAccessible
interface; - 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 TypeMethodDescriptionboolean
Returns true if, and only if, this object (usually AlgART array) is backed by an accessible Java array, that can be get byjavaArray()
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 byjavaArray()
call, corresponding to all elements of this object.int
Returns the start offset in the Java array returned byjavaArray()
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 byjavaArray()
method. If (and only if) this method returns false, thenjavaArray()
method throwsNoJavaArrayException
.- 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), throwsNoJavaArrayException
.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)
orMutableArray.trim()
methods for this array, or any modification of this array in a case when this array iscopy-on-next-write
.It this object is an AlgART array, the type of returned Java array is always one of the following:
- boolean[] for
BitArray
(this case never occurs for AlgART arrays from this package); - char[] for
CharArray
, - byte[] for
ByteArray
, - short[] for
ShortArray
, - int[] for
IntArray
, - long[] for
LongArray
, - float[] for
FloatArray
, - double[] for
DoubleArray
, - type[], where type is the result of
elementType()
method, in all other cases.
- 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.
- boolean[] for
-
javaArrayOffset
int javaArrayOffset()Returns the start offset in the Java array returned byjavaArray()
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 byjavaArray()
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.
-