All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.algart.arrays.AbstractMemoryModel Maven / Gradle / Ivy

Go to download

Open-source Java libraries, supporting generalized smart arrays and matrices with elements of any types, including a wide set of 2D-, 3D- and multidimensional image processing and other algorithms, working with arrays and matrices.

There is a newer version: 1.4.23
Show newest version
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package net.algart.arrays;

import java.util.Objects;

/**
 * 

A skeletal implementation of the {@link MemoryModel} interface to minimize * the effort required to implement this interface.

* *

This class implements all concrete newEmptyXxxArray, * newXxxArray and newUnresizableXxxArray * methods, and also all valueOf methods * via trivial calls of corresponding newEmptyArray and newArray methods. * This class implements all concrete newXxxMatrix * via trivial calls of newMatrix method. * It also offers a simple implementation of some other methods: see comments to them.

* * @author Daniel Alievsky */ public abstract class AbstractMemoryModel implements MemoryModel { public abstract MutableArray newEmptyArray(Class elementType); public abstract MutableArray newEmptyArray(Class elementType, long initialCapacity); public abstract MutableArray newArray(Class elementType, long initialLength); public abstract UpdatableArray newUnresizableArray(Class elementType, long length); public MutableArray newArray(Array array) { Objects.requireNonNull(array, "Null array argument"); return newArray(array.elementType(), array.length()); } public UpdatableArray newUnresizableArray(Array array) { Objects.requireNonNull(array, "Null array argument"); return newUnresizableArray(array.elementType(), array.length()); } /*Repeat() boolean(.class) ==> char$1,,byte$1,,short$1,,int$1,,long$1,,float$1,,double$1;; Bit ==> Char,,Byte,,Short,,Int,,Long,,Float,,Double */ public MutableBitArray newEmptyBitArray() { return (MutableBitArray) newEmptyArray(boolean.class); } public MutableBitArray newEmptyBitArray(long initialCapacity) { return (MutableBitArray) newEmptyArray(boolean.class, initialCapacity); } public MutableBitArray newBitArray(long initialLength) { return (MutableBitArray) newArray(boolean.class, initialLength); } public UpdatableBitArray newUnresizableBitArray(long initialLength) { return (UpdatableBitArray) newUnresizableArray(boolean.class, initialLength); } /*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */ public MutableCharArray newEmptyCharArray() { return (MutableCharArray) newEmptyArray(char.class); } public MutableCharArray newEmptyCharArray(long initialCapacity) { return (MutableCharArray) newEmptyArray(char.class, initialCapacity); } public MutableCharArray newCharArray(long initialLength) { return (MutableCharArray) newArray(char.class, initialLength); } public UpdatableCharArray newUnresizableCharArray(long initialLength) { return (UpdatableCharArray) newUnresizableArray(char.class, initialLength); } public MutableByteArray newEmptyByteArray() { return (MutableByteArray) newEmptyArray(byte.class); } public MutableByteArray newEmptyByteArray(long initialCapacity) { return (MutableByteArray) newEmptyArray(byte.class, initialCapacity); } public MutableByteArray newByteArray(long initialLength) { return (MutableByteArray) newArray(byte.class, initialLength); } public UpdatableByteArray newUnresizableByteArray(long initialLength) { return (UpdatableByteArray) newUnresizableArray(byte.class, initialLength); } public MutableShortArray newEmptyShortArray() { return (MutableShortArray) newEmptyArray(short.class); } public MutableShortArray newEmptyShortArray(long initialCapacity) { return (MutableShortArray) newEmptyArray(short.class, initialCapacity); } public MutableShortArray newShortArray(long initialLength) { return (MutableShortArray) newArray(short.class, initialLength); } public UpdatableShortArray newUnresizableShortArray(long initialLength) { return (UpdatableShortArray) newUnresizableArray(short.class, initialLength); } public MutableIntArray newEmptyIntArray() { return (MutableIntArray) newEmptyArray(int.class); } public MutableIntArray newEmptyIntArray(long initialCapacity) { return (MutableIntArray) newEmptyArray(int.class, initialCapacity); } public MutableIntArray newIntArray(long initialLength) { return (MutableIntArray) newArray(int.class, initialLength); } public UpdatableIntArray newUnresizableIntArray(long initialLength) { return (UpdatableIntArray) newUnresizableArray(int.class, initialLength); } public MutableLongArray newEmptyLongArray() { return (MutableLongArray) newEmptyArray(long.class); } public MutableLongArray newEmptyLongArray(long initialCapacity) { return (MutableLongArray) newEmptyArray(long.class, initialCapacity); } public MutableLongArray newLongArray(long initialLength) { return (MutableLongArray) newArray(long.class, initialLength); } public UpdatableLongArray newUnresizableLongArray(long initialLength) { return (UpdatableLongArray) newUnresizableArray(long.class, initialLength); } public MutableFloatArray newEmptyFloatArray() { return (MutableFloatArray) newEmptyArray(float.class); } public MutableFloatArray newEmptyFloatArray(long initialCapacity) { return (MutableFloatArray) newEmptyArray(float.class, initialCapacity); } public MutableFloatArray newFloatArray(long initialLength) { return (MutableFloatArray) newArray(float.class, initialLength); } public UpdatableFloatArray newUnresizableFloatArray(long initialLength) { return (UpdatableFloatArray) newUnresizableArray(float.class, initialLength); } public MutableDoubleArray newEmptyDoubleArray() { return (MutableDoubleArray) newEmptyArray(double.class); } public MutableDoubleArray newEmptyDoubleArray(long initialCapacity) { return (MutableDoubleArray) newEmptyArray(double.class, initialCapacity); } public MutableDoubleArray newDoubleArray(long initialLength) { return (MutableDoubleArray) newArray(double.class, initialLength); } public UpdatableDoubleArray newUnresizableDoubleArray(long initialLength) { return (UpdatableDoubleArray) newUnresizableArray(double.class, initialLength); } /*Repeat.AutoGeneratedEnd*/ public MutableObjectArray newEmptyObjectArray(Class elementType) { return InternalUtils.cast(newEmptyArray(elementType)); } public MutableObjectArray newEmptyObjectArray(Class elementType, long initialCapacity) { return InternalUtils.cast(newEmptyArray(elementType, initialCapacity)); } public MutableObjectArray newObjectArray(Class elementType, long initialLength) { return InternalUtils.cast(newArray(elementType, initialLength)); } public UpdatableObjectArray newUnresizableObjectArray(Class elementType, long initialLength) { return InternalUtils.cast(newUnresizableArray(elementType, initialLength)); } /** * This implementation returns usual actual copy of the array. * More precisely, it is equivalent to the following operator: * *
     * thisMemoryModel.{@link #newArray(Class, long)
     * newArray}(array.{@link Array#elementType() elementType()}, array.{@link Array#length()
     * length()}).{@link UpdatableArray#copy(Array) copy}(array);
     * 
* * @param array the source array. * @return the usual identical copy of the source array. * @throws NullPointerException if the argument is {@code null}. * @throws UnsupportedElementTypeException if the element type of the passed array * is not supported by this memory model. * @throws TooLargeArrayException if the length of the passed array is too large for this memory model. */ public MutableArray newLazyCopy(Array array) { // OBSOLETE INCORRECT IMPLEMENTATION: attempt to copy another data into such "lazy copy" via standard // tools like Arrays.copy (based on subarrays) failed due to copy-on-write nature of the array! // if (isCreatedBy(array) && array instanceof MutableArray) { // return ((MutableArray)array).asCopyOnNextWrite(); // } else { // return newArray(array.elementType(), array.length()).copy(array); // } return newArray(array.elementType(), array.length()).copy(array); } /** * This implementation returns usual actual copy of the array. * More precisely, it is equivalent to the following operator: * *
     * thisMemoryModel.{@link #newUnresizableArray(Class, long)
     * newUnresizableArray}(array.{@link Array#elementType() elementType()}, array.{@link Array#length()
     * length()}).{@link UpdatableArray#copy(Array) copy}(array);
     * 
* * @param array the source array. * @return the usual identical unresizable copy of the source array. * @throws NullPointerException if the argument is {@code null}. * @throws UnsupportedElementTypeException if the element type of the passed array * is not supported by this memory model. * @throws TooLargeArrayException if the length of the passed array is too large for this memory model. */ public UpdatableArray newUnresizableLazyCopy(Array array) { // OBSOLETE INCORRECT IMPLEMENTATION: attempt to copy another data into such "lazy copy" via standard // tools like Arrays.copy (based on subarrays) failed due to copy-on-write nature of the array! // if (isCreatedBy(array) && array instanceof UpdatableArray) { // return ((UpdatableArray)array).asCopyOnNextWrite(); // } else { // return newUnresizableArray(array.elementType(), array.length()).copy(array); // } return newUnresizableArray(array.elementType(), array.length()).copy(array); } /** * This method is fully implemented in this class. * * @param arraySupertype the desired type of the underlying array (the generic argument of the matrix type). * @param elementType the type of matrix elements. * @param dim the dimensions of the matrix. * @return created matrix. * @throws NullPointerException if elementType or dim is {@code null}. * @throws IllegalArgumentException if elementType is void.class, * or if arraySupertype is {@link MutableArray} or its subtype, * or if the specified dimensions are incorrect: * dim.length == 0, * dim[n] < 0 for some n, * or the product of all specified dimensions * is greater than Long.MAX_VALUE. * @throws ClassCastException if arraySupertype and * elementType do not match. * @throws UnsupportedElementTypeException if elementType is not supported by this memory model. * @throws TooLargeArrayException if the product of all specified dimensions is too large * for this memory model. */ public Matrix newMatrix(Class arraySupertype, Class elementType, long... dim) { Objects.requireNonNull(arraySupertype, "Null arraySupertype argument"); Arrays.checkElementTypeForNullAndVoid(elementType); if (MutableArray.class.isAssignableFrom(arraySupertype)) { throw new IllegalArgumentException("Illegal arraySupertype = " + arraySupertype + ": it is MutableArray or its subtype, but a matrix cannot be based on a resizable array"); } Class type = Arrays.type(UpdatableArray.class, elementType); if (!arraySupertype.isAssignableFrom(type)) { throw new ClassCastException("The passed array supertype " + arraySupertype.getName() + " is not a supertype for " + type.getName() + " and, so, cannot contain required " + elementType.getCanonicalName() + " elements"); } long len = AbstractMatrix.checkDimensions(dim); // this check before cloning dim array is not absolutely safe, // but it will be repeated inside MatrixImpl constructor T array = arraySupertype.cast(newUnresizableArray(elementType, len)); return new MatrixImpl(array, dim); } /** * This method is fully implemented in this class. * * @param maxSizeAllocatedInJavaMemory the maximal amount of required memory, for which this method * just redirects to the same method of * {@link SimpleMemoryModel#getInstance()} * @param arraySupertype the desired type of the underlying array (the generic argument * of the matrix type). * @param elementType the type of matrix elements. * @param dim the dimensions of the matrix. * @return created matrix. * @throws NullPointerException if elementType or dim is {@code null}. * @throws IllegalArgumentException if elementType is void.class, * or if arraySupertype is {@link MutableArray} or its subtype, * or if the specified dimensions are incorrect: dim.length == 0, * dim[n] < 0 for some n, * or the product of all specified dimensions * is greater than Long.MAX_VALUE. * @throws ClassCastException if arraySupertype and elementType do not match. * @throws UnsupportedElementTypeException if elementType is not supported by this memory model * or, for a matrix smaller than maxSizeAllocatedInJavaMemory, * by {@link SimpleMemoryModel}. * @throws TooLargeArrayException if the product of all specified dimensions is too large * for this memory model or, * for a matrix smaller than maxSizeAllocatedInJavaMemory, * by {@link SimpleMemoryModel}. */ public Matrix newMatrix( long maxSizeAllocatedInJavaMemory, Class arraySupertype, Class elementType, long... dim) { long arrayLength = Arrays.longMul(dim); return (arrayLength != Long.MIN_VALUE // prefer throwing an exception by this class, not by SimpleMemoryModel && Arrays.sizeOf(elementType, arrayLength) <= maxSizeAllocatedInJavaMemory ? Arrays.SMM : this) .newMatrix(arraySupertype, elementType, dim); } public Matrix newMatrix(Class arraySupertype, Matrix matrix) { Objects.requireNonNull(matrix, "Null matrix argument"); return newMatrix(arraySupertype, matrix.elementType(), matrix.dimensions()); } public Matrix newStructuredMatrix(Class arraySupertype, Matrix matrix) { return newMatrix(arraySupertype, matrix).structureLike(matrix); } /*Repeat() boolean ==> char,,byte,,short,,int,,long,,float,,double;; Bit ==> Char,,Byte,,Short,,Int,,Long,,Float,,Double;; bit ==> char,,byte,,short,,int,,long,,float,,double */ public Matrix newBitMatrix(long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableBitArray array = newUnresizableBitArray(len); return new MatrixImpl(array, dim); } /*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */ public Matrix newCharMatrix(long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableCharArray array = newUnresizableCharArray(len); return new MatrixImpl(array, dim); } public Matrix newByteMatrix(long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableByteArray array = newUnresizableByteArray(len); return new MatrixImpl(array, dim); } public Matrix newShortMatrix(long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableShortArray array = newUnresizableShortArray(len); return new MatrixImpl(array, dim); } public Matrix newIntMatrix(long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableIntArray array = newUnresizableIntArray(len); return new MatrixImpl(array, dim); } public Matrix newLongMatrix(long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableLongArray array = newUnresizableLongArray(len); return new MatrixImpl(array, dim); } public Matrix newFloatMatrix(long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableFloatArray array = newUnresizableFloatArray(len); return new MatrixImpl(array, dim); } public Matrix newDoubleMatrix(long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableDoubleArray array = newUnresizableDoubleArray(len); return new MatrixImpl(array, dim); } /*Repeat.AutoGeneratedEnd*/ public Matrix> newObjectMatrix(Class elementType, long... dim) { long len = AbstractMatrix.checkDimensions(dim); UpdatableObjectArray array = newUnresizableObjectArray(elementType, len); return new MatrixImpl>(array, dim); } public Matrix newLazyCopy(Class arraySupertype, Matrix matrix) { return matrix.matrix(newUnresizableLazyCopy(matrix.array())).cast(arraySupertype); } public UpdatableArray valueOf(Object array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); Class elementType = array.getClass().getComponentType(); if (elementType == null) { throw new IllegalArgumentException("The argument is not a Java array: " + array.getClass()); } return newUnresizableArray(elementType, count).setData(0, array, offset, count); } public UpdatableArray valueOf(Object array) { Objects.requireNonNull(array, "Null array argument"); Class elementType = array.getClass().getComponentType(); if (elementType == null) { throw new IllegalArgumentException("The argument is not a Java array: " + array.getClass()); } return newUnresizableArray(elementType, java.lang.reflect.Array.getLength(array)).setData(0, array); } /*Repeat() boolean ==> char,,byte,,short,,int,,long,,float,,double;; Bit ==> Char,,Byte,,Short,,Int,,Long,,Float,,Double */ public UpdatableBitArray valueOf(boolean[] array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableBitArray) newUnresizableBitArray(count).setData(0, array, offset, count); } public UpdatableBitArray valueOf(boolean[] array) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableBitArray) newUnresizableBitArray(array.length).setData(0, array); } /*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */ public UpdatableCharArray valueOf(char[] array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableCharArray) newUnresizableCharArray(count).setData(0, array, offset, count); } public UpdatableCharArray valueOf(char[] array) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableCharArray) newUnresizableCharArray(array.length).setData(0, array); } public UpdatableByteArray valueOf(byte[] array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableByteArray) newUnresizableByteArray(count).setData(0, array, offset, count); } public UpdatableByteArray valueOf(byte[] array) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableByteArray) newUnresizableByteArray(array.length).setData(0, array); } public UpdatableShortArray valueOf(short[] array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableShortArray) newUnresizableShortArray(count).setData(0, array, offset, count); } public UpdatableShortArray valueOf(short[] array) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableShortArray) newUnresizableShortArray(array.length).setData(0, array); } public UpdatableIntArray valueOf(int[] array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableIntArray) newUnresizableIntArray(count).setData(0, array, offset, count); } public UpdatableIntArray valueOf(int[] array) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableIntArray) newUnresizableIntArray(array.length).setData(0, array); } public UpdatableLongArray valueOf(long[] array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableLongArray) newUnresizableLongArray(count).setData(0, array, offset, count); } public UpdatableLongArray valueOf(long[] array) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableLongArray) newUnresizableLongArray(array.length).setData(0, array); } public UpdatableFloatArray valueOf(float[] array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableFloatArray) newUnresizableFloatArray(count).setData(0, array, offset, count); } public UpdatableFloatArray valueOf(float[] array) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableFloatArray) newUnresizableFloatArray(array.length).setData(0, array); } public UpdatableDoubleArray valueOf(double[] array, int offset, int count) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableDoubleArray) newUnresizableDoubleArray(count).setData(0, array, offset, count); } public UpdatableDoubleArray valueOf(double[] array) { Objects.requireNonNull(array, "Null array argument"); return (UpdatableDoubleArray) newUnresizableDoubleArray(array.length).setData(0, array); } /*Repeat.AutoGeneratedEnd*/ public UpdatableObjectArray valueOf(E[] array, int offset, int count) { return InternalUtils.cast(valueOf((Object) array, offset, count)); } public UpdatableObjectArray valueOf(E[] array) { return InternalUtils.cast(valueOf((Object) array)); } public abstract boolean isElementTypeSupported(Class elementType); public abstract boolean areAllPrimitiveElementTypesSupported(); public abstract boolean areAllElementTypesSupported(); public abstract long maxSupportedLength(Class elementType); public abstract boolean isCreatedBy(Array array); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy