Class CombinedMemoryModel<E>
- All Implemented Interfaces:
MemoryModel
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 set of these arrays is named "the internal storage" of the combined array.
There is an essential problem with storing large arrays of small objects in Java language. For example, let a point is described by 2 integer values: x and y, and we need to store 10 million points. In C++ or Pascal language, we can create an array of 10 000 000 structures (struct or record keyword), and this array occupies ~80 MB memory (4 bytes per every integer).
Unfortunately, the only simple way to store 10 million points in Java is usage of Java array (or collection) containing instance of Java-class, such as
class Point { int x; int y; }
For example,
Point[] points = new Point[10000000]; for (int k = 0; k < points.length; k++) points[k] = new Point();
Such an array occupies more than 200 MB and is created very slowly (several seconds on CPU P-IV 2 GHz, under Java 1.5). The reason is creating separate object for every point and saving a pointer to it in Java array. Only array of primitive types work efficiently in Java.
The arrays created by this memory model ("combined" arrays) allow a solution of this problem.
This memory model stores an array of any Java objects in one or several "parallel" another AlgART arrays -
typically, wrappers for Java-arrays of primitive types
(created by SimpleMemoryModel
) or for ByteBuffer objects
(created by LargeMemoryModel
). This array is created quickly,
does not make a difficult problem for future garbage collection
and occupies only necessary amount of memory.
However, in many situations, combined arrays work slower, than simple array of references as listed above. In particular, an access to stored elements of combined arrays are usually slower in several times, than usage direct references array or standard ArrayList. Usually, you need combined arrays if you should save occupied memory or quickly create large array.
The only thing that you should provide to use this class is implementing
CombinedMemoryModel.Combiner
interface or its inheritors
CombinedMemoryModel.CombinerInPlace
,
CombinedMemoryModel.BufferedCombiner
,
which "tell" how to store (or load) one object in (from) a set of AlgART arrays.
The CombinedMemoryModel.CombinerInPlace
interface allows to
quite eliminate usage of Java heap while working with combined array;
the CombinedMemoryModel.BufferedCombiner
interface allows to optimize
block access to the combined array.
Below are the main features of arrays created via this memory model.
- Only element types inherited from Object are supported (not primitive):
so, the created arrays always implement the
ObjectArray
/UpdatableObjectArray
/MutableObjectArray
interface. - Arrays, created by
newEmptyArray(Class elementType)
,newEmptyArray(Class elementType, long initialCapacity)
,newArray(Class elementType, long initialLength)
MutableObjectArray
interface. Arrays, created byare unresizable. Arrays, created byare immutable. - Arrays, created by this memory model, never implement
DirectAccessible
interface. - Arrays, created by this memory model, never have new or new-read-only-view
status:
Array.isNew()
andArray.isNewReadOnlyView()
method always return false, because they are views of some other (underlying
) arrays. - The
Array.loadResources(ArrayContext)
,Array.flushResources(ArrayContext)
,Array.flushResources(ArrayContext, boolean)
andArray.freeResources(ArrayContext, boolean)
methods just call the same methods of the storage arrays. - If the combiner, passed while creating the memory model by
getInstance(Combiner)
, implements extendedCombinedMemoryModel.CombinerInPlace
interface, then the arrays, created by this memory model, implementObjectInPlaceArray
/UpdatableObjectInPlaceArray
/MutableObjectInPlaceArray
interface, that allow to avoid allocating new Java objects while accessing elements. UpdatableArray.copy(Array)
,UpdatableArray.swap(UpdatableArray)
,Array.updatableClone(MemoryModel)
,Array.mutableClone(MemoryModel)
methods copies the content of elements (not references to elements!) by calling the corresponding methods of the storage arrays (and theirsubarrays
).- The
Array.equals(Object)
method, in a case when another array is combined and uses the same combiner, is based on calls of the corresponding methods of the storage array (and theirsubarrays
); so, result ofArray.equals(Object)
(for the same combiner in both arrays) does not depend on implementation of equals method in the class of elements (Array.elementType()
) - However,
Array.hashCode()
method, according to the comments for it, is still based on implementation of hashCode method in the class of elements. So, you should store in combined arrays only such objects, that have hashCode method based on the their content (stored inside a combined array viaCombinedMemoryModel.Combiner
). In other case, standard contract for hashCode and equals methods can be violated, that can lead to problems, for example, while using arrays as keys in hash maps.
This class is immutable and thread-safe: there are no ways to modify settings of the created instance.
- Author:
- Daniel Alievsky
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
A skeleton class allowing to simplify implementation ofCombinedMemoryModel.Combiner
interface.static class
A version ofCombinedMemoryModel.AbstractByteBufferCombiner
skeleton class implementingCombinedMemoryModel.CombinerInPlace
interface.static interface
Special version ofCombinedMemoryModel.Combiner
interface allowing to optimize block access to the combined array.static interface
This interface should be implemented to allow saving objects in arrays created viacombined memory model
.static interface
Special version ofCombinedMemoryModel.Combiner
interface allowing to load an element without creating new Java object. -
Method Summary
Modifier and TypeMethodDescriptionboolean
Returns true if this memory model can create arrays with all element types.boolean
Returns true if this memory model can create arrays with all primitive element types: boolean, char, byte, short, int, long, float, double.final ObjectArray<E>
asCombinedArray
(Class<E> elementType, Array[] storage) Returns an immutable combined array backed by the storage, which consists of immutable views of the passed argument (storage[0].asImmutable()
, (storage[1].asImmutable()
, ..., (storage[storage.length-1].asImmutable()
, with the current combiner (specified while creating this memory model).final UpdatableObjectArray<E>
asUpdatableCombinedArray
(Class<E> elementType, UpdatableArray[] storage) Returns an unresizable combined array backed by the storage, which consists of shallow unresizable copies of the passed argument (storage[0].asUnresizable()
.shallowClone()
, (storage[1].asUnresizable()
.shallowClone()
, ..., (storage[storage.length-1].asUnresizable()
.shallowClone()
, with the current combiner (specified while creating this memory model).static <E> CombinedMemoryModel<E>
getInstance
(CombinedMemoryModel.Combiner<E> combiner) Creates new memory model with corresponding combiner.static Array[]
getStorage
(Array combinedArray) Returns Java array of shallow copies (produced byArray.shallowClone()
of arrays used as internal storage, where the elements of the combined array are stored.static MutableArray[]
getStorage
(MutableArray combinedArray) Fully equivalent togetStorage(Array)
method.static UpdatableArray[]
getStorage
(UpdatableArray combinedArray) Fully equivalent togetStorage(Array)
method.static String[]
getStorageToStrings
(Array combinedArray) Returns array of string representations (results of toString() method} of arrays used as internal storage, where the elements of the combined array are stored.static boolean
isCombinedArray
(Array array) Returns true if the passed instance is a combined array created by some instance of combined memory model.boolean
isCreatedBy
(Array array) Returns true if the passed array was created by this (or identical) memory model.boolean
isElementTypeSupported
(Class<?> elementType) Returns true if this element type is an inheritor of Object class.long
maxSupportedLength
(Class<?> elementType) This implementation always returns Long.MAX_VALUE for supported (non-primitive) element types.Allocates a zero-filled resizable array with the specified element type and initial length.newEmptyArray
(Class<?> elementType) This implementation returnsnewArray
(elementType, 10).newEmptyArray
(Class<?> elementType, long initialCapacity) Constructs an empty array with the specified element type and initial capacity.newUnresizableArray
(Class<?> elementType, long length) Allocates a zero-filled unresizable array with the specified element type and length.toString()
Returns a brief string description of this memory model.Methods inherited from class net.algart.arrays.AbstractMemoryModel
newArray, newBitArray, newBitMatrix, newByteArray, newByteMatrix, newCharArray, newCharMatrix, newDoubleArray, newDoubleMatrix, newEmptyBitArray, newEmptyBitArray, newEmptyByteArray, newEmptyByteArray, newEmptyCharArray, newEmptyCharArray, newEmptyDoubleArray, newEmptyDoubleArray, newEmptyFloatArray, newEmptyFloatArray, newEmptyIntArray, newEmptyIntArray, newEmptyLongArray, newEmptyLongArray, newEmptyObjectArray, newEmptyObjectArray, newEmptyShortArray, newEmptyShortArray, newFloatArray, newFloatMatrix, newIntArray, newIntMatrix, newLazyCopy, newLazyCopy, newLongArray, newLongMatrix, newMatrix, newMatrix, newMatrix, newObjectArray, newObjectMatrix, newShortArray, newShortMatrix, newStructuredMatrix, newUnresizableArray, newUnresizableBitArray, newUnresizableByteArray, newUnresizableCharArray, newUnresizableDoubleArray, newUnresizableFloatArray, newUnresizableIntArray, newUnresizableLazyCopy, newUnresizableLongArray, newUnresizableObjectArray, newUnresizableShortArray, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf
-
Method Details
-
getInstance
Creates new memory model with corresponding combiner. If combiner argument implementsCombinedMemoryModel.CombinerInPlace
(not onlyCombinedMemoryModel.Combiner
), then the arrays created via this memory model will implementObjectInPlaceArray
interface (not onlyObjectArray
).Note: if you need to create several instances of
CombinedMemoryModel
with identical combiner, please use the same reference toCombinedMemoryModel.Combiner
object for all memory model instances. If two combined arrays were created with the same combiner, then some operations with these arrays (namely,UpdatableArray.copy(Array)
andUpdatableArray.swap(UpdatableArray)
will work faster.- Parameters:
combiner
- will be used for creation of combined arrays by this memory model.- Returns:
- created memory model.
- Throws:
NullPointerException
- if combiner is null.
-
newEmptyArray
This implementation returnsnewArray
(elementType, 10).- Specified by:
newEmptyArray
in interfaceMemoryModel
- Specified by:
newEmptyArray
in classAbstractMemoryModel
- Parameters:
elementType
- the type of array elements.- Returns:
- created array.
- Throws:
NullPointerException
- if elementType is null.IllegalArgumentException
- if elementType is not supported of void.class.UnsupportedElementTypeException
- if elementType is not supported by this memory model.- See Also:
-
newEmptyArray
Constructs an empty array with the specified element type and initial capacity. The element type can be any non-primitive class (inheritor of Object class). The created array will always implement theMutableObjectArray
interface (orObjectInPlaceArray
, if the combiner, passed while creating the memory model, implementsCombinedMemoryModel.CombinerInPlace
).- Specified by:
newEmptyArray
in interfaceMemoryModel
- Specified by:
newEmptyArray
in classAbstractMemoryModel
- Parameters:
elementType
- the type of array elements (non-primitive).initialCapacity
- the initial capacity of the array.- Returns:
- created array.
- Throws:
NullPointerException
- if elementType is null.IllegalArgumentException
- if elementType is void.class or if the specified initial length is negative.UnsupportedElementTypeException
- if elementType is a primitive type.TooLargeArrayException
- if the specified initial length is too large.- See Also:
-
newArray
Description copied from interface:MemoryModel
Allocates a zero-filled resizable array with the specified element type and initial length. The capacity of new array will be equal to its length.This method is equivalent to the following call:
newEmptyArray(elementType, initialLength)
.length(initialLength)
.trim()
.- Specified by:
newArray
in interfaceMemoryModel
- Specified by:
newArray
in classAbstractMemoryModel
- Parameters:
elementType
- the type of array elements.initialLength
- the initial length and capacity of the array.- Returns:
- created AlgART array.
- See Also:
-
newUnresizableArray
Description copied from interface:MemoryModel
Allocates a zero-filled unresizable array with the specified element type and length. The capacity of new array will be equal to its length.The analogous result may be obtained the following call:
newArray(elementType, length)
.asUnresizable()
. However, we don't recommend to use such code. If you are sure that you will not need to change the array length, please always use this method (ornewUnresizableBitArray
,newUnresizableBteArray
, etc.). In some memory models, creating resizable array with the given length may require much more resources that creating unresizable one. For example, in thelarge memory model
every resizable array is stored in the file consisting of integer number of blocks perDataFileModel.recommendedBankSize(true)
bytes.- Specified by:
newUnresizableArray
in interfaceMemoryModel
- Specified by:
newUnresizableArray
in classAbstractMemoryModel
- Parameters:
elementType
- the type of array elements.length
- the length and capacity of the array.- Returns:
- created unresizable AlgART array.
- See Also:
-
isElementTypeSupported
Returns true if this element type is an inheritor of Object class.- Specified by:
isElementTypeSupported
in interfaceMemoryModel
- Specified by:
isElementTypeSupported
in classAbstractMemoryModel
- Parameters:
elementType
- the type of array elements.- Returns:
- true if this memory model supports this element type.
-
areAllPrimitiveElementTypesSupported
public boolean areAllPrimitiveElementTypesSupported()Description copied from interface:MemoryModel
Returns true if this memory model can create arrays with all primitive element types: boolean, char, byte, short, int, long, float, double.- Specified by:
areAllPrimitiveElementTypesSupported
in interfaceMemoryModel
- Specified by:
areAllPrimitiveElementTypesSupported
in classAbstractMemoryModel
- Returns:
- true if this memory model supports all primitive element types.
- See Also:
-
areAllElementTypesSupported
public boolean areAllElementTypesSupported()Description copied from interface:MemoryModel
Returns true if this memory model can create arrays with all element types. This package offers only one such memory model:SimpleMemoryModel
.- Specified by:
areAllElementTypesSupported
in interfaceMemoryModel
- Specified by:
areAllElementTypesSupported
in classAbstractMemoryModel
- Returns:
- true if this memory model supports element types.
- See Also:
-
maxSupportedLength
This implementation always returns Long.MAX_VALUE for supported (non-primitive) element types. Actual maximal possible array length depends on memory model used by the combiner and on the number of sequential elements of storage arrays used for storing one element of the combined array.- Specified by:
maxSupportedLength
in interfaceMemoryModel
- Specified by:
maxSupportedLength
in classAbstractMemoryModel
- Parameters:
elementType
- the type of array elements.- Returns:
- maximal possible length of arrays supported by this memory model.
- Throws:
NullPointerException
- if elementType is null.
-
isCreatedBy
Description copied from interface:MemoryModel
Returns true if the passed array was created by this (or identical) memory model.For
SimpleMemoryModel
andBufferMemoryModel
, "identical" means the same memory model.For
LargeMemoryModel
, "identical" means that the memory model is also large and was created with the same instance of thedata file factory
.For
CombinedMemoryModel
, "identical" means that the memory model is also combined and was created with the same instance of thecombiner
.Returns false if the passed argument is null.
- Specified by:
isCreatedBy
in interfaceMemoryModel
- Specified by:
isCreatedBy
in classAbstractMemoryModel
- Parameters:
array
- the AlgART array (may be null, than the method returns false).- Returns:
- true if the passed array was created by this memory model.
-
isCombinedArray
Returns true if the passed instance is a combined array created by some instance of combined memory model. Returns false if the passed array is null or an AlgART array created by another memory model.- Parameters:
array
- the checked array.- Returns:
- true if this array is a combined array created by a combined memory model.
-
asCombinedArray
Returns an immutable combined array backed by the storage, which consists of immutable views of the passed argument (storage[0].asImmutable()
, (storage[1].asImmutable()
, ..., (storage[storage.length-1].asImmutable()
, with the current combiner (specified while creating this memory model).If modifications of the passed arrays lead to reallocation of the internal storage, then the returned array ceases to be a view of passed arrays. The only possible reasons for reallocation are the following: calling
MutableArray.length(long)
,MutableArray.ensureCapacity(long)
orMutableArray.trim()
methods for this array, or any modification of this or returned array in a case when this array iscopy-on-next-write
.- Parameters:
elementType
- the type of created array elementsstorage
- the internal storage where the combined array elements will be stored- Returns:
- combined array backed by the specified storage
-
asUpdatableCombinedArray
public final UpdatableObjectArray<E> asUpdatableCombinedArray(Class<E> elementType, UpdatableArray[] storage) Returns an unresizable combined array backed by the storage, which consists of shallow unresizable copies of the passed argument (storage[0].asUnresizable()
.shallowClone()
, (storage[1].asUnresizable()
.shallowClone()
, ..., (storage[storage.length-1].asUnresizable()
.shallowClone()
, with the current combiner (specified while creating this memory model). Changes of elements of the passed arrays will be reflected in the returned combined array, and vice-versa.Using shallow copies means that any further changes of lengths or capacities of the passed storage arrays will not affect to the length or capacity of the returned combined array. However, changes of elements of the passed arrays will be reflected in the returned combined array, and vice-versa. Also it means that if modifications of the passed arrays characteristics lead to reallocation of their internal storage, then the returned array ceases to be a view of passed arrays. The only possible reasons for reallocation are the following: calling
MutableArray.length(long)
,MutableArray.ensureCapacity(long)
orMutableArray.trim()
methods for storage[] elements, or any modification of storage[] elements in a case when they arecopy-on-next-write
.- Parameters:
elementType
- the type of created array elementsstorage
- the internal storage where the combined array elements will be stored- Returns:
- combined array backed by the specified storage
-
toString
Returns a brief string description of this memory model.The result of this method may depend on implementation.
-
getStorage
Returns Java array of shallow copies (produced byArray.shallowClone()
of arrays used as internal storage, where the elements of the combined array are stored. If this combined array implementsUpdatableArray
interface, than the returned array will be an instance ofUpdatableArray
[]. If this combined array implementsMutableArray
interface, than the returned array will be an instance ofMutableArray
[].Using shallow copies means that you are free to change the lengths or capacities of the returned arrays: it will not affect to the length or capacity of the passed combined array. However, changes of elements of the returned arrays will be reflected in the combined array, and vice-versa. If modifications of the passed combined array characteristics lead to reallocation of the internal storage, then the returned arrays ceases to be a view of the passed array. The only possible reasons for reallocation are the following: calling
MutableArray.length(long)
,MutableArray.ensureCapacity(long)
orMutableArray.trim()
methods for this array, or any modification of this or returned array in a case when this array iscopy-on-next-write
.- Parameters:
combinedArray
- the combined array.- Returns:
- array of shallow copies of arrays used as internal storage.
- Throws:
NullPointerException
- if combinedArray is null.IllegalArgumentException
- if combinedArray is not a combined array (created by this memory model).- See Also:
-
getStorage
Fully equivalent togetStorage(Array)
method.- Parameters:
combinedArray
- the combined array.- Returns:
- array of shallow copies of arrays used as internal storage.
- Throws:
NullPointerException
- if combinedArray is null.IllegalArgumentException
- if combinedArray is not a combined array (created by this memory model).- See Also:
-
getStorage
Fully equivalent togetStorage(Array)
method.- Parameters:
combinedArray
- the combined array.- Returns:
- array of shallow copies of arrays used as internal storage.
- Throws:
NullPointerException
- if combinedArray is null.IllegalArgumentException
- if combinedArray is not a combined array (created by this memory model).- See Also:
-
getStorageToStrings
Returns array of string representations (results of toString() method} of arrays used as internal storage, where the elements of the combined array are stored.- Parameters:
combinedArray
- the combined array.- Returns:
- array of string representations of arrays used as internal storage.
- Throws:
NullPointerException
- if combinedArray is null.IllegalArgumentException
- if combinedArray is not a combined array (created by this memory model).
-