Class AbstractArrayContext

java.lang.Object
net.algart.arrays.AbstractArrayContext
All Implemented Interfaces:
ArrayContext
Direct Known Subclasses:
DefaultArrayContext

public abstract class AbstractArrayContext extends Object implements ArrayContext

A skeletal implementation of the ArrayContext interface to minimize the effort required to implement this interface.

All non-abstract methods of this class are completely implemented and usually should not be overridden.

Author:
Daniel Alievsky
  • Constructor Details

    • AbstractArrayContext

      public AbstractArrayContext()
  • Method Details

    • part

      public ArrayContext part(double fromPart, double toPart)
      Description copied from interface: ArrayContext
      Returns new context, describing the execution of some subtask of the current task, from fromPart*100% of total execution until toPart*100% of total execution. The returned context works alike the current context with the only exception, that its updateProgress method passes to this (parent) context little corrected event. Namely, its ArrayContext.Event.readyPart() method of the passed event returns fromPart+event.readyPart()*(toPart-fromPart). The methods ArrayContext.getMemoryModel(), ArrayContext.getThreadPoolFactory(), ArrayContext.checkInterruption() of the returned instance call the same methods of this one.

      Below is an example of the situation when this method is necessary. Let we have 3 methods in some class: fullTask(ArrayContext), subTask1(ArrayContext), subTask2(ArrayContext). The only function of fullTask method is sequential call of subTask1 and subTask2. We can implement it in the following way:

       void fullTask(ArrayContext context) {
           subTask1(context);
           subTask2(context);
       }
       

      However, such implementation leads to a problem. The context probably has updateProgress method, that shows the execution progress to the user, for example, shows the percents of performed calculations, from 0% to 100%. This information is returned by ArrayContext.Event.readyPart() method. But the implementation, listed above, will show the change of percents from 0% to 100% twice: first time in subTask1 method, second time in subTask2 method.

      This class provides solutions of this problem. Namely:

       void fullTask(ArrayContext context) {
           subTask1(context.part(0.0, 0.5));
           subTask2(context.part(0.5, 1.0));
       }
       

      Now the execution of subTask1 method will change percents from 0% to 50% and the execution of subTask2 method will change percents from 50% to 100%.

      In many case the overloaded method ArrayContext.part(long, long, long) is more convenient.

      Specified by:
      part in interface ArrayContext
      Parameters:
      fromPart - the estimated ready part, from 0.0 to 1.0, of the total algorithm at the start of the subtask: see updateProgress method
      toPart - the estimated ready part, from 0.0 to 1.0, of the total algorithm at the finish of the subtask: see updateProgress method; must be not less than fromPart range.
      Returns:
      new context, describing the execution of the subtask of the current task.
      See Also:
    • part

      public ArrayContext part(long from, long to, long total)
      Description copied from interface: ArrayContext
      Returns new context, describing the execution of some subtask of the current task, from from/total*100% of total execution until to/total*100% of total execution. More precisely, equivalent to the following call:
       part((double)from/(double)total, to==total ? 1.0: (double)to/(double)total)
       
      excepting the case from=to=total=0, when it is equivalent to
       part(0.0, 1.0)
       
      Specified by:
      part in interface ArrayContext
      Parameters:
      from - the estimated ready part, from 0 to total, of the total algorithm at the start of the subtask.
      to - the estimated ready part, from 0.0 to total, of the total algorithm at the finish of the subtask.
      total - the number of some operation in the full task.
      Returns:
      new context, describing the execution of the subtask of the current task.
      See Also:
    • noProgressVersion

      public ArrayContext noProgressVersion()
      Description copied from interface: ArrayContext
      Returns new context, identical to this one with the only exception that its ArrayContext.updateProgress(Event) method does nothing. It can be useful in multithreading algorithms, when some complex tasks, requiring a context for their execution, are executed simultaneously, but these tasks do not "know" about this fact and have no ways to determine the part of total execution.
      Specified by:
      noProgressVersion in interface ArrayContext
      Returns:
      the version of this context without progress support.
      See Also:
    • singleThreadVersion

      public ArrayContext singleThreadVersion()
      Description copied from interface: ArrayContext
      Returns new context, identical to this one with the only exception that the thread pool factory, returned by ArrayContext.getThreadPoolFactory() method, returns thisInstance.getThreadPoolFactory().singleThreadVersion().
      Specified by:
      singleThreadVersion in interface ArrayContext
      Returns:
      the single-thread version of this context.
    • multithreadingVersion

      public ArrayContext multithreadingVersion(int currentThreadIndex, int numberOfThreads)
      Description copied from interface: ArrayContext
      Returns new context, identical to this one with the only exception that ArrayContext.currentThreadIndex() and ArrayContext.numberOfThreads() methods in the result return the values, specified in the arguments currentThreadIndex and numberOfThreads.

      You can use this method, if you need to inform some algorithm, having own context (like ArrayProcessor), about the number of threads, which will simultaneously execute the same algorithm, and the index of thread, which really performs this algorithm. It can be necessary, for example, if an algorithm uses some external work memory, which must be unique in every thread.

      Note: this method may be used together with ArrayContext.singleThreadVersion(), for example:
          arrayContext.singleThreadVersion().multithreadingVersion(k,n).
      Really, there is usually no sense to allow using multithreading (creating thread pools by ThreadPoolFactory with more than 1 thread) in a thread, which is already called in a multithreading environment simultaneously with other threads.

      Specified by:
      multithreadingVersion in interface ArrayContext
      Parameters:
      currentThreadIndex - an index of the thread, which should be executed simultaneously with another threads; must be ≥0 and <numberOfThreads.
      numberOfThreads - the number of threads in a group of parallel threads; must be positive.
      Returns:
      the version of this context, considered to be used in the thread #currentThreadIndex in a group of numberOfThreads parallel threads.
    • customDataVersion

      public ArrayContext customDataVersion(Object customData)
      Description copied from interface: ArrayContext
      Returns new context, identical to this one with the only exception that ArrayContext.customData() method in the result returns the value, specified in the argument customData.

      You can use this method, if you need to inform some algorithm, having own context (like ArrayProcessor), about some additional details of the current execution process, which is not provided by other methods of this interface. For example: let's have some algorithm, processing some AlgART array, in a form of an abstract class or interface (implementing/extending ArrayProcessorWithContextSwitching) with the method
          process(Array arrayToProcess).
      Then, let's have a special application, where this algorithm is applied to a sequence of subarrays of another large array. It is very probable that your process method does not need to know, which subarray (from which position) is processed now, but if you still need this (maybe for debugging), you can pass this information via switching the context to the result of this method with an appropriate customData object.

      Specified by:
      customDataVersion in interface ArrayContext
      Parameters:
      customData - some custom data; null is an allowed value.
      Returns:
      the version of this context, where ArrayContext.customData() method returns the reference to customData argument.
    • getMemoryModel

      public abstract MemoryModel getMemoryModel()
      Description copied from interface: ArrayContext
      Returns the memory model that should be used for creating any instances of AlgART arrays. This method never returns null.
      Specified by:
      getMemoryModel in interface ArrayContext
      Returns:
      the desired memory model.
    • getThreadPoolFactory

      public abstract ThreadPoolFactory getThreadPoolFactory()
      Description copied from interface: ArrayContext
      Returns the thread pool factory that should be used for planning parallel execution in multithread methods alike Arrays.ParallelExecutor.process(). This method never returns null.
      Specified by:
      getThreadPoolFactory in interface ArrayContext
      Returns:
      the desired thread pool factory.
    • checkInterruption

      public abstract void checkInterruption() throws RuntimeException
      Description copied from interface: ArrayContext
      This method is called periodically by long-working methods alike Arrays.ParallelExecutor.process(). If this method throws some RuntimeException, the execution of all running threads is stopped and this exception is re-thrown. You may override this method to allow the user to interrupt the algorithm. Please note that this method may be called from several threads; so, you need to synchronize access to the returned flag.
      Specified by:
      checkInterruption in interface ArrayContext
      Throws:
      RuntimeException - (or some its subclass) if the application has requested to interrupt the currently executing module. This exception will lead to stopping all threads, started by multithread method alike copy, and will be re-thrown by that method.
    • updateProgress

      public abstract void updateProgress(ArrayContext.Event event)
      Description copied from interface: ArrayContext
      This method is called periodically by long-working methods alike Arrays.ParallelExecutor.process() with the argument, containing information about the execution progress. You may override this method to show the progress to the end user.

      This method may skip updating the corresponding visual element, if it is called too often, to avoid slowing down the program. However, it should update the visual element if ArrayContext.Event.readyPart() method returns 1.0.

      Specified by:
      updateProgress in interface ArrayContext
      Parameters:
      event - information about the execution progress.
    • checkInterruptionAndUpdateProgress

      public final void checkInterruptionAndUpdateProgress(Class<?> elementType, long readyCount, long length)
      Description copied from interface: ArrayContext
      Equivalent to 2 sequential calls: ArrayContext.checkInterruption() and updateProgress(new ArrayContext.Event(elementType, readyCount, length)).
      Specified by:
      checkInterruptionAndUpdateProgress in interface ArrayContext
      Parameters:
      elementType - the result of ArrayContext.Event.elementType() method in the event; may be null.
      readyCount - the only element in the result of ArrayContext.Event.readyCountPerTask() method in the event.
      length - the result of ArrayContext.Event.length() method in the created event.
    • currentThreadIndex

      public int currentThreadIndex()
      Description copied from interface: ArrayContext
      Usually returns 0, but in multithreading environment this method may return the index of the currently executing thread in a group of ArrayContext.numberOfThreads() parallel threads. This information can be useful, if you create a group of tasks (for example, with help of ThreadPoolFactory class), which are executed parallel in several threads (usually, to optimize calculations on multiprocessor or multi-core computers).

      To create a context, in which this method returns a value different than 0, please use ArrayContext.multithreadingVersion(int currentThreadIndex, int numberOfThreads) method.

      The result of this method always lies in 0..numberOfThreads()-1 range.

      In AbstractArrayContext implementation, this method returns 0.

      Specified by:
      currentThreadIndex in interface ArrayContext
      Returns:
      the index of the currently executing thread in a group of ArrayContext.numberOfThreads() parallel threads, or 0 if this feature is not used.
    • numberOfThreads

      public int numberOfThreads()
      Description copied from interface: ArrayContext
      Usually returns 1, but in multithreading environment this method may return the number of currently executing threads in some group of parallel threads (but not must: in most contexts it still returns 1 even in multithreading environment). This value is not the number of all executing threads and not the number of threads, which are really executing at this moment — it is the number of elements in some group of tasks (for example, created by ThreadPoolFactory class), which should be executed parallel in several threads (usually, to optimize calculations on multiprocessor or multi-core computers) and which should be distinguished via ArrayContext.currentThreadIndex() method. The main goal of this method is to estimate the maximal possible value of ArrayContext.currentThreadIndex().

      To create a context, in which this method returns a value different than 1, please use ArrayContext.multithreadingVersion(int currentThreadIndex, int numberOfThreads) method.

      The result of this method is always positive (≥1).

      In AbstractArrayContext implementation, this method returns 1.

      Specified by:
      numberOfThreads in interface ArrayContext
      Returns:
      the number of executing threads in a group of parallel threads, or 1 if this feature is not used.
    • customData

      public Object customData()
      Description copied from interface: ArrayContext
      Usually returns null, but in a special environment this method may return some custom object, containing additional information about the current execution context, not provided by other methods of this class.

      To create a context, in which this method returns a value different than null, please use ArrayContext.customDataVersion(Object) method.

      The result of this method may belong to any type. So, it is a good idea to check its type with instanceof operator before attempt to use this result.

      In AbstractArrayContext implementation, this method returns null.

      Specified by:
      customData in interface ArrayContext
      Returns:
      some custom information about the current execution environment.