Interface ArrayContext

All Known Implementing Classes:
AbstractArrayContext, DefaultArrayContext

public interface ArrayContext

The context of processing AlgART arrays. It is used by Arrays.ParallelExecutor class, Arrays.copy(ArrayContext, UpdatableArray, Array) method and some other methods of this and other packages, for example, Arrays.rangeOf(ArrayContext, PArray), Arrays.sumOf(ArrayContext, PArray), Arrays.preciseSumOf(ArrayContext, PFixedArray).

We recommend to use net.algart.contexts.DefaultArrayContext as an object implementing this interface.

Objects implementing this interface are usually immutable and thread-safe: there are no ways to modify settings of the created instance.

Author:
Daniel Alievsky
  • Field Details

  • Method Details

    • getSimpleContext

      static ArrayContext getSimpleContext(MemoryModel memoryModel, boolean multithreading)
      Creates the simplest implementation of ArrayContext with the only difference from the DEFAULT/DEFAULT_SINGLE_THREAD objects, that getMemoryModel() method will return the specified memory model. (If multithreading argument is true, the result will work as DEFAULT object, if false, it will work as DEFAULT_SINGLE_THREAD.)
      Parameters:
      memoryModel - memory model.
      multithreading - whether the returned context will use multithreading.
      Returns:
      new array context.
      Throws:
      NullPointerException - if the argument is null.
    • part

      ArrayContext part(double fromPart, double toPart)
      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 getMemoryModel(), getThreadPoolFactory(), 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 part(long, long, long) is more convenient.

      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.
      Throws:
      IllegalArgumentException - if fromPart or toPart is not in 0.0..1.0 range or if fromPart>toPart.
      See Also:
    • part

      ArrayContext part(long from, long to, long total)
      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)
       
      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.
      Throws:
      IllegalArgumentException - if from or to is not in 0..total range, or if from>to, or if total<0.
      See Also:
    • noProgressVersion

      ArrayContext noProgressVersion()
      Returns new context, identical to this one with the only exception that its 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.
      Returns:
      the version of this context without progress support.
      See Also:
    • singleThreadVersion

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

      ArrayContext multithreadingVersion(int currentThreadIndex, int numberOfThreads)
      Returns new context, identical to this one with the only exception that currentThreadIndex() and 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 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.

      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.
      Throws:
      IllegalArgumentException - if numberOfThreads≤0 or if currentThreadIndex does not lie in 0..numberOfThreads-1 range.
    • customDataVersion

      ArrayContext customDataVersion(Object customData)
      Returns new context, identical to this one with the only exception that 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.

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

      MemoryModel getMemoryModel()
      Returns the memory model that should be used for creating any instances of AlgART arrays. This method never returns null.
      Returns:
      the desired memory model.
    • getThreadPoolFactory

      ThreadPoolFactory getThreadPoolFactory()
      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.
      Returns:
      the desired thread pool factory.
    • checkInterruption

      void checkInterruption() throws RuntimeException
      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.
      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

      void updateProgress(ArrayContext.Event event)
      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.

      Parameters:
      event - information about the execution progress.
    • checkInterruptionAndUpdateProgress

      void checkInterruptionAndUpdateProgress(Class<?> elementType, long readyCount, long length)
      Equivalent to 2 sequential calls: checkInterruption() and updateProgress(new ArrayContext.Event(elementType, readyCount, length)).
      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

      int currentThreadIndex()
      Usually returns 0, but in multithreading environment this method may return the index of the currently executing thread in a group of 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 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.

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

      int numberOfThreads()
      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 currentThreadIndex() method. The main goal of this method is to estimate the maximal possible value of currentThreadIndex().

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

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

      In AbstractArrayContext implementation, this method returns 1.

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

      Object customData()
      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 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.

      Returns:
      some custom information about the current execution environment.