Class CachingRemoteIterator<T>

Type Parameters:
T - The type of the elements that are retrieved from the cached iterator.
All Implemented Interfaces:
RemoteIterator<List<T>>, de.aristaflow.adept2.model.communication.ServerSideProxy, de.aristaflow.adept2.model.communication.TimeTrackingSsProxy, Closeable, AutoCloseable

public class CachingRemoteIterator<T> extends AbstractTimeTrackingRemoteIterator<T>
This iterator implements a cache for the underlying iterator, that is, when iterating via AbstractRemoteIterator.getNext(int), all retrieved elements will be cached. Previous elements will always be retrieved from the cache. Note that a positioned next will add enough elements to the cache to fulfil the request. As soon as all elements have been retrieved, the wrapped remote iterator will be closed.
It has an expiring alive time thus allowing to release the occupied memory even if no explicit close() occurs. This alive time is kept in sync with the underlying iterator until all elements have been retrieved (and are thus cached).
  • Field Details

    • wrappedIterator

      protected RemoteIterator<List<T>> wrappedIterator
      The wrapped iterator of which all elements will be cached. Note that the current cursor need not correspond to the current cursor of the underlying iterator. This will be null when the wrapped iterator has been closed.
    • elements

      protected List<T> elements
      The elements that have been retrieved from the underlying remote iterator so far. null indicates that this caching remote iterator has been closed.
    • lastCached

      protected int lastCached
      The index of the last element that is in the cache. This corresponds to the current index of the wrapped iterator.
    • last

      protected int last
      The index of last element in case it has been reached in the result set, -1 otherwise.
    • current

      protected int current
      The reference to the current element which is to be retrieved next.
  • Constructor Details

    • CachingRemoteIterator

      @Deprecated(since="15.0.0", forRemoval=true) public CachingRemoteIterator(RemoteIterator<List<T>> wrappedIterator)
      Deprecated, for removal: This API element is subject to removal in a future version.
      Creates a new caching remote iterator for the designated iterator sending no close notification for the wrapped iterator.
      Parameters:
      wrappedIterator - The iterator of which the elements should be cached as soon as they are iterated (with AbstractRemoteIterator.getNext(int)).
    • CachingRemoteIterator

      public CachingRemoteIterator(RemoteIterator<List<T>> wrappedIterator, long aliveTime, long aliveTimeExtension, Logger logger)
      Creates a new caching remote iterator for the designated iterator.
      Parameters:
      wrappedIterator - The iterator of which the elements should be cached as soon as they are iterated (with AbstractRemoteIterator.getNext(int)).
      aliveTime - The time in milliseconds this remote iterator is alive.
      aliveTimeExtension - The time in milliseconds to extend the alive time when accessing this remote iterator.
      logger - The logger for logging exceptions from the wrapped remote iterator that cannot be forwarded or are irrelevant.
  • Method Details

    • exit

      protected Long exit()
      Tracks exiting a method reentrant which is removing an invocation of the current thread to properly set AbstractTimeTrackingRemoteIterator.isBusy(). If the thread leaves completely, the alive time will be extended; it will not be shortened in case the extension is less than the already set close time. If this remote iterator has been closed, no extension will take place. As long as the wrapped remote iterator is alive, we need to keep it alive since we may need to retrieve data that is not in the cache yet. Otherwise going to previous elements will not extend the alive time of the wrapped iterator but extend the alive time of the caching remote iterator.
      Overrides:
      exit in class AbstractTimeTrackingRemoteIterator<T>
      Returns:
      The possibly new remaining alive time in milliseconds or null in case the thread is still active and not exiting finally.
    • isClosed

      protected boolean isClosed()
      Description copied from class: AbstractRemoteIterator
      Gets whether this remote iterator has been closed and its data is not available any more.
      Specified by:
      isClosed in class AbstractRemoteIterator<T,T>
      Returns:
      Whether this remote iterator has been closed and its data is not available any more.
    • getNextImpl

      protected List<T> getNextImpl(int count) throws DataSourceException, DataConsistencyException
      Description copied from class: AbstractRemoteIterator
      Implements AbstractRemoteIterator.getNext(int) without the need to consider result transformation, closeable and alive time tracking.
      Specified by:
      getNextImpl in class AbstractRemoteIterator<T,T>
      Throws:
      DataSourceException
      DataConsistencyException
    • getNextImpl

      protected List<T> getNextImpl(int count, int start) throws DataSourceException, DataConsistencyException
      Description copied from class: AbstractRemoteIterator
      Implements AbstractRemoteIterator.getNext(int, int) without the need to consider result transformation, closeable and alive time tracking.
      Specified by:
      getNextImpl in class AbstractRemoteIterator<T,T>
      Throws:
      DataSourceException
      DataConsistencyException
    • getPreviousImpl

      protected List<T> getPreviousImpl(int count) throws DataSourceException, DataConsistencyException
      Description copied from class: AbstractRemoteIterator
      Implements AbstractRemoteIterator.getPrevious(int) without the need to consider result transformation, closeable and alive time tracking.
      Specified by:
      getPreviousImpl in class AbstractRemoteIterator<T,T>
      Throws:
      DataSourceException
      DataConsistencyException
    • getAllImpl

      protected List<T> getAllImpl() throws DataSourceException, DataConsistencyException
      Description copied from class: AbstractRemoteIterator
      Implements AbstractRemoteIterator.getAll() without the need to consider result transformation, closeable and alive time tracking.
      Specified by:
      getAllImpl in class AbstractRemoteIterator<T,T>
      Throws:
      DataSourceException
      DataConsistencyException
    • getSnapshotImpl

      protected boolean getSnapshotImpl() throws DataSourceException
      Description copied from class: AbstractTimeTrackingRemoteIterator
      Gets whether this iterator is a snapshot and therefore its contents is not subject of change while iterating.
      This method will need to be overridden if the snapshot status cannot be provided when creating this instance (AbstractTimeTrackingRemoteIterator(boolean, boolean, long, long, Logger)).

      This implementation always throws an UnsupportedOperationException.

      Overrides:
      getSnapshotImpl in class AbstractTimeTrackingRemoteIterator<T>
      Returns:
      Whether this iterator is a snapshot and therefore its contents is not subject of change while iterating.
      Throws:
      DataSourceException - If there are problems retrieving the snapshot status of this remote iterator, a DataSourceException will be thrown.
    • getRemainingAliveTime

      public long getRemainingAliveTime()
      Description copied from interface: RemoteIterator
      Gets the time in milliseconds this iterator will still be valid and does allow access to the underlying data. Afterwards the iterator will be closed automatically to save memory and resources.
      A negative value indicates a closed iterator. Such an iterator cannot be kept alive. Note that this alive time does not need to correspond to the original alive time requested
      Specified by:
      getRemainingAliveTime in interface RemoteIterator<T>
      Specified by:
      getRemainingAliveTime in interface de.aristaflow.adept2.model.communication.ServerSideProxy
      Specified by:
      getRemainingAliveTime in interface de.aristaflow.adept2.model.communication.TimeTrackingSsProxy
      Overrides:
      getRemainingAliveTime in class AbstractTimeTrackingRemoteIterator<T>
      Returns:
      The time this iterator remains valid and can be used. Afterwards the iterator will be closed. Long.MIN_VALUE for an already closed remote iterator.
    • keepAlive

      public long keepAlive(long aliveTime) throws IOException
      Description copied from interface: RemoteIterator
      Keeps this iterator alive for the designated time span (in milliseconds). This allows to continue using this iterator. However, note that extending the usage time significantly impacts resource occupation.
      Note that extending the time need not be successful. The underlying iterator implementation may not be able to extend the alive time of all used resource, for instance pooled database connections.

      A 0 or a negative value is equal to closed this iterator.

      Specified by:
      keepAlive in interface RemoteIterator<T>
      Specified by:
      keepAlive in interface de.aristaflow.adept2.model.communication.ServerSideProxy
      Specified by:
      keepAlive in interface de.aristaflow.adept2.model.communication.TimeTrackingSsProxy
      Overrides:
      keepAlive in class AbstractTimeTrackingRemoteIterator<T>
      Parameters:
      aliveTime - The time in milliseconds to keep this iterator alive that is not to close it automatically.
      Returns:
      The relative time this iterator will be kept alive longer. 0 indicates immediate closing. A negative value represents the failure of extending the alive time, check RemoteIterator.getRemainingAliveTime() in this case whether extending the keep alive time has been successful or not.
      Throws:
      IOException - If there are problems accessing the underlying data source, an IOException will be thrown.
    • close

      public void close() throws IOException
      Description copied from interface: RemoteIterator
      Explicitly closes this iterator which allows to release occupied memory and resources. Closing will be done implicitly after the alive time has elapsed.
      This method may be called several times. Implementors have to take care of this.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Specified by:
      close in interface RemoteIterator<T>
      Specified by:
      close in interface de.aristaflow.adept2.model.communication.ServerSideProxy
      Overrides:
      close in class AbstractRemoteIterator<T,T>
      Throws:
      IOException - If there are problems accessing the underlying data source, an IOException will be thrown.
    • closeWrappedIoe

      protected void closeWrappedIoe(boolean keepAlive) throws IOException
      closeWrappedException(boolean) closing this iterator implicitly and wrapping a DataSourceException in a IOException or unwrapping a IOException from an DataSourceException if appropriate.
      Parameters:
      keepAlive - Whether to keep this caching remote iterator alive despite the wrapped iterator being closed.
      Throws:
      IOException - If there are problems accessing the underlying data source, an IOException will be thrown.
    • closeWrappedDse

      protected void closeWrappedDse() throws DataSourceException
      closeWrappedException(boolean) keeping this iterator alive and wrapping IOException in a DataSourceException or unwrapping a DataSourceException from an IOException if appropriate.
      Throws:
      DataSourceException - If there are problems accessing the underlying data source, a DataSourceException will be thrown.