Class MatrixInfo

java.lang.Object
net.algart.arrays.MatrixInfo

public abstract class MatrixInfo extends Object

Full structural information about the AlgART matrix, consisting of elements of some primitive types, in a form convenient for serialization. This class contains information about the matrix element type, matrix dimensions and byte order, and allows to pack this information, with special signature, into a byte array or String (serialize, toBytes() / toChars() methods) and, vice versa, convert such byte array or String to an instance of this class (deserialize, valueOf(byte[]) / valueOf(String) methods).

This tool helps to store AlgART matrices in external files. The "raw" matrix data, i.e. elements of the built-in AlgART array, can be stored / loaded via

methods. However, if you want to load a matrix from a file, you need structural information about it, that should be passed to these methods and to Matrices.matrix(Array, long...). This class encapsulates all this information and allows to represent it in a form of Java byte array byte[] or in a usual String, that can be stored in a separate file or in a prefix of the given data file (before the filePosition, passed to asArray / asUpdatableArray methods). This class can be used together with higher-level methods

More precisely, this class represents the following information about the matrix:

  1. The type of matrix elements: see elementType() method.
  2. The byte order used by the matrix for storing data: see byteOrder() method.
  3. The matrix dimensions: see dimensions() method.

In addition to this information about a matrix, this class also contains the following data:

  1. Version: some string determining the format of conversion of this information to byte array by toBytes() method or to String by toChars() method. The version is always stored in the serialized form returned by toBytes() / toChars() methods. If the instance of this class was created by valueOf(Matrix, long) method, its version is equal to the current default version DEFAULT_VERSION (but you may specify some older version via valueOf(Matrix, long, String) method). If the instance was created by valueOf(byte[]) or valueOf(String), the version is equal to the version stored in this byte/char sequence. Future implementations of this class will support all old serialization formats.
  2. Data offset: some long value, that usually means the offset of the matrix content in the data file. This offset is necessary for mapping the array to a disk file via asArray / asUpdatableArray methods (it is their filePosition argument). For example, if you use this class to add a fixed-size prefix to the file containg the matrix, this value may contain the prefix length. You also may ignore this offset and always pass 0 (or any other value) as an argument of valueOf(Matrix, long) method.
  3. (Since the version 1.2) Additional properties: a map of some strings, that can store some additional information about the matrix, for example, about its tiling. All properties are also serialized by toBytes() / toChars() methods, deserialized by valueOf(byte[]) / valueOf(String) methods and accessed via additionalProperties() and cloneWithOtherAdditionalProperties(Map) methods.

This class does work with primitive element types only: boolean, char, byte, short, int, long, float and double. The number of matrix dimensions (Matrix.dimCount()) must be not greater than Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS.

Below is an example of creating 1000x1000 matrix in a mapped file with the prefix based on this class:

 final File file = new File("someFileName.dat");
 DataFileModel<File> dfm = new DefaultDataFileModel(file, MatrixInfo.MAX_SERIALIZED_MATRIX_INFO_LENGTH, false);
 LargeMemoryModel<File> lmm = LargeMemoryModel.getInstance(dfm);
 Class elementType = float.class;
 Matrix<UpdatablePArray> m = lmm.newMatrix(elementType, 1000, 1000);
 MatrixInfo mi = MatrixInfo.valueOf(m, MatrixInfo.MAX_SERIALIZED_MATRIX_INFO_LENGTH);
 UpdatableByteArray ba = lmm.asUpdatableByteArray(LargeMemoryModel.getDataFilePath(m.array()),
     0, MatrixInfo.MAX_SERIALIZED_MATRIX_INFO_LENGTH, false, ByteOrder.nativeOrder());
 ba.setData(0, mi.toBytes());
 LargeMemoryModel.setTemporary(m.array(), false);
 

The following code opens this file as a matrix for read-write access:

 final String file = new File("someFileName.dat");
 LargeMemoryModel<File> lmm = LargeMemoryModel.getInstance();
 ByteArray ba = lmm.asByteArray(file, 0,
     Math.min(file.length(), MatrixInfo.MAX_SERIALIZED_MATRIX_INFO_LENGTH),
     ByteOrder.nativeOrder());
 // "min" here is added to be on the safe side: maybe, this file was created by another program with shorter prefix
 MatrixInfo mi = MatrixInfo.valueOf(Arrays.toJavaArray(ba));
 UpdatablePArray pa = lmm.asUpdatableArray(file,
     mi.elementType(), mi.dataOffset(), LargeMemoryModel.ALL_FILE, false, mi.byteOrder());
 pa = pa.subArr(0, Math.min(pa.length(), mi.size()));
 // "min" here necessary because matrix info can be damaged: then subArr throws a non-informative exception
 // mi.size() is necessary even for correct file: for example, bit arrays occupy uneven number of bytes
 Matrix<UpdatablePArray> m = Matrices.matrix(pa, mi.dimensions());
 

This class is immutable and thread-safe: there are no ways to modify settings of the created instance.

Author:
Daniel Alievsky
See Also:
  • Field Details

    • MAX_SERIALIZED_MATRIX_INFO_LENGTH

      public static final int MAX_SERIALIZED_MATRIX_INFO_LENGTH
      The maximal allowed length of byte array or String, returned by toBytes() / toChars() methods: 8192. This length is enough to store Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS = 9 matrix dimensions, start signature, element type, byte order and more than 7 KB of additional information.

      Note that this limit guarantees that the string toChars() can be written and restored via DataOutput.writeUTF and DataInput.readUTF methods, because the required number of bytes in the modified UTF-8 representation is much less than 65535 (the limit for these Java I/O methods).

      See Also:
    • MAX_NUMBER_OF_PROPERTIES_IN_MATRIX_INFO

      public static final int MAX_NUMBER_OF_PROPERTIES_IN_MATRIX_INFO
      The maximal number of additional properties, that can be stored in this object: 10000.
      See Also:
    • DEFAULT_VERSION

      public static String DEFAULT_VERSION
      The current default version of the serialized format of the information about matrices: "1.2".
  • Method Details

    • valueOf

      public static MatrixInfo valueOf(Matrix<? extends PArray> matrix, long dataOffset)
      Creates an instance of this class containing full structural information about the given matrix. The created instance will have the version, equal to the default version supported by this class: DEFAULT_VERSION.
      Parameters:
      matrix - the matrix.
      dataOffset - the value that may be interpreted as an offset of some "main" data and that will be stored in byte array returned by toBytes() method.
      Returns:
      full structural information about the matrix.
      Throws:
      NullPointerException - if the argument is null.
      TooLargeArrayException - if the number of matrix dimensions is greater than Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS.
      ClassCastException - if the built-in array in the matrix is not PArray.
    • valueOf

      public static MatrixInfo valueOf(Matrix<? extends PArray> matrix, long dataOffset, String version)
      Creates an instance of this class containing full structural information about the given matrix with the specified version of serialization format.

      The specified version must be supported by this class. Current implementation supports the following versions: "1.1" and "1.2". There is no guarantee that all previous format versions, that was supported by old implementations of this class, will be supported by this method. (However, all previous format versions are always supported by deserialization methods valueOf(byte[]) and valueOf(String).)

      Parameters:
      matrix - the matrix.
      dataOffset - the value that may be interpreted as an offset of some "main" data and that will be stored in byte array returned by toBytes() method.
      version - the version of the serialization format supported by the created instance.
      Returns:
      full structural information about the matrix.
      Throws:
      NullPointerException - if the argument is null.
      TooLargeArrayException - if the number of matrix dimensions is greater than Matrix.MAX_DIM_COUNT_FOR_SOME_ALGORITHMS.
      ClassCastException - if the built-in array in the matrix is not PArray.
      IllegalArgumentException - if the specified version is not supported by this class.
    • valueOf

      public static MatrixInfo valueOf(byte[] bytes) throws IllegalInfoSyntaxException
      Deserializes the byte array and creates new instance of this class on the base of information, stored in this byte array.

      The passed data must have format, corresponding to the current default format version or to any previous format version, that was somewhen implemented by this class in the past. In other case, IllegalInfoSyntaxException will be thrown.

      The passed array may contain extra elements after the end of the stored information. All versions of this class guarantee that random bytes after the end of the serialized information will not lead to problems: the serialization format always allows to detect the end of information in the sequence of bytes.

      Parameters:
      bytes - the byte array produced by some previous call of toBytes() method.
      Returns:
      new instance of this class, built on the base of the passed byte array.
      Throws:
      NullPointerException - if the argument is null.
      IllegalInfoSyntaxException - if the format of bytes argument is illegal.
      See Also:
    • valueOf

      public static MatrixInfo valueOf(String chars) throws IllegalInfoSyntaxException
      Deserializes the char array (passed as String argument) and creates new instance of this class on the base of information, stored in this char array.

      The passed data must have format, corresponding to the current default format version or to any previous format version, that was somewhen implemented by this class in the past. In other case, IllegalInfoSyntaxException will be thrown.

      The passed char array may contain extra elements after the end of the stored information. All versions of this class guarantee that random characters after the end of the serialized information will not lead to problems: the serialization format always allows to detect the end of information in the sequence of characters.

      Parameters:
      chars - the string produced by some previous call of toChars() method.
      Returns:
      new instance of this class, built on the base of the passed string.
      Throws:
      NullPointerException - if the argument is null.
      IllegalInfoSyntaxException - if the format of chars argument is illegal.
      See Also:
    • isCorrectAdditionalPropertyName

      public static boolean isCorrectAdditionalPropertyName(String name)
      Returns true if and only if the passed string is an allowed name for an additional property, that can be stored via cloneWithOtherAdditionalProperties(Map) method. Namely, this method returns true if and only if:
      • the passed name is not empty (name.length()>0);
      • the passed name contains only characters from the following set: digits '0'..'9', latin letters 'a'..'z' and 'A'..'Z', the dot '.' and the underline character '_';
      • the first character of the name is a letter 'a'..'z' or 'A'..'Z'.

      There is a guarantee that the keys in the map, returned by additionalProperties() method, always fulfil this condition.

      Parameters:
      name - the checked property name.
      Returns:
      whether the passed string is an allowed name for an additional property.
      Throws:
      NullPointerException - if the argument is null.
    • version

      public final String version()
      Returns the version of the serialization format implemented by this instance.

      If this instance was created by valueOf(byte[]) or valueOf(String) method, this version corresponds to the format of the data in the argument of that method. If this instance was created by valueOf(Matrix, long, String) method, this version is equal to the last argument of that method. If this instance was created by valueOf(Matrix, long) method, this version is equal DEFAULT_VERSION.

      The version format is traditional: "N.N" or "N.N.N" (every "N" is a single digit 0..9).

      Returns:
      the version of the serialization of the stored data.
    • elementType

      public final Class<?> elementType()
      Returns the type of matrix elements.
      Returns:
      the type of matrix elements.
      See Also:
    • bitsPerElement

      public long bitsPerElement()
      Returns the size in bits, required for each matrix element. Equivalent to Arrays.bitsPerElement(thisInstance.elementType()).
      Returns:
      the size in bits, required for each matrix element.
      See Also:
    • byteOrder

      public final ByteOrder byteOrder()
      Returns the byte order used by the matrix for storing data.

      This method never returns null.

      Returns:
      the byte order used by the matrix for storing data.
      See Also:
    • size

      public final long size()
      Returns the array length: total number of elements in the matrix. Always equal to the product of all matrix dimensions.
      Returns:
      the array length: total number of elements in the matrix.
      See Also:
    • dimensions

      public final long[] dimensions()
      Returns the array containing all matrix dimensions.

      The returned array is a clone of the internal dimension array stored in this object.

      Returns:
      the array containing all dimensions of the matrix.
      See Also:
    • dimCount

      public final int dimCount()
      Returns the number of the matrix dimensions. This value is always positive (>=1). Equivalent to dimensions().length, but works faster.
      Returns:
      the number of the matrix dimensions.
      See Also:
    • dim

      public final long dim(int n)
      Returns the dimension #n of the matrix or 1 if n>=dimCount(). Equivalent to n<dimCount()?dimensions()[n]:1, but works faster.
      Parameters:
      n - the index of matrix dimension.
      Returns:
      the dimension #n of the matrix.
      Throws:
      IndexOutOfBoundsException - if n<0 (but not if n is too large).
      See Also:
    • dataOffset

      public final long dataOffset()
      Returns the data offset, passed to valueOf(Matrix, long) or valueOf(Matrix, long, String) method or loaded from the serialized form by valueOf(byte[]) or valueOf(String) method.
      Returns:
      the data offset.
    • additionalProperties

      public abstract Map<String,String> additionalProperties()
      Returns additional string properties, stored in this instance. These properties can be loaded from a serialized form by valueOf(byte[]) / valueOf(String) methods or added by cloneWithOtherAdditionalProperties(Map) method.

      There is a guarantee that the keys and values, returned by this method, are always non-null String instances, and that the keys always fulfil the isCorrectAdditionalPropertyName(String) method.

      The returned map is a clone of the internal map stored in this object. The returned map is always mutable and allows to add/remove elements, alike HashMap or TreeMap classes. The returned object is never null.

      Note that the first version 1.1 of serialization format does not support this feature. If the current version of serialization format of this instance is 1.1, this method always returns an empty map.

      Returns:
      additional string properties, stored in this instance.
      See Also:
    • cloneWithOtherByteOrder

      public abstract MatrixInfo cloneWithOtherByteOrder(ByteOrder byteOrder)
      Creates an instance of this class, identical to this one, with the only difference that the new instance have the specified byte order.
      Parameters:
      byteOrder - new value of byte order.
      Returns:
      modified instance of this class.
      Throws:
      NullPointerException - if the argument is null.
    • cloneWithOtherVersion

      public MatrixInfo cloneWithOtherVersion(String version)
      Creates an instance of this class, identical to this one, with the only difference that the new instance have the specified version of the serialization format.

      It is possible that the specified version does not support all features, supported by this object, and cannot create fully identical instance. In particular, it is possible if the specified version is 1.1 and the map of properties, returned by additionalProperties() method, is not empty. In this case, this method throws UnsupportedOperationException.

      Parameters:
      version - required version.
      Returns:
      modified instance of this class.
      Throws:
      NullPointerException - if the argument is null.
      IllegalArgumentException - if the specified version is not supported by this class.
      UnsupportedOperationException - if the specified version cannot store all information, stored in this object.
    • cloneWithOtherDataOffset

      public abstract MatrixInfo cloneWithOtherDataOffset(long dataOffset)
      Creates an instance of this class, identical to this one, with the only difference that the new instance have the specified data offset.
      Parameters:
      dataOffset - new value of data offset.
      Returns:
      modified instance of this class.
    • cloneWithOtherAdditionalProperties

      public abstract MatrixInfo cloneWithOtherAdditionalProperties(Map<String,String> additionalProperties)
      Creates an instance of this class, identical to this one, with the only difference that the new instance have the specified map of named additional string properties. The specified map can be serialized by toBytes() / toChars() methods and retrieved by additionalProperties() method.

      The names of all specified properties must fulfil the isCorrectAdditionalPropertyName(String) method. In addition to this requirement, we recommend not to use (for your own goals) properties starting with "net.algart.arrays." substring, because some methods of this package use such properties.

      The values of all specified properties must be non-null String instances, that can contain any characters.

      Please avoid very large number or size of properties. There are limits for the number of properties (MAX_NUMBER_OF_PROPERTIES_IN_MATRIX_INFO) and for the total size of the data that can be stored while serialization (MAX_SERIALIZED_MATRIX_INFO_LENGTH).

      Note that the first version 1.1 of serialization format does not support this feature. So, if the current version of serialization format of this instance is 1.1, this method throws UnsupportedOperationException. The method additionalProperties() still works in the version 1.1 and returns an empty map.

      The passed additionalProperties argument is cloned by this method: no references to it are maintained by the created instance.

      Parameters:
      additionalProperties - another additional properties.
      Returns:
      modified instance of this class.
      Throws:
      UnsupportedOperationException - if the version of this instance is 1.1.
      NullPointerException - if the argument is null or if some keys or values are null.
      ClassCastException - if some of keys or values are not String instances (this situation is possible while passing raw Map type without generics).
      IllegalArgumentException - if one of the passed properties has incorrect name (for which isCorrectAdditionalPropertyName(String) method returns false) or if the number of passed properties is greater than MAX_NUMBER_OF_PROPERTIES_IN_MATRIX_INFO.
      See Also:
    • toBytes

      public byte[] toBytes()
      Serializes the content of this instance into a byte array and returns it. The format of serialization depends on the version of this instance.

      The length of returned array never exceeds MAX_SERIALIZED_MATRIX_INFO_LENGTH.

      Returns:
      the content of this instance converted into a byte array.
      Throws:
      IllegalStateException - if the summary size of all additional properties is very large and, so, this instance cannot be serialized in MAX_SERIALIZED_MATRIX_INFO_LENGTH bytes.
      See Also:
    • toChars

      public abstract String toChars()
      Serializes the content of this instance into a char sequence and returns it. The format of serialization depends on the version of this instance.

      The length of returned string never exceeds MAX_SERIALIZED_MATRIX_INFO_LENGTH.

      Returns:
      the content of this instance converted into a string.
      Throws:
      IllegalStateException - if the summary size of all additional properties is very large and, so, this instance cannot be serialized in MAX_SERIALIZED_MATRIX_INFO_LENGTH characters.
      See Also:
    • matches

      public boolean matches(Matrix<?> matrix)
      Indicates whether this information correctly describes the given matrix. Returns true if and only if:
      1. matrix.elementType().equals(this.elementType());
      2. matrix.array().byteOrder() == this.byteOrder();
      3. matrix.dimensions() and this dimensions() arrays are identical.
      Parameters:
      matrix - the matrix to be compared with this matrix information.
      Returns:
      true if this information correctly describes the given matrix.
      Throws:
      NullPointerException - if the argument is null.
    • toString

      public String toString()
      Returns a brief string description of this object.

      The result of this method may depend on implementation and usually contains a short description of all matrix dimensions.

      Overrides:
      toString in class Object
      Returns:
      a brief string description of this object.
    • hashCode

      public int hashCode()
      Returns the hash code of this matrix information. The result depends on the element type, byte order, all dimensions, data offset and all additional properties, but does not depend on the version.
      Overrides:
      hashCode in class Object
      Returns:
      the hash code of this matrix information.
    • equals

      public boolean equals(Object obj)
      Indicates whether some other matrix information is equal to this instance. Returns true if and only if:
      1. the specified object is a non-null MatrixInfo instance;
      2. both instances have the same element type and byte order;
      3. both instances have equal dimension arrays;
      4. both instances have the same data offset;
      5. both instances have the equal additional properties maps, in terms of Map.equals method.

      Please note that this method, unlike Matrix.equals(Object), compares the byte order in both objects. This method does not check versions of the objects.

      Overrides:
      equals in class Object
      Parameters:
      obj - the object to be compared for equality with this instance.
      Returns:
      true if the specified object is a matrix information equal to this one.