Interface Arrays.SystemSettings.DiskSynchronizer

Enclosing class:
Arrays.SystemSettings

public static interface Arrays.SystemSettings.DiskSynchronizer

Global synchronizer, used for all disk operations, performed by this package. More precisely, the implementation of interface, returned by Arrays.SystemSettings.globalDiskSynchronizer() method, is used for all operations with disk files, performed by DefaultDataFileModel and StandardIODataFileModel.

Access to AlgART arrays, created via LargeMemoryModel, can require loading or saving some portion of data at an external device, according to the used DataFileModel. However, access to AlgART arrays can be performed from several threads: for example, each window of your application can use own thread for calculations. If the device for storing data is a usual disk, then simultaneous multithreading access to it can lead to extreme slowing down all calculations: unlike RAM, most of disk devices do not provide quick parallel I/O operation with different files or portions of a file.

To solve this problem, this library performs any action, connected with disk I/O operations — reading or writing file regions, mapping, preloading or flushing mapped buffers (MappedByteBuffer.load/force methods) — not directly, but via calling doSynchronously(String, Callable) method of the global implementation of this interface, returned by Arrays.SystemSettings.globalDiskSynchronizer() method. For example, DefaultDataFileModel class performs disk mapping in the following manner:

 MappedByteBuffer buffer = Arrays.SystemSettings.globalDiskSynchronizer().doSynchronously(
     fileName,
     new Callable() {
         public MappedByteBuffer call() throws IOException {
             return fileChannel.map(mode, position, size);
         }
     });
 

You can use (and usually should use) the analogous "wrapping" of your own disk operations.

By default, the implementation of doSynchronously(String fileName, Callable action) method performs the desired action with global synchronization, alike in the following code:

 synchronized (globalLock) { // some private static field
     return action.call();
 }
 

It means that all disk operations, which are performed via this disk synchronizer, will be performed sequentially always. It is a good solution for most of disk devices.

However, some disk controllers provide quick parallel disk operation, usually with different disks. If your application should be optimized for such systems, you may provide your own custom implementation of this interface and specify it via "net.algart.arrays.globalDiskSynchronizer" system property (see globalDiskSynchronizer()). Your implementation, for example, can analyse the file name, detect the physical device, corresponding to this file, and allow simultaneous operation at different devices.

It is obvious that any implementation of this interface is thread-safe.

  • Method Summary

    Modifier and Type
    Method
    Description
    <T> T
    doSynchronously(String fileName, Callable<T> action)
    Performs the specified action synchronously.
  • Method Details

    • doSynchronously

      <T> T doSynchronously(String fileName, Callable<T> action) throws Exception
      Performs the specified action synchronously. Depending on implementation, it is probably performed with some form of global synchronization.

      The specified action is supposed to be I/O operation with a file, the absolute path to which is passed via fileName argument. This name can help to control synchronization depending on the physical disk where the file is located: for example, this method can allow simultaneous reading 2 files, if they are placed on disks C: and D: (controlled by different disk controllers), but can disable simultaneous reading files from the same disk.

      The default implementation does not use this argument.

      Parameters:
      fileName - the symbolic name of file, probably its canonical path.
      action - some I/O operations that should be synchronously performed with this file.
      Returns:
      result of the operation.
      Throws:
      Exception - if unable to compute a result.