Package net.algart.arrays
AlgART arrays and matrices: generalized arrays and matrices of any Java types and basic algorithms of their processing.
AlgART arrays are classes allowing to store one- or multi-dimensional random access arrays, containing elements of any Java type, including primitive types.
AlgART arrays are homogeneous: the type of elements of an array are the same (for primitive elements) or are inheritors of the same class (for non-primitive elements). AlgART arrays, unlike standard Java arrays, can be resizable: you can add elements to the array end or remove some elements at any time.
AlgART arrays include all basic functionality of the standard Java ArrayList class and of Java NIO buffers, but also provide a lot of new features.
The basic AlgART array interfaces are Array,
UpdatableArray, MutableArray:
one-dimensional arrays with any element type.
There are many subinterfaces with additional functionality and restrictions.
The basic interface fo representing AlgART multi-dimensional matrix is Matrix.
The classes Arrays and Matrices
offer a wide collection of useful functions for processing AlgART arrays and matrices.
Contents
- Main features of AlgART arrays
- The diagram of interfaces and implementations
- The maximal supported array length
- 5 levels of protection against unallowed changes
- Multithreading and synchronization
- Runtime exceptions and errors
- System properties used for customizing AlgART arrays
- Built-in logging
- Tasks that are better solved by standard Java collections
Main features of AlgART arrays
- The addressing of array elements is 63-bit. So, it's theoretically possible to
create and process arrays containing up to 263-1 (~1019)
elements of any primitive or non-primitive types, if OS and hardware can provide necessary amount
of memory or disk space. Please see also the section
"The maximal supported array length" below.
- Multi-dimensional arrays, named matrices, are supported via the
Matrixinterface. Any one-dimensional array can be viewed as a matrix and vice versa.
- AlgART arrays are implemented with help of special factories, named
Virtual Memory Models (
MemoryModelinterface), that provide a standard way of implementing any schemes for storing data, from simple Java arrays to mapped disk files. The current implementation offers 4 basic memory models:- the simplest and fastest
Simple memory model, that stores data in usual Java arrays; Buffer memory model, that use Java NIO buffers for storing data: it does not provide the maximal access speed, but can provide better overall performance in applications that require large amount of RAM, and also provides good compatibility with Java code working with channels and NIO buffers;- advanced
Large memory model, that can store large amount of primitive elements in mapped-files — it is the only way (in current Java versions) to create very large arrays, containing, theoretically, up to 263-1 elements; - special
Combined memory model, allowing efficient storing non-primitive elements in a set of another arrays — together with LargeMemoryModel, it allows to store more than 231-1 non-primitive elements in one array.
Large memory modelis based on special low-level factories, named Data File Models (DataFileModelinterface). Creating non-standard data file models allows to easily implement storing array elements in almost any possible devices or storages. For example, it's possible to create data file model that will represent a content of BufferedImage as AlgART array.
- the simplest and fastest
- Arrays implement maximal efficient memory usage. In particular, AlgART arrays allow to
use only 1 bit per element while storing boolean values, 4 bytes per elements
while storing int or float values, or 3*4=12 bytes per element while
storing Java objects consisting 3 int field, as for the following Circle object:
class Circle { int x; int y; int r; }Unlike this, Java NIO buffers allow efficient storing only non-boolean primitive elements, and standard ArrayList always stores every element as a separate instance, that require a lot of extra memory for simple structures.
- There are separate interfaces for almost all kinds of data access
that makes usage of arrays more simple and stable.
Namely, there are separate interfaces
for read-only access (
Array), read-write access without changing the array length (UpdatableArray), stack access — adding and removing the last element (Stack), and full access including resizing the array (MutableArray). In addition, there areDataBufferinterface, providing convenient and maximally efficient block access to AlgART arrays, andDirectAccessibleinterface for quick access to internal Java array if the elements are really stored in an underlying Java array. There is also full set of interfaces for quick and convenient access to elements of all primitive types.
This architectural solution allows safe programming style, when illegal array operations are syntactically impossible. For example, the methods, which process an AlgART array argument and calculate some results, but don't need any modifications of the passed array, declare their array argument as Array or XxxArray, where Xxx is Byte, Int, Float, ... — interfaces containing only reading, but not writing methods. The methods, which correct the array content, but don't need to add or remove array elements, declare their array argument as UpdatableArray (or UpdatableXxxArray) — interfaces containing only reading and writing, but not resizing methods. This solution allows to avoid "optional" operations, used for implementation of read-only arrays in standard Java libraries.
- The AlgART arrays architecture offers advanced
means for protection against unallowed changes of the array content.
Namely, any array can be
cloned(the simplest protection), converted toimmutableform, to more efficient (in some cases)trusted immutableform or to special quite safecopy-on-next-writeform. Also, any resizable array can be converted tounresizableform, which length is fixed. Using read-onlyArrayor unresizableUpdatableArrayinterfaces (and their inheritors for primitive types), instead of the fullMutableArray, also helps to avoid unwanted operations.
The diagram of interfaces and implementations
The basic set of AlgART array interfaces and classes can be represented as 3-dimensional structure.
The 1st dimension corresponds to the type of elements: there are separate interfaces and classes
for all 8 primitive Java types and for Object type (and its inheritors).
The 2nd dimension describes the array functionality:
read-only access (Array),
read/write access (UpdatableArray),
full access including resizing (MutableArray),
quick access to internal Java array (DirectAccessible).
The 3rd dimension is the Virtual Memory Model:
the scheme of storing array elements.
Below is a diagram of basic array interfaces and classes.
Simple memory model
(the only model that supports all element types) |
||||
| Read-only access | Read/write access | Stack access (adding/removing the last element) | Full access | Access to internal Java array |
Interfaces:Array,BitArray,CharArray,ByteArray,ShortArray,IntArray,LongArray,FloatArray,DoubleArray,ObjectArray
|
Interfaces:UpdatableArray,UpdatableBitArray,UpdatableCharArray,UpdatableByteArray,UpdatableShortArray,UpdatableIntArray,UpdatableLongArray,UpdatableFloatArray,UpdatableDoubleArray,UpdatableObjectArray
|
Interfaces:Stack,BitStack,CharStack,ByteStack,ShortStack,IntStack,LongStack,FloatStack,DoubleStack,ObjectStack
|
Interfaces:MutableArray,MutableBitArray,MutableCharArray,MutableByteArray,MutableShortArray,MutableIntArray,MutableLongArray,MutableFloatArray,MutableDoubleArray,MutableObjectArray
|
Interface
DirectAccessible:
implemented by all arrays excepting bit (boolean) ones
and immutable instances
|
Buffer memory model
and Large memory model
(support all primitive element types) |
||||
| Read-only access | Read/write access | Stack access (adding/removing the last element) | Full access | Access to internal Java array |
Interfaces:Array,BitArray,CharArray,ByteArray,ShortArray,IntArray,LongArray,FloatArray,DoubleArray,(but not ObjectArray)
|
Interfaces:UpdatableArray,UpdatableBitArray,UpdatableCharArray,UpdatableByteArray,UpdatableShortArray,UpdatableIntArray,UpdatableLongArray,UpdatableFloatArray,UpdatableDoubleArray(but not UpdatableObjectArray)
|
Interfaces:Stack,BitStack,CharStack,ByteStack,ShortStack,IntStack,LongStack,FloatStack,DoubleStack,(but not ObjectStack)
|
Interfaces:MutableArray,MutableBitArray,MutableCharArray,MutableByteArray,MutableShortArray,MutableIntArray,MutableLongArray,MutableFloatArray,MutableDoubleArray,(but not MutableObjectArray)
|
Interface
DirectAccessible:
is never implemented
|
CombinedMemoryModel memory model
(supports only non-primitive element types) |
||||
| Read-only access | Read/write access | Stack access (adding/removing the last element) | Full access | Access to internal Java array |
Interfaces:Array,ObjectArray,ObjectInPlaceArray (optional)
|
Interfaces:UpdatableArray,UpdatableObjectArray,UpdatableObjectInPlaceArray (optional)
|
Interfaces:ObjectStack
|
Interfaces:MutableArray,MutableObjectArray,MutableObjectInPlaceArray (optional)
|
Interface
DirectAccessible:
is never implemented
|
There are special superinterfaces for some groups of primitive types, allowing to specify any array with elements from such groups. The hierarchy is the following:
Arraysubinterfaces:PArraysubinterfaces:PFixedArraysubinterfaces:BitArrayCharArrayPIntegerArraysubinterfaces:
PFloatingArraysubinterfaces:
ObjectArray
Also, all subinterfaces of PFixedArray and
PFloatingArray are grouped into the common interface
PNumberArray (any primitive types excepting boolean
and char, alike java.lang.Number class).
There are the same hierarchies for updatable and mutable arrays, but not for stacks.
The maximal supported array length
The maximal possible length of AlgART array depends on the
memory model, which has created this array.
An attempt to create an array with length exceeding the limit, specified by the memory model,
or an attempt to increase the length
or capacity
of an existing array over this limit, leads to
TooLargeArrayException (instead of the usual OutOfMemoryError).
The maximal array lengths for different memory models are listed below.
Simple memory modelThe maximal array length is defined by the language limitations for arrays. So, it cannot exceed 231-1 — the maximal possible length of Java arrays, excepting bit arrays, that can contain up to 237-1 because they are packed into long[]. However, real Java Machines usually limit the maximal length of arrays by 231-1 bytes (though the language theoretically allows to defined an array with 231-1 elements). It reduces the maximal possible length of AlgART arrays. |
||
| The type of elements | Theoretical limit for array length | Usual real limit for array length |
boolean (BitArray) char ( CharArray) byte ( ByteArray) short ( ShortArray) int ( IntArray) long ( LongArray) float ( FloatArray) double ( DoubleArray) Object ( ObjectArray)
|
237-1 231-1 231-1 231-1 231-1 231-1 231-1 231-1 231-1 |
234-1 230-1 231-1 230-1 229-1 228-1 229-1 228-1 depends on JVM implementation and the size of objects |
| The real limits are less in 32-bit JVM,
that usually cannot utilize 2 GB of memory. |
Buffer memory modelThe maximal array length is defined by the Java API limitations for ByteBuffer class. This API use int type for the buffer length and allows creating direct NIO buffers only as views of ByteBuffer. So, the limit is 231-1 bytes. |
|
| The type of elements | The limit for array length |
boolean (BitArray) char ( CharArray) byte ( ByteArray) short ( ShortArray) int ( IntArray) long ( LongArray) float ( FloatArray) double ( DoubleArray)
|
234-1 230-1 231-1 230-1 229-1 228-1 229-1 228-1 |
| The real limits are less in 32-bit JVM,
that usually cannot utilize 2 GB of memory. |
Large memory modelThe maximal array length is limited by 263-1 bytes (the maximal supported file length in Java API and most OS), but also, of course, cannot exceed the common limit 263-1 elements (that is more strict limitation for bit arrays). |
|
| The type of elements | The limit for array length |
boolean (BitArray) char ( CharArray) byte ( ByteArray) short ( ShortArray) int ( IntArray) long ( LongArray) float ( FloatArray) double ( DoubleArray)
|
263-1 262-1 263-1 262-1 261-1 260-1 261-1 260-1 |
| In other words, the limits are so large that the real maximal array length
depends only on the available disk space. |
Combined memory modelThe maximal array length depends on the corresponding limit for a memory model, that is used by the combiner
which defines an algorithm of storing objects.
For example, if the storage is based on Large memory model,
the maximal array length usually depends only on the available disk space. |
5 levels of protection against unallowed changes
There is an often and important problem to protect some application data against unallowed changes, to avoid hard bugs connected with unexpected damage of application objects. Below is a typical code illustraging this problem:
DataClass a = ...; // some important data someResults = someObject.process(a); // some method that need read-only access to the argument
Here a is some "important" data, that must stay immutable while the following call of process method. Maybe, for example, some parallel threads are reading this object now. And someObject.process is a method, which, theoretically, should not correct the passed data: it only analyzes it and creates some result. But it's very possible, that we are not sure, that this method really fulfils it. Maybe, its implementation is downloaded from Internet (and can be written by a hacker to damage our application). Or this method performs very complex tasks, and we cannot be sure that it doesn't contain bugs.
Java arrays offer only one way to protect data against changes and to solve this issue: cloning an array. An example:
int[] a = ...; // some important array int[] protected = (int[])a.clone(); someResults = someObject.process(protected);
Here the process method can corrupt the passed argument, but the original array will stay unchanged.
Standard Java collections, as well as buffers from java.nio package, offer an additional method: making an immutable view. For example:
List a = ...; // some important list List protected = Collections.unmodifiableList(a); someResults = someObject.process(protected);
Now, if the process method will try to correct the passed argument, an exception will be thrown. This solution has an advantage: no additional memory is required for storing a clone.
AlgART array architecture supports 5 ways for solving this task, including 2 ways described above. We shall compare all them below.
1. Syntactical protection
The 1st solution is the simplest, fastest, but not safe enough. It is a syntactical solution. If the process method does not need to modify its argument, it should be declared with Array argument type, which doesn't contain any mutation methods at all:
public ResultType process(Array a);
A usage example:
Array a = ...; // maybe, there is MutableArray in this expression someResults = someObject.process(a);
Of course, it is not a problem to write a "malicious" process method which will correct its argument by operators alike the following: ((MutableArray)a).set(0, ...). However, if process method is written by you or by your colleagues, and you only need to protect against possible bugs, the syntactical protection will help you.
2. Cloning
It is a very simple and absolutely safe solution:
Array a = ...; Array protected = a.updatableClone(Arrays.SMM); // or a.mutableClone(...) someResults = someObject.process(protected);
Unfortunately, such a solution requires additional memory and time, even if the process method, really, does not try do modify its argument.
3. Immutable view
It is a traditional, also simple and absolutely safe method, used by standard Java collections and NIO buffers:
Array a = ...;
Array protected = a.asImmutable();
someResults = someObject.process(protected);
The difference from the analogous technique, implemented in standard Java libraries,
is absence of "optional" operations. In a case of Java collections, process
method will have an ability to call a mutation method
for the passed array, but this method will throw an exception.
Unlike this, Array.asImmutable() method returns
an object that does not implement any interfaces and does not contain
any methods, which allow to change data anyhow.
The main defect of this solution is disabling any possible optimization, based on direct access
to stored data. For example, DirectAccessible interface can allow access to
the Java array, internally used for storing elements. If process method needs a lot
of accesses to elements in random order, then using DirectAccessible interface
in a separate algorithm branch can optimize the method in times, in a case when the AlgART array is really
based on Java arrays. Unfortunately, an immutable view has no right to provide such direct access
to internal storage, because it is a possible way to corrupt the array.
4. Trusted immutable view
It is a compromise between absolute safety, provided by cloning and immutable views, and maximal efficiency, achieved while using syntactical protection only. An example of usage:
Array a = ...; Array protected = a.asTrustedImmutable(); try { someResults = someObject.process(protected); } finally { protected.checkUnallowedMutation(); }
Unlike usual immutable view, a trusted immutable view may implement some interfaces,
that allow to change the array content — only if it is really necessary for
optimization. (The only example of such interface in this package is DirectAccessible.)
So, the process method can corrupt the original array a.
However, any changes in the original array will be detected by the following call
"protected.checkUnallowedMutation()" with almost 100% probability,
and if the array was changed, UnallowedMutationError will be thrown.
To detect changes, checkUnallowedMutation usually calculates a hash code
and compares it with the hash code calculated in asTrustedImmutable method.
This technique is a suitable solution if you trust the authors of process method (for example, it is written by you or your colleagues), but this method is not trivial and you are not sure that all possible bugs in this method are already fixed. Unlike all other 4 protection methods, it is the only way to automatically detect such bugs: so, trusted immutable views can be very useful in a stage of testing application.
This solution have the following defects.
- It requires little additional time (for calculation of hash code) while calling
asTrustedImmutable()andcheckUnallowedMutation()methods. (However, as well as immutable views, this method does not require any additional memory.) - If there are another threads working with the original array,
then the unallowed changes of elements can lead to errors in that threads before
detecting these changes and throwing
UnallowedMutationError. - This method protects against algorithmic bugs, but not against a malicious method, specially written by a hacker. If the author of the method have read the source code of this package, it can perform changes of the array, which will not be detected by this technique.
5. Copy-on-next-write view
It is a more efficient alternative to cloning an array. This solution is also absolutely safe, but, sometimes, it requires additional memory and time. An example:
Array a = ...;
Array protected = a.asCopyOnNextWrite();
someResults = someObject.process(protected);
Now process method may freely change the passed argument (if it implements necessary
interfaces). However, the first (not further!) attempt to modify the passed protected 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. It means that modification will not affect
the original a array, but only protected array.
This solution is the best choice, if you need a strict guarantee that the original array
will not be modified (that is not provided by trusted immutable views), and you don't need
a guarantee that no additional memory will be occupied. If the process method
will not try to modify the array or use optimization interfaces alike DirectAccessible,
then this solution will provide the maximal efficiency.
If the method will try to get direct access for optimization via DirectAccessible
interface, then the internal data will be cloned at this moment, that can require additional memory and time,
but all further accesses to elements will work with maximal efficiency.
This solution have the following defects.
- It is not better than simple cloning, if the processing method always use the direct
access to the storage for optimization goals (for example, via
DirectAccessibleinterface), and the passed array really allows this optimization (for example, is based on Java arrays). Good processing methods can useArray.isCopyOnNextWrite()method to choose the best behavior. - It does not help to detect bugs that lead to unallowed changes of array elements. But you
can use this technique together with trusted immutable view:
"Array protected = a.
asCopyOnNextWrite().asTrustedImmutable()" Such protection is also absolutely safe, but also allows to catch unallowed attempts of correction bycheckUnallowedMutation()method.
Multithreading and synchronization
Immutable AlgART arrays are absolutely thread-safe
and can be used simultaneously in several threads.
Moreover, even if an AlgART array is mutable (for example, implements MutableArray),
but all threads, accessing it, only read data from it and do not attempt to modify the array by any way,
then this array is also thread-safe and no synchronization is required.
(The same rules are correct for usual Java arrays.)
If there are 2 or more threads accessing an AlgART array, and at least one from them modifies it
(for example, changes elements or the length), then you should synchronize access to the array.
Without external synchronization, the resulting data in the array will be unspecified.
However, if you do not use any methods from MutableArray /
Stack interfaces and their inheritors,
but only read and write elements via methods provided by UpdatableArray interface
(and its versions for concrete element types),
then the behavior while simultaneous multithreading access will be the same as for usual Java arrays.
In particular, access to one element will never affect another elements.
So, you can correctly simultaneously work with several non-overlapping sets of elements of the same array
from several threads without synchronization, if different threads work with different sets.
(Please compare: the standard java.util.BitSet class does not provide such guarantees.)
Runtime exceptions and errors
The methods of classes implementing AlgART arrays, usually, can throw exceptions declared in the Javadoc comments to methods. In addition, there are following exception, that can be thrown by methods and are not always specified in comments.
- java.io.IOError can be thrown at any moment by any method processing an AlgART array,
as well as OutOfMemoryError can be thrown my almost any Java method.
java.io.IOError is usually thrown when an array is based on some external file,
as in the
Large memory model, and there is some problem with access to this file, for example, not enough disk space.
One of the typical situations leading to this error is unexpected program termination, when some threads work with arrays created byLarge memory model. In this case, the built-in shutdown hook is started to remove all temporarily allocated disk files, and since it is started, almost any access to an AlgART array, based on a temporary file, lead to IOError with IllegalStateException as a cause.
Warning: java.io.IOError can be also thrown while processing an AlgART array, based on some external file, as in theLarge memory model, if the current thread is interrupted by Thread.interrupt() method. Also this error is thrown if the Thread.interrupt() method is called for a thread, that is currently performing multithread copying bycopymethod. Usually, such behavior is not suitable. So, you should not try to interrupt the threads, processing AlgART arrays, via Thread.interrupt() technique! Please use an alternative technique: some volatile flag, required interruption, or net.algart.contexts.InterruptionContext interface. For interruption ofArrays.copymethod, you can also use the custom implementation ofArrayContext.
TooLargeArrayExceptioncan be thrown by methods, which allocate memory in form of AlgART arrays, if the size of an allocated array is too large: seecomments to this exception. In other words, this exception is possible in the same situations as the standard OutOfMemoryError, but its probability is very low: usually an attempt to create too large AlgART array leads to another exceptions, like OutOfMemoryError or java.io.IOError with "disk full" message.
- Any RuntimeException can be thrown by methods, using
ArrayContexttechnique to allow interruption by user (for example, byArrays.copymethod), if the context, passed to this method, throws this exception in itscheckInterruption()method. It is the recommended way of interrupting long-working methods, processing AlgART arrays.
- java.io.IOError was added since JDK 1.6 only. Under Java 1.5, the similar
net.algart.arrays.IOErrorJ5 exception is thrown instead.
This error is package-private and may be excluded in future versions of AlgART libraries.
- AssertionError can be thrown at any time if some bug will be auto-detected in AlgART libraries.
Some internal checks (that can lead to this error in a case of the bug) are skipped
when Java is started without -ea flag.
The most serious bugs, if they will be auto-detected, lead to InternalError
instead of AssertionError.
We hope that these errors will not be thrown inside this package in your applications.
System properties used for customizing AlgART arrays
Behavior of AlgART arrays depends on some system properties, that allow to customize many important aspects. Below is the list of these properties.
- "net.algart.arrays.maxAvailableProcessors"
- Defines the maximal number of processor units, that are permitted to be used simultaneously
by AlgART libraries for any goals. Namely, AlgART libraries never directly use
the system value, returned by Runtime.getRuntime().availableProcessors() call,
but use a minimum from that value and the value, specified in this property.
The default value depends on JVM: on 64-bit JVM it is 256, on 32-bit it is only 8.
If it is not suitable, please specify another value (from 1 to 1024).
See
Arrays.SystemSettings.availableProcessors()for more details. - "net.algart.arrays.CPUCount"
- Defines the number of processor units that should be used for multithreading optimization.
If not exists, or zero, or negative, then
Arrays.SystemSettings.availableProcessors()will be used instead. SeeArrays.SystemSettings.cpuCountProperty()for more details. - "net.algart.arrays.globalMemoryModel"
- Defines the default
memory model, that can be used in your classes which need AlgART arrays. Thesimple memory modelis used by default. SeeArrays.SystemSettings.globalMemoryModel()for more details. - "net.algart.arrays.maxTempJavaMemory"
- Defines the maximal amount of usual Java memory, in bytes, which can be freely used
by methods, processing AlgART arrays, for internal needs and for creating results.
May contain any non-negative long value.
Default value is 33554432 (32 MB).
See
Arrays.SystemSettings.maxTempJavaMemory()for more details. - "net.algart.arrays.maxTempJavaMemoryForTiling"
- Defines the maximal amount of usual Java memory, in bytes, which can be used
by methods, performing conversion AlgART matrices into the
tiled formand inversely from the tiled form. May contain any non-negative long value. Default value is max(134217728,Arrays.SystemSettings.maxTempJavaMemory()) (134217728=128 MB). SeeArrays.SystemSettings.maxTempJavaMemoryForTiling()for more details. - "net.algart.arrays.maxMultithreadingMemory"
- Defines the maximal size of memory block, in bytes, that should be processed in several threads
for optimization on multiprocessor or multi-core computers.
May contain any positive long value.
Default value is 1048576) (1 MB).
See
Arrays.SystemSettings.maxMultithreadingMemory()for more details. - "net.algart.arrays.maxMappedMemory"
- Defines the maximal amount of system memory, in bytes, allowed for simultaneous mapping
by
DefaultDataFileModelclass. May contain any non-negative long value. Default value is 536870912 (512 MB). SeeDefaultDataFileModel.maxMappedMemory()for more details. - "net.algart.arrays.globalThreadPoolSize"
- Defines the number of threads in the global system thread pool that will be used for multithreading optimization.
If zero or negative, then the thread pools will be created on demand.
If not exists, the global thread pool with
threads (default value) will be used, where MULT is an integer value of "net.algart.arrays.globalThreadPoolsPerCPU" system property. SeeArrays.SystemSettings.availableProcessors()*MULT+1DefaultThreadPoolFactory.globalThreadPool()for more details. - "net.algart.arrays.globalThreadPoolsPerCPU"
- Helps to define the number of threads in the global system thread pool if "net.algart.arrays.globalThreadPoolSize" system property does not exist: see above.
- Defines the default
disk synchronizer, that will be used for synchronization of all disk operations, performed by this package. SeeArrays.SystemSettings.globalDiskSynchronizer()for more details. - "net.algart.arrays.profiling"
- Defines whether the algorithms, processing AlgART arrays, should write to logs some timing information.
May be "false" or "true". Default value is identical to "-ea" JVM flag:
if java was called with "-ea" flag (assertions are enabled), the default profiling mode is true,
in other case it is false.
See
Arrays.SystemSettings.profilingMode()for more details. - "net.algart.arrays.LargeMemoryModel.dataFileModel"
- Defines the default
data file model, used by theLarge memory model.DefaultDataFileModelis used by default. SeeLargeMemoryModel.getInstance()for more details. - "net.algart.arrays.DefaultDataFileModel.numberOfBanksPerCPU"
- Defines the number of banks per each existing CPU or CPU kernel,
used by the
default data file model. Default value is 3. SeeDefaultDataFileModel.recommendedNumberOfBanks()for more details. - "net.algart.arrays.DefaultDataFileModel.bankSize"
- Defines the size of banks, used by the
default data file modelfor unresizable arrays (on 64-bit Java machines). Default value is 16777216 (16 MB). SeeDefaultDataFileModel.recommendedBankSize(boolean)with true argument for more details. - "net.algart.arrays.DefaultDataFileModel.resizableBankSize"
- Defines the size of banks, used by the
default data file modelfor resizable arrays (on 64-bit Java machines). Default value is 4194304 (4 MB). SeeDefaultDataFileModel.recommendedBankSize(boolean)with false argument for more details. - "net.algart.arrays.DefaultDataFileModel.singleMappingLimit"
- Defines the limit for file size, so that less unresizable files are mapped only once
in the
default data file model(on 64-bit Java machines). Default value is 268435456 (256 MB). SeeDefaultDataFileModel.recommendedSingleMappingLimit()for more details. - "net.algart.arrays.DefaultDataFileModel.bankSize32"
- Defines the size of banks, used by the
default data file modelfor unresizable arrays (on 32-bit Java machines). Default value is 4194304 (4 MB). SeeDefaultDataFileModel.recommendedBankSize(boolean)with true argument for more details. - "net.algart.arrays.DefaultDataFileModel.resizableBankSize32"
- Defines the size of banks, used by the
default data file modelfor resizable arrays (on 32-bit Java machines). Default value is 2097152 (2 MB). SeeDefaultDataFileModel.recommendedBankSize(boolean)with false argument for more details. - "net.algart.arrays.DefaultDataFileModel.singleMappingLimit32"
- Defines the limit for file size, so that less unresizable files are mapped only once
in the
default data file model(on 32-bit Java machines). Default value is 4194304 (4 MB). SeeDefaultDataFileModel.recommendedSingleMappingLimit()for more details. - "net.algart.arrays.DefaultDataFileModel.autoResizingOnMapping"
- Defines whether AlgART mapping manager in the
default data file modelshould increase the file size via standard I/O API, or it is increased automatically as a result of new mappings. Default value is false. SeeDefaultDataFileModel.autoResizingOnMapping()for more details. - "net.algart.arrays.DefaultDataFileModel.lazyWriting"
- Defines whether the
default data file modelwill use lazy-writing mode by default. Default value is true in Java 1.7 or higher Java version and false in Java 1.5 and Java 1.6. SeeDefaultDataFileModel.defaultLazyWriting()method andDefaultDataFileModel(java.io.File, long, boolean)constructor for more details. - "net.algart.arrays.StandardIODataFileModel.numberOfBanks"
- Defines the number of banks, used by
the
alternative data file model. Default value is 32. SeeStandardIODataFileModel.recommendedNumberOfBanks()for more details. - "net.algart.arrays.StandardIODataFileModel.bankSize"
- Defines the size of banks, used by
alternative data file modelfor both resizable and unresizable arrays. Default value is 65536 (64 KB). SeeStandardIODataFileModel.recommendedBankSize(boolean)for more details. - "net.algart.arrays.StandardIODataFileModel.directBuffers"
- Defines whether the
alternative data file modelwill use direct byte buffers by default. Default value is true. SeeStandardIODataFileModel.defaultDirectBuffers()method andStandardIODataFileModel(java.io.File, long, boolean, boolean)constructor for more details. - Logger.getLogger("
net.algart.arrays.Arrays") - Logger.getLogger("
net.algart.arrays.LargeMemoryModel") - Logger.getLogger("
net.algart.arrays.Arrays") is used in following situations.- The level SEVERE:
- When
Arraysclass is initialized and the system properties net.algart.arrays.globalMemoryModel or net.algart.arrays.globalDiskSynchronizer contain names of illegal classes. See the methodsArrays.SystemSettings.globalMemoryModel()andArrays.SystemSettings.globalDiskSynchronizer().
- When
- The level CONFIG:
- While executing
Arrays.copy(ArrayContext, UpdatableArray, Array)andArrays.copy(ArrayContext, UpdatableArray, Array, int)methods, ifArrays.SystemSettings.profilingMode()returns true and the execution time is long enough. In this case, these methods log the time of copying and a short description of the source array (generated by its toString() method). Please note that these methods underlie in a lot of array processing algorithms, that create some "lazy" array view and then actualize it via copying into a new array. So, these 2 methods are often the main methods that should be profiled. - While executing
AbstractIterativeArrayProcessor.process()method, ifArrays.SystemSettings.profilingMode()returns true and the execution time is long enough. In this case, this method logs the time of iterative processing and a short description of the resulting matrix (generated by its toString() method).
- While executing
- The level SEVERE:
- Logger.getLogger("
net.algart.arrays.LargeMemoryModel") is used in following situations.- The level SEVERE:
- When
LargeMemoryModelis initialized and the system property net.algart.arrays.LargeMemoryModel.dataFileModel contains illegal name of data memory model. See the methodLargeMemoryModel.getInstance(). - In finalization code and built-in shutdown hook, if some error occurs while releasing
mappings, that usually means flushing all non-saved data to disk. - In finalization code and built-in shutdown hook, if an attempt to delete a data file
via
DataFileModel.deletemethod leads to exception other than java.io.IOError (or net.algart.arrays.IOErrorJ5 under JDK 1.5). Usually it means incorrect implementation of the custom overridden implementation of this method.
- When
- The level WARNING:
- In finalization code, if we tries to delete a temporary
data filebyDataFileModel.delete(net.algart.arrays.DataFile)method many times, but it's impossible. This situation occurs rarely and is not normal: the finalization code is performed only when no instances of AlgART arrays use this data file and all mappings are already finalized, so, the file should be normally deleted. Usually, if this situation though occurs, the deletion of this file is just scheduled to the next garbage collection. However, if there were a lot of attempts to delete this file already, this fact is logged with WARNING level and deletion of this file by finalization code is canceled. (The file will probably be though deleted by the built-in shutdown hook.)
- In finalization code, if we tries to delete a temporary
- The level CONFIG:
- In built-in shutdown hook, when we delete a temporary
data file. Both normal deletion and failure while deletion are logged with the same CONFIG level, but with different messages. (More precisely, the situations are logged when theDataFileMode.delete(DataFile)method returns true or throws an exception. If this method returns false, that means that the file was already deleted, this situation is not logged or is logged with lower levels.) The failure while deletion is not too serious problem, because the list of all non-deleted temporary files can be retrieved byDataFileModel.allTemporaryFiles()method and saved for further deletion in your own shutdown task installed byArrays.addShutdownTask(Runnable, TaskExecutionOrder). - Maybe, in some other situations.
- In built-in shutdown hook, when we delete a temporary
- The level SEVERE:
- AlgART arrays are always oriented to random access: here is no analog of the standard java.util.LinkedList class.
- AlgART arrays do not support synchronization and, therefore, may be not thread-safe.
There is an exception: all
immutable arrays, as well as most of all immutable objects, are thread-safe. All AlgART arrays are thread-compatible: there are no problems to use an external synchronization to provide simultaneous access to any kind of arrays from several threads. See above the precise specification of array behaviour in a case of multithreading access. - AlgART arrays do not support serialization (do not implement java.io.Serializable
interface). However, the
Large memory modelprovides easy storing arrays in external mapped files, that allows to implement an efficient alternative to standard serialization mechanism. - Finding, inserting and removing elements to/from the middle of AlgART arrays are not
included into the basic set of interfaces, unlike standard Java collections.
However, there are special insertion and removal methods in
Arraysclass. Adding and removing elements to/from the array end are simple: seeStack.pushElement(Object),Stack.popElement(),MutableArray.append(Array),MutableCharArray.append(String). - Author:
- Daniel Alievsky
-
ClassDescriptionImplementation of basic functions of
MutableArrayinterface.A skeletal implementation of theArrayContextinterface to minimize the effort required to implement this interface.A skeletal implementation of theArrayProcessorWithContextSwitchinginterface.Implementation of almost all basic functions ofBitArrayinterface.Implementation of almost all basic functions ofByteArrayinterface.Implementation of almost all basic functions ofCharArrayinterface.A skeletal implementation of theDataFileModelinterface to minimize the effort required to implement this interface for processing usual disk files.Implementation of almost all basic functions ofDoubleArrayinterface.Implementation of almost all basic functions ofFloatArrayinterface.Implementation of almost all basic functions ofIntArrayinterface.A skeletal implementation of theIterativeArrayProcessorinterface.Implementation of almost all basic functions ofLongArrayinterface.AbstractMatrix<T extends Array>A skeletal implementation of theMatrixinterface to minimize the effort required to implement this interface.A skeletal implementation of theMemoryModelinterface to minimize the effort required to implement this interface.Implementation of almost all basic functions ofObjectArrayinterface.Implementation of almost all basic functions ofShortArrayinterface.A skeletal implementation of theThreadPoolFactoryinterface.Implementation of almost all basic functions ofUpdatableBitArrayinterface.Implementation of almost all basic functions ofUpdatableByteArrayinterface.Implementation of almost all basic functions ofUpdatableCharArrayinterface.Implementation of almost all basic functions ofUpdatableDoubleArrayinterface.Implementation of almost all basic functions ofUpdatableFloatArrayinterface.Implementation of almost all basic functions ofUpdatableIntArrayinterface.Implementation of almost all basic functions ofUpdatableLongArrayinterface.Implementation of almost all basic functions ofUpdatableObjectArrayinterface.Implementation of almost all basic functions ofUpdatableShortArrayinterface.AlgART array of any elements, read-only access.Comparison interface, designed for comparing elements in some data array.Version ofArrayComparatorfor a case of 32-bit indexes (int instead of long).The context of processing AlgART arrays.The array processing event: an argument ofArrayContext.updateProgress(Event)method.Exchanging interface, designed for exchanging (swapping) two elements in some data array.Version ofArrayExchangerfor a case of 32-bit indexes (int instead of long).A simple pool of theunresizable AlgART arrays(usually work buffers) with the same size and type of elements, based on a list of SoftReference or WeakReference.Abstract array processor: an algorithm processing AlgART arrays or matrices.Array processor allowing to switch the current context.A set of static methods useful for working withAlgART arrays.The information about the copying, returned byArrays.compareAndCopy(ArrayContext, UpdatableArray, Array)andMatrices.compareAndCopy(ArrayContext, Matrix, Matrix)methods.Implementation ofArrays.ParallelExecutorperforming simple copying of the source array.The information about the internal algorithm, which was used by copying methods of this package:Arrays.copy(ArrayContext, UpdatableArray, Array),Arrays.copy(ArrayContext, UpdatableArray, Array, int, boolean),Arrays.compareAndCopy(ArrayContext, UpdatableArray, Array),Matrices.copy(ArrayContext, Matrix, Matrix), etc.The information about the copying, returned by copying methods of this package:Arrays.copy(ArrayContext, UpdatableArray, Array),Arrays.copy(ArrayContext, UpdatableArray, Array, int, boolean),Matrices.copy(ArrayContext, Matrix, Matrix), etc.The helper class forArrays.rangeOf(PArray, MinMaxInfo)method, containing information about the minimum and maximum in some AlgART array.The class simplifying the parallel processing a large AlgART array in several threads, where each thread process a set of ranges of the source array (Array.subArray).A set of static methods for getting some important global settings, stored in system properties and used for customizing modules processingAlgART arrays.Global synchronizer, used for all disk operations, performed by this package.Describes when to execute the task passed toArrays.addShutdownTask(Runnable, TaskExecutionOrder)method.Selecting algorithms.Sorting algorithms.AlgART array of boolean values, read-only access.Stack of boolean values.A simple class allowing to reuse Java boolean[] array many times.The memory model, based on ByteBuffer and other buffers from package.AlgART array of byte values, read-only access.Special version ofArraySelectorclass, optimized for selecting from byte[] arrays.A simple class allowing to reuse Java byte[] array many times.Stack of byte values.AlgART array of char values, read-only access.A simple class allowing to reuse Java char[] array many times.Stack of char values.Utilities useful for working with lists ofAlgART matrices, representing channels in a color image.The memory model allowing to create combined arrays: special kind of AlgART arrays, that store an array of Java objects with minimal amount of memory, namely in one or several another "parallel" arrays.A skeleton class allowing to simplify implementation ofCombinedMemoryModel.Combinerinterface.A version ofCombinedMemoryModel.AbstractByteBufferCombinerskeleton class implementingCombinedMemoryModel.CombinerInPlaceinterface.Special version ofCombinedMemoryModel.Combinerinterface allowing to optimize block access to the combined array.This interface should be implemented to allow saving objects in arrays created viacombined memory model.Special version ofCombinedMemoryModel.Combinerinterface allowing to load an element without creating new Java object.Data buffer for bit elements.Data buffer: an interface allowing to read and write blocks from / to some linear data storage, containing a sequence of elements of any Java type, with maximal performance.Access mode, describing access todata buffers.Unchecked exception thrown byDataBuffermethodsfrom(),to()andcnt(), if the values, they should be returned by these methods, are greater than Integer.MAX_VALUE.Data buffer for byte elements.Data buffer for char elements.Data buffer for double elements.Some "data file" (usually disk file) that supports file-mapping operation.An object allowing to access mapped data, returned by theDataFile.map(net.algart.arrays.DataFile.Range, boolean)method.Possible results ofDataFile.open(boolean)method.Pair of 2 long values position and length, describing the range position..position+length-1 of linear addresses in somedata file.Data file model: the factory allowing to create and remove some file-like objects ("data files").Data buffer for float elements.Data buffer for int elements.Data buffer for long elements.Data buffer for Object elements.Data buffer for short elements.Default implementation ofDataFileModelthat creates usual Java files, which are mapped via standard Java technique (FileChannel.map method).A simple implementation ofThreadPoolFactoryinterface.Unchecked exception thrown if the n-dimensional simplexMatrices.Simplexcannot be constructed because all vertices lies on the same hyperplane.Direct accessible array: an object that can be viewed as a Java array or a part of Java array.AlgART array of double values, read-only access.A simple class allowing to reuse Java double[] array many times.Stack of double values.AlgART array of float values, read-only access.A simple class allowing to reuse Java float[] array many times.Stack of float values.Rounding mode, in whichGeneralizedBitProcessingclass works: see comments to that class.Algorithm of processing bit arrays, that should be generalized for another element types viaGeneralizedBitProcessingclass.Histogram: an array of non-negative integer numbers b[v], 0≤v<M, where every element b[v] represents the number of occurrence of the value v in some source array A, consisting of integer elements in 0..M−1 range.Checked exception thrown if the format of byte[] or String serialized form of theMatrixInfois invalid.AlgART array of int values, read-only access.A simple class allowing to reuse Java int[] array many times.Stack of int values.An iterative algorithm processing some AlgART array (arrays) or matrix (matrices).A simple pool of the Java arrays (usually work buffers) with the same size and type of elements, based on a list of SoftReference.Some operations for Java array manipulation, in addition to java.util.Arrays.Implementation ofArrayExchanger, that simultaneously exchanges two pairs elements at the same positions in two arrays: some byte[] array and some int[] array.Simple implementation ofArrayComparator, comparing elements of byte[] array.Simple implementation ofArrayExchanger, exchanging elements of byte[] array.Implementation ofArrayExchanger, that simultaneously exchanges two pairs elements at the same positions in two arrays: some char[] array and some int[] array.Simple implementation ofArrayComparator, comparing elements of char[] array.Simple implementation ofArrayExchanger, exchanging elements of char[] array.Implementation ofArrayExchanger, that simultaneously exchanges two pairs elements at the same positions in two arrays: some double[] array and some int[] array.Simple implementation ofArrayComparator, comparing elements of double[] array.Simple implementation ofArrayExchanger, exchanging elements of double[] array.Implementation ofArrayExchanger, that simultaneously exchanges two pairs elements at the same positions in two arrays: some float[] array and some int[] array.Simple implementation ofArrayComparator, comparing elements of float[] array.Simple implementation ofArrayExchanger, exchanging elements of float[] array.Implementation ofArrayExchanger, that simultaneously exchanges two pairs elements at the same positions in two arrays: some int[] array and some int[] array.Simple implementation ofArrayComparator, comparing elements of int[] array.Simple implementation ofArrayExchanger, exchanging elements of int[] array.Implementation ofArrayExchanger, that simultaneously exchanges two pairs elements at the same positions in two arrays: some long[] array and some int[] array.Simple implementation ofArrayComparator, comparing elements of long[] array.Simple implementation ofArrayExchanger, exchanging elements of long[] array.Implementation ofArrayExchanger, that simultaneously exchanges two pairs elements at the same positions in two arrays: some short[] array and some int[] array.Simple implementation ofArrayComparator, comparing elements of short[] array.Simple implementation ofArrayExchanger, exchanging elements of short[] array.Some operations for Java NIO buffers manipulation in the same manner as array operations fromJArraysand java.util.Arrays classes.The memory model, storing array elements in an external file.AlgART array of long values, read-only access.A simple class allowing to reuse Java long[] array many times.Stack of long values.Utilities useful for working withAlgART matrices.Convex hyperpolyhedron: an intersection of severaln-dimensional half-spaces and somehyperparallelepiped.Hyperparallelepiped: the simplest n-dimensional region.Interpolation method for representing AlgART matrix as a mathematicalfunction.2-dimensional polygon.Region in n-dimensional space.Resizing mode forMatrices.asResizedmethod.Resizing method with averaging (while compression).Simplex: the simplest n-dimensional hyperpolyhedron withn+1 vertices.AlgART matrix: multidimensional array.Continuation mode for submatrices, created byMatrix.subMatrix(long[], long[], ContinuationMode continuationMode),Matrix.subMatr(long[], long[], ContinuationMode continuationMode)and similar methods.Full structural information about theAlgART matrix, consisting of elements of some primitive types, in a form convenient for serialization.Virtual memory model: implementations of this abstract factory is the main way of creating new AlgART arrays.AlgART one-dimensional array of any elements, full access (reading, writing, resizing).Resizable AlgART array of boolean values.Resizable AlgART array of byte values.Resizable AlgART array of char values.Resizable AlgART array of double values.Resizable AlgART array of float values.Resizable AlgART array of int values.Resizable AlgART array of long values.Resizable AlgART array of some objects (non-primitive values) with the specified generic type E, read-write and resize access.Special version ofMutableObjectArrayallowing to load an element without creating new Java object.Resizable AlgART array of primitive elements (boolean, char, byte, short, int, long, float or double).Resizable AlgART array of any fixed-point numeric, character or bit primitive elements (byte, short, int, long, char or boolean).Resizable AlgART array of any floating-point primitive elements (float or double).Resizable AlgART array of any fixed-point numeric primitive elements (byte, short, int or long).Resizable AlgART array of any numeric primitive elements (byte, short, int, long, float or double).Resizable AlgART array of short values.Unchecked exception thrown byDirectAccessible.javaArray()method, if the object cannot be viewed as a Java array.Unchecked exception thrown byMatrix.ContinuationMode.continuationConstant()method, if the continuation mode is not aconstant continuation.ObjectArray<E>AlgART array of some objects (non-primitive values) with the specified generic type E, read-only access.Special version ofObjectArrayallowing to load an element without creating new Java object.ObjectStack<E>Stack of some objects (non-primitive values).Operations with bit arrays packed into long[] Java arrays.Operations with bit arrays packed into byte[] Java arrays.Operations with bit arrays packed into java.nio.LongBuffer.AlgART array of primitive elements (boolean, char, byte, short, int, long, float or double), read-only access.AlgART array of any fixed-point primitive numeric, character or bit elements (byte, short, int, long, char or boolean), read-only access.AlgART array of any floating-point primitive elements (float or double), read-only access.AlgART array of any fixed-point primitive numeric elements (byte, short, int or long), read-only access.AlgART array of any primitive numeric elements (byte, short, int, long, float or double), read-only access.AlgART array of short values, read-only access.A simple class allowing to reuse Java short[] array many times.Stack of short values.The degenerate memory model that does not allow to create any AlgART arrays.The simplest memory model, based on usual Java arrays.Unchecked exception thrown by some methods, processing several AlgART arrays or matrices, when the passed arrays / matrices have different lengths / dimensions.Resizable stack of any elements.Alternative implementation ofDataFileModel, that creates usual Java files, but emulates mapping via standard read/write operations.Summing histogram: an extension ofHistogramclass, allowing quick calculation of sums of all elements of the sorted source array A[k] with indexes, lying in some ranger1≤k≤r2 , or with values, lying in some rangev1≤A[k]≤v2 .The helper class for static methods ofSummingHistogramclass, calculating the integrals ofv(r) function between two given values:minValue≤v≤maxValue .The factory allowing to get a thread pool (ExecutorService) for processing some AlgART array.Unchecked exception thrown if the current or desired array length is extremely large.Unchecked error thrown if the elements oftrusted immutableAlgART arrays have been changed.Unchecked exception thrown by methods, creating new AlgART arrays (asMemoryModel.newEmptyArray(Class)), if the specified element type is not supported by thememory model.AlgART one-dimensional array of any elements, read/write access, no resizing.AlgART array of boolean values, read/write access, no resizing.AlgART array of byte values, read/write access, no resizing.AlgART array of char values, read/write access, no resizing.AlgART array of double values, read/write access, no resizing.AlgART array of float values, read/write access, no resizing.AlgART array of int values, read/write access, no resizing.AlgART array of long values, read/write access, no resizing.AlgART array of some objects (non-primitive values) with the specified generic type E, read/write access, no resizing.Special version ofUpdatableObjectArrayallowing to load an element without creating new Java object.AlgART array of primitive elements (boolean, char, byte, short, int, long, float or double), read/write access, no resizing.AlgART array of any fixed-point primitive numeric, character or bit elements (byte, short, int, long, char or boolean), read/write access, no resizing.AlgART array of any floating-point primitive elements (float or double), read/write access, no resizing.AlgART array of any fixed-point primitive numeric elements (byte, short, int or long), read/write access, no resizing.AlgART array of any primitive numeric elements (byte, short, int, long, float or double), read-only access.AlgART array of short values, read/write access, no resizing.
All these properties, excepting "net.algart.arrays.CPUCount", are loaded while initialization of the corresponding classes. So, any changes of them will be applied only at the next start of the Java application.
Note: all properties containing integer values, excepting
"net.algart.arrays.CPUCount",
can contain a suffix K, M, G, T
(or k, m, g, t),
that means that the integer value, specified before this suffix, is multiplied by
1024 (210, "Kilo"), 1048576 (220, "Mega"), 1073741824 (230, "Giga")
or 1099511627776 (240, "Tera") correspondingly.
For example, you can specify -Dnet.algart.arrays.DefaultDataFileModel.bankSize=64m
to set the bank size to 64 MB.
Note: the properties
"net.algart.arrays.maxTempJavaMemory",
"net.algart.arrays.maxTempJavaMemoryForTiling",
"net.algart.arrays.maxMultithreadingMemory",
"net.algart.arrays.maxMappedMemory" are limited by the value 256~7.2*1016:
if one of these properties exceeds this value, this limit is used instead.
It guarantees that using the values of these properties will never lead to integer overflows.
The most important properties, that usually should be customized, are
"net.algart.arrays.maxAvailableProcessors" (in applications that prefer not to use all available processors),
"net.algart.arrays.maxTempJavaMemory" and
"net.algart.arrays.maxMappedMemory".
Other properties can be not customized in most cases.
There are some other system properties, starting with "net.algart.arrays." substring, used for internal goals. They are undocumented and should not be used in your applications.
Built-in logging
Some classes implementing AlgART arrays logs some situations via standard java.util.logging tools. Now 3 loggers are used:
We don't specify what situations are logged with levels FINE or lower. Below is the information about logging with higher levels.
Tasks that are better solved by standard Java collections
The following tasks are not well solved in this architecture: please use standard Java libraries in these cases.