AlgART Home

net.algart.arrays
Class AbstractArray

java.lang.Object
  extended by net.algart.arrays.AbstractArray
All Implemented Interfaces:
java.lang.Cloneable, Array
Direct Known Subclasses:
AbstractBitArray, AbstractByteArray, AbstractCharArray, AbstractDoubleArray, AbstractFloatArray, AbstractIntArray, AbstractLongArray, AbstractObjectArray, AbstractShortArray

public abstract class AbstractArray
extends java.lang.Object
implements Array, java.lang.Cloneable

Implementation of basic functions of MutableArray interface.

This class implements only Array interface and doesn't implement UpdatableArray / MutableArray. (It is necessary to allow read-only arrays, implementing Array only, to be inheritors of AbstractArray. In other case, the user would be able to use illegal constructions as the following:

     Array ar = some immutable array (inheritor of AbstractArray);
     ((AbstractArray)ar)set(0, newValue);
 

This package guarantees that such illegal array operations are syntactically impossible.

Instead of implementing full MutableArray interface, this class provides default implementation for some methods of UpdatableArray / MutableArray via separate protected static methods: defaultCopy(UpdatableArray, Array), defaultSwap(UpdatableArray, UpdatableArray), defaultAppend(MutableArray, Array).

AlgART Laboratory 2007-2013

Since:
JDK 1.5
Version:
1.2
Author:
Daniel Alievsky

Field Summary
Modifier and Type Field and Description
protected  long capacity
          The current array's capacity.
protected  long length
          The current array's length.
protected  Array[] underlyingArrays
          The underlying arrays passed by the last constructor argument.
 
Constructor Summary
Modifier Constructor and Description
protected AbstractArray(long initialCapacityAndLength)
          Equivalent to AbstractArray(initialCapacityAndLength, initialCapacityAndLength, new Array[0]).
protected AbstractArray(long initialCapacity, long initialLength)
          Equivalent to AbstractArray(initialCapacity, initialLength, new Array[0]).
protected AbstractArray(long initialCapacity, long initialLength, Array... underlyingArrays)
          Creates an array with the given initial capacity and length.
 
Method Summary
Modifier and Type Method and Description
abstract  Array asCopyOnNextWrite()
          Returns a copy-on-next-write view of this array.
abstract  Array asImmutable()
          Returns an immutable view of this array.
abstract  Array asTrustedImmutable()
          Returns a trusted immutable view of this array.
 DataBuffer buffer()
          This implementation returns buffer(suitableMode), where suitableMode is this instanceof UpdatableArray ? DataBuffer.AccessMode.READ_WRITE : DataBuffer.AccessMode.READ.
 DataBuffer buffer(DataBuffer.AccessMode mode)
          This implementation returns buffer(mode, someCapacity), where mode is the argument of this method and someCapacity is the result of defaultBufferCapacity(thisArray) method.
 DataBuffer buffer(DataBuffer.AccessMode mode, long capacity)
          This method is fully implemented in this class.
 DataBuffer buffer(long capacity)
          This implementation returns buffer(suitableMode, capacity), where capacity is the argument of this method and suitableMode is this instanceof UpdatableArray ? DataBuffer.AccessMode.READ_WRITE : DataBuffer.AccessMode.READ.
 java.nio.ByteOrder byteOrder()
          This implementation returns ByteOrder.nativeOrder().
 long capacity()
          This implementation returns capacity & Long.MAX_VALUE.
static void checkCopyArguments(UpdatableArray thisArray, Array src)
          Checks whether the passed arguments correct for UpdatableArray.copy(Array) and throws corresponding exception if no.
protected  void checkSubArrArguments(long position, long count)
          Checks whether the passed arguments correct for subArr(long, long) and throws corresponding exception if no.
protected  void checkSubArrayArguments(long fromIndex, long toIndex)
          Checks whether the passed arguments correct for subArray(long, long) and throws corresponding exception if no.
static void checkSwapArguments(UpdatableArray thisArray, UpdatableArray another)
          Checks whether the passed arguments correct for UpdatableArray.swap(UpdatableArray) and throws corresponding exception if no.
abstract  void checkUnallowedMutation()
          Tries to check, whether some unallowed mutations of this trusted immutable array took place, and throw UnallowedMutationError in this case.
protected static MutableArray defaultAppend(MutableArray thisArray, Array appendedArray)
          Simplest implementation of MutableArray.append(Array), based on MutableArray.length(long), UpdatableArray.subArr(long, long) and UpdatableArray.copy(Array) methods.
protected static DataBuffer defaultBuffer(Array thisArray, DataBuffer.AccessMode mode, long capacity)
          Default implementation of buffer(net.algart.arrays.DataBuffer.AccessMode, long) method.
static int defaultBufferCapacity(Array thisArray)
          Returns the data buffer capacity used by buffer(net.algart.arrays.DataBuffer.AccessMode) and buffer() methods.
protected static void defaultCopy(UpdatableArray thisArray, Array src)
          Equivalent to defaultCopy(thisArray, src, false).
protected static void defaultCopy(UpdatableArray thisArray, Array src, boolean allowNulls)
          Possible implementation of UpdatableArray.copy(Array) based on Array.getData(long, Object) and UpdatableArray.setData(long, Object) methods (for some temporary array).
protected static void defaultSwap(UpdatableArray thisArray, UpdatableArray another)
          Possible implementation of UpdatableArray.swap(UpdatableArray) based on Array.getData(long, Object) and UpdatableArray.setData(long, Object) methods (for some temporary array).
abstract  java.lang.Class<?> elementType()
          Returns the type of array elements.
static boolean equals(Array obj1, java.lang.Object obj2)
          Default implementation of Array.equals(Object) method.
 boolean equals(java.lang.Object obj)
          This method is fully implemented in this class and is not be overridden usually.
 void flushResources(ArrayContext context)
          This implementation just calls flushResources(context, false).
 void flushResources(ArrayContext context, boolean forcePhysicalWriting)
          This implementation calls the same method with the same arguments for all underlying arrays, passed via the last argument of the constructor.
 void freeResources(ArrayContext context)
          This implementation just calls freeResources(context, false).
 void freeResources(ArrayContext context, boolean forcePhysicalWriting)
          This implementation calls the same method for all underlying arrays, passed via the last argument of the constructor.
abstract  void getData(long arrayPos, java.lang.Object destArray)
          Copies min(this.length() - arrayPos, destArray.length}) elements of this array, starting from arrayPos index, into the specified Java array of corresponding type, starting from 0 index.
abstract  void getData(long arrayPos, java.lang.Object destArray, int destArrayOffset, int count)
          Copies count elements of this array, starting from arrayPos index, into the specified Java array of corresponding type, starting from destArrayOffset index.
abstract  java.lang.Object getElement(long index)
          Returns the element #index.
 int hashCode()
          This method is fully implemented in this class and cannot be overridden (it is declared as final method here).
static int hashCode(Array array)
          Default implementation of Array.hashCode() method.
abstract  boolean isCopyOnNextWrite()
          Returns true if this array is copy-on-next-write.
abstract  boolean isImmutable()
          Returns true if this instance is immutable, i.e. there are no ways to change its content or state.
 boolean isLazy()
          This implementation returns underlyingArrays.length > 0.
 boolean isNew()
          This implementation returns a private boolean field, that is false by default, but can be changed by protected setNewStatus(boolean) method.
 boolean isNewReadOnlyView()
          This implementation returns a private boolean field, that is false by default, but can be changed by protected setNewReadOnlyViewStatus() method.
abstract  boolean isUnresizable()
          Returns true if this instance is unresizable, i.e. there are no ways to change its length or capacity.
 boolean isZeroFilled()
          This method of PArray interface is fully implemented in this class.
 long length()
          This implementation returns length & Long.MAX_VALUE.
 void loadResources(ArrayContext context)
          This implementation does nothing.
 MutableArray mutableClone(MemoryModel memoryModel)
          This implementation performs the following: memoryModel.newArray(thisArray).copy(thisArray).
abstract  java.lang.Class<? extends MutableArray> mutableType()
          Returns the canonical resizable AlgART type of arrays with the same element types: the class of one of 9 basic interfaces, describing all kinds of resizable AlgART arrays for 8 primitive and any non-primitive element types.
 java.lang.Object newJavaArray(int length)
          This implementation returns java.lang.reflect.Array.newInstance(elementType(), length).
protected  void setNewReadOnlyViewStatus()
          Sets to true the value of the private boolean field returned by isNewReadOnlyView() method.
protected  void setNewStatus(boolean value)
          Sets the value of the private boolean field returned by isNew() method.
 Array shallowClone()
          This implementation returns standardObjectClone().
protected  AbstractArray standardObjectClone()
          Performs default Object.clone() call and clears in its result both new status and new-read-only-view status.
 Array subArr(long position, long count)
          This implementation returns subArray(position, position + count).
abstract  Array subArray(long fromIndex, long toIndex)
          Returns a view of the portion of this array between fromIndex, inclusive, and toIndex, exclusive.
abstract  java.lang.String toString()
          Returns a brief string description of this object.
abstract  java.lang.Class<? extends Array> type()
          Returns the canonical AlgART type of this array: the class of one of 9 basic interfaces, describing all kinds of AlgART arrays for 8 primitive and any non-primitive element types.
 UpdatableArray updatableClone(MemoryModel memoryModel)
          This implementation performs the following: memoryModel.newUnresizableArray(thisArray).copy(thisArray).
abstract  java.lang.Class<? extends UpdatableArray> updatableType()
          Returns the canonical updatable AlgART type of arrays with the same element types: the class of one of 9 basic interfaces, describing all kinds of updatable AlgART arrays for 8 primitive and any non-primitive element types.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

capacity

protected long capacity
The current array's capacity.


length

protected long length
The current array's length.


underlyingArrays

protected Array[] underlyingArrays
The underlying arrays passed by the last constructor argument. It is the same reference, which was passed to the constructor (not its clone).

Constructor Detail

AbstractArray

protected AbstractArray(long initialCapacity,
                        long initialLength,
                        Array... underlyingArrays)
Creates an array with the given initial capacity and length. Does not check the initialCapacity and initialLength arguments: they may contain any values, for example, negative. Some implementations may use bit #63 for service goals.

If the created array is a view of some another AlgART arrays, as result of Arrays.asFuncArray method, all these arrays should be passed by underlyingArrays argument. The Array.flushResources(ArrayContext), Array.flushResources(ArrayContext, boolean) and Array.freeResources(ArrayContext, boolean) methods in the created instance, and also in all its views created by subArray(long, long), subArr(long, long) or asImmutable() methods, will call the same methods of all underlying arrays specified by this argument.

Parameters:
initialCapacity - initial capacity of the array.
initialLength - initial length of the array.
underlyingArrays - the created arrays is a view of the arrays passed by this argument.
Throws:
java.lang.NullPointerException - if underlyingArrays is null.

AbstractArray

protected AbstractArray(long initialCapacity,
                        long initialLength)
Equivalent to AbstractArray(initialCapacity, initialLength, new Array[0]).

Parameters:
initialCapacity - initial capacity of the array.
initialLength - initial length of the array.

AbstractArray

protected AbstractArray(long initialCapacityAndLength)
Equivalent to AbstractArray(initialCapacityAndLength, initialCapacityAndLength, new Array[0]).

Parameters:
initialCapacityAndLength - initial capacity and length of the array.
Method Detail

elementType

public abstract java.lang.Class<?> elementType()
Description copied from interface: Array
Returns the type of array elements. For arrays of primitive types, returns: All elements of the array are values of this type or (for non-primitive types) some inheritor of this type.

There is a guarantee that this method works very quickly (usually it just returns a value of some private field).

Specified by:
elementType in interface Array
Returns:
the type of array elements.
See Also:
Arrays.elementType(Class)

type

public abstract java.lang.Class<? extends Array> type()
Description copied from interface: Array
Returns the canonical AlgART type of this array: the class of one of 9 basic interfaces, describing all kinds of AlgART arrays for 8 primitive and any non-primitive element types. More precisely, returns:

There is a guarantee that this method works very quickly (usually it just returns a constant value).

Specified by:
type in interface Array
Returns:
canonical AlgART type of this array.

updatableType

public abstract java.lang.Class<? extends UpdatableArray> updatableType()
Description copied from interface: Array
Returns the canonical updatable AlgART type of arrays with the same element types: the class of one of 9 basic interfaces, describing all kinds of updatable AlgART arrays for 8 primitive and any non-primitive element types. More precisely, returns:

There is a guarantee that this method works very quickly (usually it just returns a constant value).

Specified by:
updatableType in interface Array
Returns:
canonical AlgART type of an updatable array of the same kind.

mutableType

public abstract java.lang.Class<? extends MutableArray> mutableType()
Description copied from interface: Array
Returns the canonical resizable AlgART type of arrays with the same element types: the class of one of 9 basic interfaces, describing all kinds of resizable AlgART arrays for 8 primitive and any non-primitive element types. More precisely, returns:

There is a guarantee that this method works very quickly (usually it just returns a constant value).

Specified by:
mutableType in interface Array
Returns:
canonical AlgART type of a resizable array of the same kind.

length

public long length()
This implementation returns length & Long.MAX_VALUE. (The high bit of length may be used for service goals.)

Specified by:
length in interface Array
Returns:
the number of elements in this array.

capacity

public long capacity()
This implementation returns capacity & Long.MAX_VALUE. (The high bit of capacity may be used for service goals.)

Specified by:
capacity in interface Array
Returns:
the capacity of this array.

getElement

public abstract java.lang.Object getElement(long index)
Description copied from interface: Array
Returns the element #index. It this array contains elements of primitive types, the value is automatically wrapped in an object (Boolean, Byte, etc.).

It is a low-level method. For arrays of primitive elements, implementing one of corresponding interfaces BitArray, CharArray, ByteArray, ShortArray, IntArray, LongArray, FloatArray, DoubleArray, we recommend to use more efficient equivalent method of that interfaces: BitArray.getBit(long), CharArray.getChar(long), ByteArray.getByte(long), ShortArray.getShort(long), IntArray.getInt(long), LongArray.getLong(long), FloatArray.getFloat(long), DoubleArray.getDouble(long). For other arrays, implementing ObjectArray, we recommend to use ObjectArray.get(long).

Specified by:
getElement in interface Array
Parameters:
index - index of element to get.
Returns:
the element at the specified position in this array.

getData

public abstract void getData(long arrayPos,
                             java.lang.Object destArray,
                             int destArrayOffset,
                             int count)
Description copied from interface: Array
Copies count elements of this array, starting from arrayPos index, into the specified Java array of corresponding type, starting from destArrayOffset index.

For non-primitive element type (ObjectArray, UpdatableObjectArray, MutableObjectArray subinterfaces), this method may allocate new instances for Java array elements destArray[destArrayOffset]..destArray[destArrayOffset+count-1], but also may change the state of already existing non-null elements: it depends on implementation. In any case, you can be sure that if some of target elements destArray[k]==null, this method always allocate new element.

Note: if IndexOutOfBoundsException occurs due to attempt to write data outside the passed Java array, the target Java array can be partially filled. In other words, this method can be non-atomic regarding this failure. All other possible exceptions are checked in the very beginning of this method before any other actions (the standard way for checking exceptions).

Specified by:
getData in interface Array
Parameters:
arrayPos - starting position in this AlgART array.
destArray - the target Java array.
destArrayOffset - starting position in the target Java array.
count - the number of elements to be copied.
See Also:
DirectAccessible, UpdatableArray.setData(long, Object, int, int), BitArray.getBits(long, long[], long, long)

getData

public abstract void getData(long arrayPos,
                             java.lang.Object destArray)
Description copied from interface: Array
Copies min(this.length() - arrayPos, destArray.length}) elements of this array, starting from arrayPos index, into the specified Java array of corresponding type, starting from 0 index.

For non-primitive element type (ObjectArray, UpdatableObjectArray, MutableObjectArray subinterfaces), this method may allocate new instances for Java array elements destArray[0]..destArray[count-1], but also may change the state of already existing non-null elements: it depends on implementation. In any case, you can be sure that if some of target elements destArray[k]==null, this method always allocate new element.

Note: if IndexOutOfBoundsException occurs due to attempt to write data outside the passed Java array, the target Java array can be partially filled. In other words, this method can be non-atomic regarding this failure. All other possible exceptions are checked in the very beginning of this method before any other actions (the standard way for checking exceptions).

Specified by:
getData in interface Array
Parameters:
arrayPos - starting position in this AlgART array.
destArray - the target Java array.
See Also:
DirectAccessible, Array.getData(long, Object, int, int), UpdatableArray.setData(long, Object)

newJavaArray

public java.lang.Object newJavaArray(int length)
This implementation returns java.lang.reflect.Array.newInstance(elementType(), length).

Specified by:
newJavaArray in interface Array
Parameters:
length - the length of created Java-array.
Returns:
Java-array with the specified length and the same type of elements.
Throws:
java.lang.NegativeArraySizeException - if the specified length is negative.

isZeroFilled

public boolean isZeroFilled()
This method of PArray interface is fully implemented in this class. If this instance does not implement PArray (i.e. if it is ObjectArray), this method throws UnsupportedOperationException.

Returns:
true if and only if all elements of this array are zero, or if this array is empty.
Throws:
java.lang.UnsupportedOperationException - if this instance is an array of non-primitive elements.

subArray

public abstract Array subArray(long fromIndex,
                               long toIndex)
Description copied from interface: Array
Returns a view of the portion of this array between fromIndex, inclusive, and toIndex, exclusive.

Like List.subList method, this method eliminates the need for explicit range operations. For example, you may use Arrays.sort(UpdatableArray, ArrayComparator) method for sorting a fragment of the array.

Unlike List.subList, the semantics of the array returned by this method is well-defined in any case, even in case of resizing of the source array. Namely, if the internal storage of this or returned array is reallocated, then the returned array will cease 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 or returned array in a case when this array is copy-on-next-write. Also, if the length of this array will be reduced, it can lead to clearing some elements in returned array: see comments to MutableArray.length(long) method.

Specified by:
subArray in interface Array
Parameters:
fromIndex - low endpoint (inclusive) of the subarray.
toIndex - high endpoint (exclusive) of the subarray.
Returns:
a view of the specified range within this array.
See Also:
Array.subArr(long, long)

subArr

public Array subArr(long position,
                    long count)
This implementation returns subArray(position, position + count). Please note that the exception message can be not fully correct for the very exotic case position+count>Long.MAX_VALUE.

Specified by:
subArr in interface Array
Parameters:
position - start position (inclusive) of the subarray.
count - number of elements in the subarray.
Returns:
a view of the specified range within this array.
Throws:
java.lang.IndexOutOfBoundsException - for illegal position and count (position < 0 || count < 0 || position + count > length).
See Also:
Array.subArray(long, long)

buffer

public DataBuffer buffer(DataBuffer.AccessMode mode,
                         long capacity)
This method is fully implemented in this class.

The returned buffer will be direct, if mode is not PRIVATE, this array is not immutable, is not copy-on-next-write, and either it implements DirectAccessible interface and its hasJavaArray() method returns true, or it is a bit array created by the simple memory model.

Specified by:
buffer in interface Array
Parameters:
mode - the access mode for new buffer.
capacity - the capacity of the buffer
Returns:
new data buffer for accessing this array.
Throws:
java.lang.NullPointerException - if mode argument is null.
java.lang.IllegalArgumentException - if the mode is not the DataBuffer.AccessMode.READ, but this arrays does not implement UpdatableArray interface, or if the specified capacity is negative or too high (>=0..237 for bits or >=0..231 for other element types).
See Also:
Array.buffer(net.algart.arrays.DataBuffer.AccessMode), Array.buffer(long), Array.buffer()

buffer

public DataBuffer buffer(DataBuffer.AccessMode mode)
This implementation returns buffer(mode, someCapacity), where mode is the argument of this method and someCapacity is the result of defaultBufferCapacity(thisArray) method.

Specified by:
buffer in interface Array
Parameters:
mode - the access mode for new buffer.
Returns:
new data buffer for accessing this array.
Throws:
java.lang.NullPointerException - if mode argument is null.
java.lang.IllegalArgumentException - if the mode is not the DataBuffer.AccessMode.READ, but this arrays does not implement UpdatableArray interface.

buffer

public DataBuffer buffer(long capacity)
This implementation returns buffer(suitableMode, capacity), where capacity is the argument of this method and suitableMode is this instanceof UpdatableArray ? DataBuffer.AccessMode.READ_WRITE : DataBuffer.AccessMode.READ.

Specified by:
buffer in interface Array
Parameters:
capacity - the capacity of the buffer.
Returns:
new data buffer for accessing this array.
Throws:
java.lang.IllegalArgumentException - if the specified capacity is negative or too high (>=0..237 for bits or >=0..231 for other element types).

buffer

public DataBuffer buffer()
This implementation returns buffer(suitableMode), where suitableMode is this instanceof UpdatableArray ? DataBuffer.AccessMode.READ_WRITE : DataBuffer.AccessMode.READ.

Specified by:
buffer in interface Array
Returns:
new data buffer for accessing this array.

asImmutable

public abstract Array asImmutable()
Description copied from interface: Array
Returns an immutable view of this array. If this array is already immutable (i.e. Array.isImmutable() is true), returns a reference to this object.

A array is considered to be immutable, if there are no ways to modify its content or state with help of this instance. In particular, immutable arrays never implement UpdatableArray or DirectAccessible interfaces. Moreover, any third-party implementation of Array interface must return an instance of a class, which has no public methods or fields allowing to change this instance.

Query operations on the returned array "read through" to this array. The returned view is also unresizable (see UpdatableArray.asUnresizable()).

The returned view (when it is not a reference to this object) contains the same elements as this array, but independent length, start offset, capacity, copy-on-next-write and possible other information about array characteristics besides its elements, as for Array.shallowClone() method. If modifications of this array characteristics lead to reallocation of the internal storage, then the returned 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 or returned array in a case when this array is copy-on-next-write.

By default, the array factories (memory models) create mutable arrays, but they can be converted to immutable by this method.

Note: Array.isNew() method, called for the result of this method, always returns false — because it does not implement UpdatableArray.

Also note: Array.isNewReadOnlyView() method, called for the result of this method, always returns the same value as Array.isNewReadOnlyView() for this object. Really,

Specified by:
asImmutable in interface Array
Returns:
an immutable view of this array (or a reference to this array if it is already immutable).
See Also:
Array.isImmutable(), Array.asTrustedImmutable(), Array.mutableClone(MemoryModel), Array.updatableClone(MemoryModel), UpdatableArray.asUnresizable()

isImmutable

public abstract boolean isImmutable()
Description copied from interface: Array
Returns true if this instance is immutable, i.e. there are no ways to change its content or state. (See Array.asImmutable() method for more details.)

It is possible that array is immutable in fact, but this method returns false: for example, if the array is mapped to read-only file. However, it is guaranteed: if the array was created via Array.asImmutable() method, this method returns true.

Typically, this method returns true if the array:

  1. does not implement UpdatableArray interface;
  2. does not implement DirectAccessible interface, or implements it, but DirectAccessible.hasJavaArray() method returns false.

But you should not use these conditions to check whether an array is immutable; please use this method instead. In principle, it is possible that both these conditions are satisfied, but the array is though mutable. Maybe, some class from another package (or from future versions of this package), implementing Array interface, does not implement neither UpdatableArray, nor DirectAccessible, but offers another methods allowing to change its state or content.

Note: if this method returns true, it does not mean that its content cannot be modified at all. Quite the contrary, usually an immutable array a is just an immutable view of another mutable array b (created via a=b.Array.asImmutable() call), and the original array b does allow to change the content of the immutable array a. Immutability means only that there are no ways to modify the content or state of the object a, if this object a is the only reference to its content, which you have. The same note is true for immutable collections, created by the standard Collections.unmodifiableList and analogous methods. Please compare this with the behaviour of another method Array.isNewReadOnlyView().

There is a guarantee that this method works very quickly (usually it just returns a constant or a value of some private field).

Specified by:
isImmutable in interface Array
Returns:
true if this instance is immutable.
See Also:
Array.asImmutable()

asTrustedImmutable

public abstract Array asTrustedImmutable()
Description copied from interface: Array
Returns a trusted immutable view of this array. If this array is already trusted immutable, returns a reference to this object.

A array is considered to be "trusted" immutable, if it potentially can change its elements, but the Java code working with this array promises that it will not change them. The returned instance never implements UpdatableArray, but may implement DirectAccessible, that allow quick access to its elements. As for usual immutable view, query operations on the returned array "read through" to this array.

The only standard way allowing to change elements of returned array is using DirectAccessible.javaArray() method, in a case when the array is backed by an accessible array. But the Java code, processing the trusted immutable array, must use this method only for quick reading elements and not try to change them. If, despite the promise, the elements of the trusted immutable array will be changed, the UnallowedMutationError may be thrown by the call of Array.checkUnallowedMutation() method.

In some implementations — for example, if DirectAccessible interface is not supported by this array — this method may return the same result as Array.asImmutable().

The returned view is always unresizable.

The returned view (when it is not a reference to this object) contains the same elements as this array, but independent length, start offset, capacity, copy-on-next-write and possible other information about array characteristics besides its elements, as for Array.shallowClone() method. If modifications of this array characteristics lead to reallocation of the internal storage, then the returned 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 or returned array in a case when this array is copy-on-next-write.

Trusted immutable view is a compromise between absolute safety, provided by usual immutable view, and maximal efficiency, achieved while using the original non-protected array. Please see the package description to learn more about possible usage of this method.

Specified by:
asTrustedImmutable in interface Array
Returns:
a trusted immutable view of this array (or a reference to this array if it is already trusted immutable).
See Also:
Array.asImmutable(), Array.checkUnallowedMutation()

checkUnallowedMutation

public abstract void checkUnallowedMutation()
                                     throws UnallowedMutationError
Description copied from interface: Array
Tries to check, whether some unallowed mutations of this trusted immutable array took place, and throw UnallowedMutationError in this case. Does nothing if this array implement UpdatableArray interface or if it is truly immutable.

Implementation of this method usually checks whether the hash code was changed since array creation.

We recommend to call this method in finally sections after using the trusted immutable array. If it is impossible to create necessary finally section, you may use Finalizer class (or an equivalent tool) to schedule call of this method for the shallow clone of this array on deallocation of this array:

 Finalizer fin = ...(some global application finalizer);
 final Array dup = thisArray.shallowClone();
 // - must be here, not inside the following inner class, to allow deallocation of thisArray
 fin.invokeOnDeallocation(thisArray, new Runnable() {
     public void run() {
         try {
             dup.checkUnallowedMutation();
         } catch (UnallowedMutationError ex) {
             myLogger.severe(ex.toString());
         }
     }
 });
 
Important: while using this finalization scheme, this array must not be copy-on-next-write! Illegal modifications of copy-on-next-write array will not change it's shallow clone and will not be detected.

Specified by:
checkUnallowedMutation in interface Array
Throws:
UnallowedMutationError - if some unallowed mutations of this array took place.
See Also:
Array.asTrustedImmutable()

asCopyOnNextWrite

public abstract Array asCopyOnNextWrite()
Description copied from interface: Array
Returns a copy-on-next-write view of this array. If this array is immutable (and only in this case), returns a reference to this object. If (and only if) this array implements UpdatableArray interface, then the returned array also implements it. If (and only if) this array implements MutableArray interface, then the returned array also implements it.

Copy-on-next-write array is a array with the following special feature: the next attempt (but not further!) to modify this array, or any other access that can lead to its modification (like DirectAccessible.javaArray() method), will lead to reallocation of the underlying storage, used for array elements, before performing the operation. In other words, you have a guarantee: if this array is a view of some another array or data (for example, a subarray or a view of Java array, that there are no ways to change that data via accessing the returned array. Any changes, it they will occur, will be performed with the newly allocated storage only.

Moreover, there are no guarantees that the returned array will be a view of this one, even immediately after creation. Some implementations of updatable arrays may just return the full (deep) copy of this object, alike Array.mutableClone(MemoryModel) method, and in this case TooLargeArrayException is possible. All implementations from this package, excepting AbstractUpdatableXxxArray classes, returns a view; but in AbstractUpdatableXxxArray classes this method is equivalent to updatableClone(Arrays.SMM).

Please note that copy-on-next-write arrays are not traditional copy-on-write objects like CopyOnWriteArrayList! In particular, copy-on-next-write arrays are not thread-safe.

The main purpose of using copy-on-next-write arrays is more efficient alternative to cloning and creating quite immutable views, when we need to be sure that original data will not be corrupted. Please see the package description to learn more about possible usage of this technique.

Specified by:
asCopyOnNextWrite in interface Array
Returns:
a copy-on-next-write view of this array (or a reference to this array if it is immutable).
See Also:
Array.isCopyOnNextWrite(), MemoryModel.newLazyCopy(Array), MemoryModel.newUnresizableLazyCopy(Array)

isCopyOnNextWrite

public abstract boolean isCopyOnNextWrite()
Description copied from interface: Array
Returns true if this array is copy-on-next-write. In other words, if this method returns true, it means that the next attempt (but not further) to modify this array, or any other access that can lead to its modification (like DirectAccessible.javaArray() method), will lead to reallocation of the underlying storage. After reallocation, the array will cease to be copy-on-next-write: further calls of this method will return false.

This method can be useful if it's possible to select another, more optimal algorithm branch, allowing to avoid reallocation for copy-on-next-write arrays. The typical example is usage of DirectAccessible interface. That interface, providing direct access to the internal Java array (which is a storage of the array elements), can optimize most of algorithms processing a array. However, reallocation of the Java array, that will be a result of calling DirectAccessible.javaArray() for copy-on-next-write array, can make such "optimization" very unwanted.

The only standard way to make copy-on-next-write is calling Array.asCopyOnNextWrite() method.

There is a guarantee that this method works very quickly (usually it just returns a constant or a value of some private field).

Specified by:
isCopyOnNextWrite in interface Array
Returns:
true if this array is copy-on-next-write.
See Also:
Array.asCopyOnNextWrite()

isUnresizable

public abstract boolean isUnresizable()
Description copied from interface: Array
Returns true if this instance is unresizable, i.e. there are no ways to change its length or capacity.

It is guaranteed that if the array was created via Array.asImmutable() method, this method returns true.

Typically, this method returns true if the array does not implement MutableArray. But you should not use this condition to check whether a array is unresizable; please use this method instead. Maybe, some class from another package (or from future versions of this package), implementing this Array interface, does not implement MutableArray, but offer another methods allowing to change its state or content.

There is a guarantee that this method works very quickly (usually it just returns a constant or a value of some private field).

Specified by:
isUnresizable in interface Array
Returns:
true if this instance is unresizable.
See Also:
UpdatableArray.asUnresizable()

isNew

public boolean isNew()
This implementation returns a private boolean field, that is false by default, but can be changed by protected setNewStatus(boolean) method.

Specified by:
isNew in interface Array
Returns:
whether this array instance if new: a new object, allocated by some MemoryModel.
See Also:
Array.isNewReadOnlyView()

isNewReadOnlyView

public boolean isNewReadOnlyView()
This implementation returns a private boolean field, that is false by default, but can be changed by protected setNewReadOnlyViewStatus() method.

Specified by:
isNewReadOnlyView in interface Array
Returns:
whether this array instance is a newly created view of some external data, providing read-only access to this data.

isLazy

public boolean isLazy()
This implementation returns underlyingArrays.length > 0. Please override this if the access to underlying arrays is very quick (as for Matrix.subMatrix(long[], long[]) or, vice versa, if there no underlying arrays, but getting an element requires some calculation (as for Arrays.asIndexFuncArray(net.algart.math.functions.Func, Class, long)).

Specified by:
isLazy in interface Array
Returns:
true if and only if underlyingArrays is non-empty.

byteOrder

public java.nio.ByteOrder byteOrder()
This implementation returns ByteOrder.nativeOrder().

Specified by:
byteOrder in interface Array
Returns:
ByteOrder.nativeOrder()

shallowClone

public Array shallowClone()
This implementation returns standardObjectClone().

Be careful: if you are extending this class to implement full MutableArray interface, your should investigate, whether you need to override this method to provide real independence of the length, start offset, capacity, copy-on-next-write and other information about any array characteristics besides its elements.

Specified by:
shallowClone in interface Array
Returns:
a shallow copy of this object.
See Also:
Array.length(), Array.capacity(), DirectAccessible.javaArrayOffset(), Array.isCopyOnNextWrite()

mutableClone

public MutableArray mutableClone(MemoryModel memoryModel)
This implementation performs the following: memoryModel.newArray(thisArray).copy(thisArray).

Specified by:
mutableClone in interface Array
Parameters:
memoryModel - the memory model, used for allocation a new copy of this array.
Returns:
a mutable copy of this array.
Throws:
java.lang.NullPointerException - if the argument is null.
UnsupportedElementTypeException - if thisArray.Array.elementType() is not supported by the specified memory model.
TooLargeArrayException - if the length of this array is too large for this the specified memory model.
See Also:
Array.updatableClone(MemoryModel)

updatableClone

public UpdatableArray updatableClone(MemoryModel memoryModel)
This implementation performs the following: memoryModel.newUnresizableArray(thisArray).copy(thisArray).

Specified by:
updatableClone in interface Array
Parameters:
memoryModel - the memory model, used for allocation a new copy of this array.
Returns:
an updatable copy of this array.
Throws:
java.lang.NullPointerException - if the argument is null.
UnsupportedElementTypeException - if thisArray.Array.elementType() is not supported by the specified memory model.
TooLargeArrayException - if the length of this array is too large for this the specified memory model.
See Also:
Array.mutableClone(MemoryModel)

loadResources

public void loadResources(ArrayContext context)
This implementation does nothing. You need to override it to provide (in a case of subarray) preloading correct part all underlying arrays, passed via the last argument of the constructor.

Specified by:
loadResources in interface Array
Parameters:
context - the context of execution; may be null, then it will be ignored.
See Also:
Array.freeResources(ArrayContext), Array.flushResources(ArrayContext), Array.flushResources(ArrayContext, boolean)

flushResources

public final void flushResources(ArrayContext context)
This implementation just calls flushResources(context, false).

Specified by:
flushResources in interface Array
Parameters:
context - the context of execution; may be null, then it will be ignored.
See Also:
Array.loadResources(ArrayContext), Array.freeResources(ArrayContext)

flushResources

public void flushResources(ArrayContext context,
                           boolean forcePhysicalWriting)
This implementation calls the same method with the same arguments for all underlying arrays, passed via the last argument of the constructor. Please override it if you want to provide (in a case of subarray) flushing correct part of the underlying arrays.

Specified by:
flushResources in interface Array
Parameters:
context - the context of execution; may be null, then it will be ignored.
forcePhysicalWriting - is it necessary to try forcing physical writing all associated resources to the external device.
See Also:
Array.loadResources(ArrayContext), Array.flushResources(ArrayContext), Array.freeResources(ArrayContext, boolean)

freeResources

public final void freeResources(ArrayContext context)
This implementation just calls freeResources(context, false).

Specified by:
freeResources in interface Array
Parameters:
context - the context of execution; may be null, then it will be ignored.
See Also:
Array.loadResources(ArrayContext), Array.flushResources(ArrayContext)

freeResources

public void freeResources(ArrayContext context,
                          boolean forcePhysicalWriting)
This implementation calls the same method for all underlying arrays, passed via the last argument of the constructor. Please override it if you want to provide (in a case of subarray) freeing correct part of the underlying arrays.

Specified by:
freeResources in interface Array
Parameters:
context - the context of execution; may be null, then it will be ignored.
forcePhysicalWriting - is it necessary to try forcing physical writing all associated resources to the external device.
See Also:
Array.loadResources(ArrayContext context), Array.flushResources(ArrayContext context, boolean forcePhysicalWriting), Array.freeResources(ArrayContext), Arrays.freeAllResources()

toString

public abstract java.lang.String toString()
Description copied from interface: Array
Returns a brief string description of this object.

The result of this method may depend on implementation and usually contains a short description of the array length, capacity, element type.

Note: for character arrays, unlike CharSequence.toString(), this method works as for all other array types. If you need to convert a character array to a string, containing all characters of the array, you may use Arrays.toString(CharArray) method.

Specified by:
toString in interface Array
Overrides:
toString in class java.lang.Object
Returns:
a brief string description of this object.

hashCode

public final int hashCode()
This method is fully implemented in this class and cannot be overridden (it is declared as final method here).

For non-primitive element type (ObjectArray subinterfaces), this implementation is based on calls of hashCode method of the class of elements (elementType()).

This method is equivalent to the following call: hashCode(this).

Specified by:
hashCode in interface Array
Overrides:
hashCode in class java.lang.Object
Returns:
the hash code of this array.

equals

public boolean equals(java.lang.Object obj)
This method is fully implemented in this class and is not be overridden usually.

For non-primitive element type (ObjectArray subinterface), this implementation is based on calls of equals method of the class of elements (elementType()).

This method is equivalent to the following call: equals(this, obj).

In some cases, you may override this method to provide better performance or to exclude dependence on elements' equals method. (For example, this method is overridden in combined arrays.)

Specified by:
equals in interface Array
Overrides:
equals in class java.lang.Object
Parameters:
obj - the object to be compared for equality with this array.
Returns:
true if the specified object is an AlgART array equal to this one.

hashCode

public static int hashCode(Array array)
Default implementation of Array.hashCode() method.

All classes implementing Array interface, that do not extend AbstractArray, must use this method or fully equivalent algorithm to ensure correct arrays behavior. Classes that extend AbstractArray always inherit standard implementation AbstractArray.hashCode().

Parameters:
array - the AlgART array.
Returns:
the hash code of this array.

equals

public static boolean equals(Array obj1,
                             java.lang.Object obj2)
Default implementation of Array.equals(Object) method.

All classes implementing Array interface must use this method or fully equivalent algorithm to ensure correct arrays behavior. Classes that extend AbstractArray may just inherit standard implementation AbstractArray.equals(Object).

Parameters:
obj1 - first compared object.
obj2 - second compared object.
Returns:
true if obj2 is a array and the specified arrays are equal.

defaultBufferCapacity

public static int defaultBufferCapacity(Array thisArray)
Returns the data buffer capacity used by buffer(net.algart.arrays.DataBuffer.AccessMode) and buffer() methods. The result is calculated so that the buffer occupies ~16-32 KB RAM.

In any case, you can be sure that the result will not be greater than Integer.MAX_VALUE-64.

Parameters:
thisArray - this array.
Returns:
default data buffer capacity, suitable for this array.

checkCopyArguments

public static void checkCopyArguments(UpdatableArray thisArray,
                                      Array src)
Checks whether the passed arguments correct for UpdatableArray.copy(Array) and throws corresponding exception if no. More precisely, this method throws IllegalArgumentException if is not possible to assign elements of src array to elements of thisArray, i.e. if !thisArray.elementType().isAssignableFrom(src.elementType()).

Note: for primitive array types (PArray and its inheritors), this method throws an exception if and only if thisArray.elementType()!=src.elementType().

Parameters:
thisArray - this array.
src - the source array.
Throws:
java.lang.NullPointerException - if thisArray or src argument is null.
java.lang.IllegalArgumentException - if the source and destination element types do not match.

checkSwapArguments

public static void checkSwapArguments(UpdatableArray thisArray,
                                      UpdatableArray another)
Checks whether the passed arguments correct for UpdatableArray.swap(UpdatableArray) and throws corresponding exception if no. More precisely, this method throws IllegalArgumentException if another array thisArray have different element types, i.e. if thisArray.elementType()!=another.elementType().

Parameters:
thisArray - this array.
another - another array.
Throws:
java.lang.NullPointerException - if thisArray or src argument is null.
java.lang.IllegalArgumentException - if another and this element types do not match.

standardObjectClone

protected final AbstractArray standardObjectClone()
Performs default Object.clone() call and clears in its result both new status and new-read-only-view status. In other words, it is a usual clone with the only difference, that Array.isNew() and Array.isNewReadOnlyView() methods returns false in the returned object. (It is a requirement of the contracts of these methods.)

The call of this method is a suitable implementation of shallowClone() method for most cases.

Please note that this method clones a reference underlyingArrays and does not tries to create a clone of this Java array.

Returns:
result of default Object.clone()

checkSubArrayArguments

protected final void checkSubArrayArguments(long fromIndex,
                                            long toIndex)
Checks whether the passed arguments correct for subArray(long, long) and throws corresponding exception if no.

Parameters:
fromIndex - low endpoint (inclusive) of the subarray.
toIndex - high endpoint (exclusive) of the subarray.
Throws:
java.lang.IndexOutOfBoundsException - for illegal fromIndex and toIndex (fromIndex < 0 || toIndex > length() || fromIndex > toIndex).

checkSubArrArguments

protected final void checkSubArrArguments(long position,
                                          long count)
Checks whether the passed arguments correct for subArr(long, long) and throws corresponding exception if no.

Parameters:
position - start position (inclusive) of the subarray.
count - number of elements in the subarray.
Throws:
java.lang.IndexOutOfBoundsException - for illegal position and count (position < 0 || count < 0 || position + count > length()).

setNewStatus

protected final void setNewStatus(boolean value)
Sets the value of the private boolean field returned by isNew() method.

This method is called with true argument while allocating new AlgART array and reallocating internal storage, for example, in copy-on-next-write arrays. This method is called with false argument in UpdatableArray.setNonNew() method only. In your inheritors of this class, you must not provide an ability (via public methods) to call this method with true argument.

If the argument is false, this instance must implement UpdatableArray interface. In other case, UnsupportedOperationException will be thrown.

The access to the "new status", provided by this and isNew() method, is always internally synchronized (the corresponding private field is volatile). So, changing "new-read-only-view status" by this method will be immediately visible in all threads using this instance.

Parameters:
value - new "new status".
Throws:
java.lang.UnsupportedOperationException - if the argument is false and this instance does not implement UpdatableArray interface.

setNewReadOnlyViewStatus

protected final void setNewReadOnlyViewStatus()
Sets to true the value of the private boolean field returned by isNewReadOnlyView() method.

This method is called creating a view of external data, providing read-only access to this data. In this package, it is called only by LargeMemoryModel.asArray(Object, Class, long, long, java.nio.ByteOrder) method, its strict equivalents asBitArray, asCharArray, etc. and by LargeMemoryModel.asMatrix(Object, MatrixInfo) method, and only in a case when the data offset, specified while calling these methods, is zero.

In your inheritors of this class, you must not provide an ability (via public methods) to call this method.

If the argument is false, this instance must implement UpdatableArray interface. In other case, UnsupportedOperationException will be thrown.

The access to the "new-read-only-view status", provided by this and isNewReadOnlyView() method, is always internally synchronized (the corresponding private field is volatile). So, changing "new-read-only-view status" by this method will be immediately visible in all threads using this instance.

Throws:
java.lang.UnsupportedOperationException - if this instance implements UpdatableArray interface.

defaultBuffer

protected static DataBuffer defaultBuffer(Array thisArray,
                                          DataBuffer.AccessMode mode,
                                          long capacity)
Default implementation of buffer(net.algart.arrays.DataBuffer.AccessMode, long) method.

Parameters:
thisArray - this array.
mode - the access mode for new buffer.
capacity - the capacity of the buffer
Returns:
new data buffer for accessing this array.
Throws:
java.lang.NullPointerException - if mode argument is null.
java.lang.IllegalArgumentException - if the mode is not the DataBuffer.AccessMode.READ, but this arrays does not implement UpdatableArray interface, or if the specified capacity is negative or too high (>=0..237 for bits or >=0..231 for other element types).

defaultCopy

protected static void defaultCopy(UpdatableArray thisArray,
                                  Array src)
Equivalent to defaultCopy(thisArray, src, false).

Parameters:
thisArray - this array.
src - the source array.
Throws:
java.lang.NullPointerException - if thisArray or src argument is null.
java.lang.IllegalArgumentException - if the source and destination element types do not match.

defaultCopy

protected static void defaultCopy(UpdatableArray thisArray,
                                  Array src,
                                  boolean allowNulls)
Possible implementation of UpdatableArray.copy(Array) based on Array.getData(long, Object) and UpdatableArray.setData(long, Object) methods (for some temporary array). Usually called in UpdatableArray.copy(Array) method in a case when src.getClass() != this.getClass().

If allowNulls argument is true, then this method, in addition to standard behavior, always allows to copy src when it is result of Arrays.nObjectCopies(..., null) and when thisArray is UpdatableObjectArray. (The element type of such source array is Object and usually cannot be assigned to element type of thisArray.)

Parameters:
thisArray - this array.
src - the source array.
allowNulls - whether this method should always allow filling object array by null.
Throws:
java.lang.NullPointerException - if thisArray or src argument is null.
java.lang.IllegalArgumentException - if the source and destination element types do not match.

defaultSwap

protected static void defaultSwap(UpdatableArray thisArray,
                                  UpdatableArray another)
Possible implementation of UpdatableArray.swap(UpdatableArray) based on Array.getData(long, Object) and UpdatableArray.setData(long, Object) methods (for some temporary array). Usually called in swap method in a case when src.getClass() != this.getClass().

Parameters:
thisArray - this array.
another - another array.
Throws:
java.lang.NullPointerException - if thisArray or another argument is null.
java.lang.IllegalArgumentException - if another and this element types do not match.

defaultAppend

protected static MutableArray defaultAppend(MutableArray thisArray,
                                            Array appendedArray)
Simplest implementation of MutableArray.append(Array), based on MutableArray.length(long), UpdatableArray.subArr(long, long) and UpdatableArray.copy(Array) methods.

Parameters:
thisArray - this array.
appendedArray - appended array.
Returns:
this array.
Throws:
java.lang.NullPointerException - if thisArray or appendedArray argument is null.
java.lang.IllegalArgumentException - if the source and this element types do not match.
TooLargeArrayException - if the resulting array length is too large for this type of arrays.