Class DefaultDataFileModel
- All Implemented Interfaces:
DataFileModel<File>
Default implementation of DataFileModel
that creates usual Java files,
which are mapped via standard Java technique (FileChannel.map method).
The data files
, returned by this class, creates
buffer holders
with the
unmap(boolean)
method which does not perform
actual unmapping: Java NIO package does not support unmapping.
File mapping will be released automatically by the built-in finalizers.
The close()
method in data files, returned by this class,
perform closing via RandomAccessFile.close() method,
but it may not completely close the disk file!
The disk file will be completely closed and all connected system resources will be freed
only while the following garbage collection at the unspecified moment,
or while exiting JVM.
So, if you need to process a very large number of AlgART arrays (tens of thousands or millions),
we recommend to use the StandardIODataFileModel
and
call Array.freeResources(ArrayContext)
method in time.
See comments to AbstractDataFileModel.createTemporary(boolean)
method for information about temporary
files created by this class.
Warning: under Sun Java versions before 1.7 (i.e. 1.5 and 1.6), this data file model is not stable, due to the Sun's bug "(fc) "Cleaner terminated abnormally" error in simple mapping test". More precisely, for Java prior to 1.7:
- In
lazy-writing mode
, this model is unstable at all: processing large arrays can lead to internal error while garbage collection, that will lead to immediate abnormal JVM termination. Due to this reason, thedefault lazy-writing mode
is false in Java versions prior to 1.7, but true in Java 1.7+. - In usual mode, this model can occasionally lead to unexpected IOError
while processing large arrays. Unlike an internal error in the lazy-writing mode,
this exception can be normally caught and shown to the user in GUI applications.
It can occur with large
bank size
(32 MB or more), if an array occupies several banks. This probability of this situation is not too high for unresizable arrays whensingle mapping
is used.
This class is immutable and thread-safe: there are no ways to modify settings of the created instance.
- Author:
- Daniel Alievsky
- See Also:
-
Field Summary
Fields inherited from class net.algart.arrays.AbstractDataFileModel
allTemporaryFiles, prefixSize, tempPath
-
Constructor Summary
ConstructorDescriptionEquivalent to newDefaultDataFileModel
(null, 0,defaultLazyWriting()
).DefaultDataFileModel
(boolean lazyWriting) Equivalent to newDefaultDataFileModel
(null, 0, lazyWriting).DefaultDataFileModel
(File tempPath) Equivalent to newDefaultDataFileModel
(tempPath, 0,defaultLazyWriting()
).DefaultDataFileModel
(File tempPath, boolean lazyWriting) Equivalent to newDefaultDataFileModel
(tempPath, 0, lazyWriting).DefaultDataFileModel
(File tempPath, long prefixSize, boolean lazyWriting) Creates new instance with specified lazy-writing mode. -
Method Summary
Modifier and TypeMethodDescriptionboolean
This implementation returns the value Boolean.getBoolean("net.algart.arrays.DefaultDataFileModel.autoResizingOnMapping"), stored while initializingDefaultDataFileModel
class, or false if there is no such system property or some exception occurred while calling Boolean.getBoolean.static boolean
Defaultlazy-writing mode
, used when this this class is instantiated by a constructor without lazyWriting argument.getDataFile
(File path, ByteOrder byteOrder) This implementation returns the data file corresponding to usual Java file new java.io.File(path) withDataFile.map
method based on standard Java mapping.Returns the absolute path to the disk file (java.io.File.getAbsoluteFile()).boolean
This implementation returns true.final boolean
Returns the lazyWriting argument, passed tothe constructor
while creating this instance.static long
The maximal amount of RAM (in bytes), allowed for simultaneous mapping by FileChannel.map method without flushing data to the disk by MappedByteBuffer.force() method.int
recommendedBankSize
(boolean unresizable) This implementation returns the value Integer.getInteger("net.algart.arrays.DefaultDataFileModel.bankSize",16777216) (16 MB) when the argument is true and Integer.getInteger("net.algart.arrays.DefaultDataFileModel.resizableBankSize",4194304) (4 MB) when the argument is false on 64-bit Java machines.int
This implementation returns the value Integer.getInteger("net.algart.arrays.DefaultDataFileModel.numberOfBanksPerCPU", 3) *Arrays.SystemSettings.availableProcessors()
, stored while initializing thisDefaultDataFileModel
class, or default value 3 *Arrays.SystemSettings.availableProcessors()
, if some exception occurred while calling Integer.getInteger.int
This implementation returns the value Integer.getInteger("net.algart.arrays.DefaultDataFileModel.singleMappingLimit",268435456) (256 MB) on 64-bit Java machines.This implementation returns "mapmm";toString()
Returns a brief string description of this class.Methods inherited from class net.algart.arrays.AbstractDataFileModel
allTemporaryFiles, byteOrderInTemporaryFiles, createTemporary, createTemporaryFile, delete, finalizationNotify, isConcreteFile, pathClass, recommendedPrefixSize, setTemporary, tempPath
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Methods inherited from interface net.algart.arrays.DataFileModel
allTemporaryFiles, createTemporary, delete, finalizationNotify, pathClass, recommendedPrefixSize, setTemporary
-
Constructor Details
-
DefaultDataFileModel
public DefaultDataFileModel()Equivalent to newDefaultDataFileModel
(null, 0,defaultLazyWriting()
). -
DefaultDataFileModel
public DefaultDataFileModel(boolean lazyWriting) Equivalent to newDefaultDataFileModel
(null, 0, lazyWriting).- Parameters:
lazyWriting
- it true, lazy-writing mode will be used.
-
DefaultDataFileModel
Equivalent to newDefaultDataFileModel
(tempPath, 0,defaultLazyWriting()
).- Parameters:
tempPath
- the path where new temporary files will be created byAbstractDataFileModel.createTemporaryFile(boolean)
method or null if the default temporary-file directory is to be used.
-
DefaultDataFileModel
Equivalent to newDefaultDataFileModel
(tempPath, 0, lazyWriting).- Parameters:
tempPath
- the path where new temporary files will be created byAbstractDataFileModel.createTemporaryFile(boolean)
method or null if the default temporary-file directory is to be used.lazyWriting
- it true, lazy-writing mode will be used.
-
DefaultDataFileModel
Creates new instance with specified lazy-writing mode.Please see
AbstractDataFileModel(File, long)
about tempPath and prefixSize arguments.The lazyWriting argument specifies whether the data files will use lazy writing mode. Namely, if this flag is set, flushing or unmapping the mapped regions via
DataFile.BufferHolder.flush(false)
,DataFile.BufferHolder.unmap(false)
calls will not lead to immediate writing data to the disk file: this method will not do anything. Instead, the data will be really written by garbage collector. If this flag is not set, any call ofDataFile.BufferHolder.flush(boolean)
orDataFile.BufferHolder.unmap(boolean)
method forces writing data to the disk by force() method of MappedByteBuffer class.By default, if you use constructors without lazyWriting argument, this flag is retrieved from the system property "net.algart.arrays.DefaultDataFileModel.lazyWriting" or, if there is no such property, is set to true in Java 1.7+ or false in Java 1.5 and 1.6. Please see
defaultLazyWriting()
.Usually, you should set lazyWriting flag to true. It can essentially increase the performance, if you create and modify many large AlgART arrays, because OS will store the new data in the cache and will not physically write data to the disk. Even in this case, this class periodically flushs the unsaved data, when the summary amount of mapped buffers exceeds the limit returned by
maxMappedMemory()
method.The false value of this flag may be recommended if the stable behavior of your application is more important than the speed. If lazy writing is disabled, the application will use less RAM and the risk of swapping will be much less, because each new data will be immediately saved to the disk and will not be cached in RAM.
Unfortunately, lazy-writing mode leads to internal Sun's bug in Java 1.5 and 1.6: we recommend never set it to true in these Java versions. The detailed description of this bug is here: "(fc) "Cleaner terminated abnormally" error in simple mapping test".
- Parameters:
tempPath
- the path where new temporary files will be created byAbstractDataFileModel.createTemporaryFile(boolean)
method or null if the default temporary-file directory is to be used.prefixSize
- the value returned byAbstractDataFileModel.recommendedPrefixSize()
implementation in this class.lazyWriting
- it true, lazy-writing mode will be used.- See Also:
-
-
Method Details
-
defaultLazyWriting
public static boolean defaultLazyWriting()Defaultlazy-writing mode
, used when this this class is instantiated by a constructor without lazyWriting argument. More precisely, if there is the system property "net.algart.arrays.DefaultDataFileModel.lazyWriting", containing "true" or "false" string (in lower case), this method returns true if this property contains "true" and false if this property contains "false". If there is no such property, or if it contains illegal string (not "true" or "false"), or if some exception occurred while calling System.getProperty, this method returns true in Java 1.7 or higher Java version and false in Java 1.5 and Java 1.6. The value of this system property is loaded and checked only once while initializingDefaultDataFileModel
class.- Returns:
- default
lazy-writing mode
-
maxMappedMemory
public static long maxMappedMemory()The maximal amount of RAM (in bytes), allowed for simultaneous mapping by FileChannel.map method without flushing data to the disk by MappedByteBuffer.force() method.This value is important while using
lazy-writing mode
. In this case, a lot of mapping requests (calls of FileChannel.map), with modifications of the mapped data and without further MappedByteBuffer.force(), will use RAM for storing the changed data in the system cache. When all (or almost all) available RAM will be spent, it may lead to intensive disk swapping. The reason is that the mapped memory is not controlled by Java garbage collector: it is possible to map much more disk memory than Runtime.maxMemory(). The result may be extremely slowing down of all other applications, working on the computer, and even practical impossibility of any work: all RAM will be occupied by your application.To avoid this behavior, this class controls the total amount of mapped memory (summary size of all mapped buffers in all files), and when it exceeds the limit, returned by this method, calls MappedByteBuffer.force() for all currently mapped buffers and, so, flushs the data to the disk and frees the system memory.
This value, returned by this method, is retrieved from the system property "net.algart.arrays.maxMappedMemory", if it exists and contains a valid integer number. If this property contains zero or negative integer, this method returns 0, and it means that the amount of RAM for simultaneous mapping is not limited at all: the application will try to use all available system memory. If this property contains an integer greater than the limit 256~7.2*1016, this limit is used instead: it guarantees that using this value will not lead to integer overflow. If there is no such property, or if it contains not a number, or if some exception occurred while calling Long.getLong, this method returns the default value 536870912 (512 MB). The value of this system property is loaded and checked only once while initializing
DefaultDataFileModel
class.We recommend to always set this system property in serious applications, working with large AlgART arrays. The suitable value is about 50-100% of the current RAM installed on the computer. The default value 512 MB works well if you don't need to process larger amounts of data frequently.
- Returns:
- the maximal amount of RAM (in bytes), allowed for simultaneous mapping by this class.
-
isLazyWriting
public final boolean isLazyWriting()Returns the lazyWriting argument, passed tothe constructor
while creating this instance.- Returns:
- the lazyWriting flag, passed to the constructor.
-
getDataFile
This implementation returns the data file corresponding to usual Java file new java.io.File(path) withDataFile.map
method based on standard Java mapping.This method never throws java.io.IOError.
- Specified by:
getDataFile
in interfaceDataFileModel<File>
- Specified by:
getDataFile
in classAbstractDataFileModel
- Parameters:
path
- the path to disk file (as the argument of new java.io.File(path)).byteOrder
- the byte order that will be always used for mapping this file.- Returns:
- new instance of
DataFile
object. - Throws:
NullPointerException
- if one of the passed arguments is null.
-
getPath
Returns the absolute path to the disk file (java.io.File.getAbsoluteFile()). The argument may be created by this data file model or byStandardIODataFileModel
.This method never throws java.io.IOError.
- Specified by:
getPath
in interfaceDataFileModel<File>
- Specified by:
getPath
in classAbstractDataFileModel
- Parameters:
dataFile
- the data file.- Returns:
- the absolute path to the disk file.
- Throws:
NullPointerException
- if the argument is null.ClassCastException
- if the data file was created by data file model, other thanDefaultDataFileModel
orStandardIODataFileModel
.
-
isAutoDeletionRequested
public boolean isAutoDeletionRequested()This implementation returns true.
- Specified by:
isAutoDeletionRequested
in interfaceDataFileModel<File>
- Specified by:
isAutoDeletionRequested
in classAbstractDataFileModel
- Returns:
- true.
-
recommendedNumberOfBanks
public int recommendedNumberOfBanks()This implementation returns the value Integer.getInteger("net.algart.arrays.DefaultDataFileModel.numberOfBanksPerCPU", 3) *
Arrays.SystemSettings.availableProcessors()
, stored while initializing thisDefaultDataFileModel
class, or default value 3 *Arrays.SystemSettings.availableProcessors()
, if some exception occurred while calling Integer.getInteger. If this value is less than 2, returns 2. If "net.algart.arrays.DefaultDataFileModel.numberOfBanksPerCPU" property contains negative or zero integer, returns 2.Please note that many algorithms, on multiprocessor or multi-core systems, use several parallel threads for processing arrays: see
Arrays.ParallelExecutor
. So, the number of banks should be enough for parallel using by all CPU units, to avoid frequently bank swapping. There should be at least 2 banks per each CPU unit, better 3-4 banks (for complex random-access algorithms).- Specified by:
recommendedNumberOfBanks
in interfaceDataFileModel<File>
- Specified by:
recommendedNumberOfBanks
in classAbstractDataFileModel
- Returns:
- the recommended number of memory banks.
-
recommendedBankSize
public int recommendedBankSize(boolean unresizable) This implementation returns the value Integer.getInteger("net.algart.arrays.DefaultDataFileModel.bankSize",16777216) (16 MB) when the argument is true and Integer.getInteger("net.algart.arrays.DefaultDataFileModel.resizableBankSize",4194304) (4 MB) when the argument is false on 64-bit Java machines. On 32-bit JVM, this method returns Integer.getInteger("net.algart.arrays.DefaultDataFileModel.bankSize32",4194304) (4 MB) when the argument is true and Integer.getInteger("net.algart.arrays.DefaultDataFileModel.resizableBankSize32",2097152) (2 MB) when the argument is false. These values are stored while initializing
DefaultDataFileModel
class. If some exceptions occur while calling Integer.getInteger, the default values 16777216 / 4194304 (for 64-bit Java) or 4194304 / 2097152 (for 32-bit Java) are returned. If this property contains invalid value (for example, not a power of two), this value is automatically corrected to the nearest valid one.This method distinguishes between 32-bit and 64-bit Java via
Arrays.SystemSettings.isJava32()
method. Please remember that the result of that method is not 100% robust; so, please not specify too high values if you are not quite sure that your JVM is not 32-bit and has no 32-bit limitations for the address space.- Specified by:
recommendedBankSize
in interfaceDataFileModel<File>
- Specified by:
recommendedBankSize
in classAbstractDataFileModel
- Parameters:
unresizable
- true if this bank size will be used for unresizable arrays only.- Returns:
- the recommended size of every memory bank in bytes.
- See Also:
-
recommendedSingleMappingLimit
public int recommendedSingleMappingLimit()This implementation returns the value Integer.getInteger("net.algart.arrays.DefaultDataFileModel.singleMappingLimit",268435456) (256 MB) on 64-bit Java machines. On 32-bit JVM, this method returns Integer.getInteger("net.algart.arrays.DefaultDataFileModel.singleMappingLimit32",4194304) (4 MB). This value is stored while initializing
DefaultDataFileModel
class. If some exceptions occur while calling Integer.getInteger, the default value 268435456 (or 4194304 for 32-bit Java) is returned.This method distinguishes between 32-bit and 64-bit Java via
Arrays.SystemSettings.isJava32()
method. Please remember that the result of that method is not 100% robust; so, please not specify too high values if you are not quite sure that your JVM is not 32-bit and has no 32-bit limitations for the address space.- Specified by:
recommendedSingleMappingLimit
in interfaceDataFileModel<File>
- Overrides:
recommendedSingleMappingLimit
in classAbstractDataFileModel
- Returns:
- the recommended limit for file size, in bytes, so that less files, if they are unresizable,
should be mapped only once by single call of
DataFile.map(net.algart.arrays.DataFile.Range, boolean)
method.
-
autoResizingOnMapping
public boolean autoResizingOnMapping()This implementation returns the value Boolean.getBoolean("net.algart.arrays.DefaultDataFileModel.autoResizingOnMapping"), stored while initializing
DefaultDataFileModel
class, or false if there is no such system property or some exception occurred while calling Boolean.getBoolean.- Specified by:
autoResizingOnMapping
in interfaceDataFileModel<File>
- Overrides:
autoResizingOnMapping
in classAbstractDataFileModel
- Returns:
- true if mapping outside the file length automatically increase the length.
-
temporaryFilePrefix
This implementation returns "mapmm";- Overrides:
temporaryFilePrefix
in classAbstractDataFileModel
- Returns:
- "mapmm".
-
toString
Returns a brief string description of this class.The result of this method may depend on implementation.
-