Class ReferenceManager<G>

java.lang.Object
org.apache.lucene.search.ReferenceManager<G>
Type Parameters:
G - the concrete type that will be acquired and released.
All Implemented Interfaces:
Closeable, AutoCloseable
Direct Known Subclasses:
ReaderManager, SearcherManager

public abstract class ReferenceManager<G> extends Object implements Closeable
Utility class to safely share instances of a certain type across multiple threads, while periodically refreshing them. This class ensures each reference is closed only once all threads have finished using it. It is recommended to consult the documentation of ReferenceManager implementations for their maybeRefresh() semantics.
WARNING: This API is experimental and might change in incompatible ways in the next release.
  • Field Details

    • current

      protected volatile G current
  • Constructor Details

    • ReferenceManager

      public ReferenceManager()
  • Method Details

    • decRef

      protected abstract void decRef(G reference) throws IOException
      Decrement reference counting on the given reference.
      Throws:
      IOException - if reference decrement on the given resource failed.
    • refreshIfNeeded

      protected abstract G refreshIfNeeded(G referenceToRefresh) throws IOException
      Refresh the given reference if needed. Returns null if no refresh was needed, otherwise a new refreshed reference.
      Throws:
      AlreadyClosedException - if the reference manager has been closed.
      IOException - if the refresh operation failed
    • tryIncRef

      protected abstract boolean tryIncRef(G reference) throws IOException
      Try to increment reference counting on the given reference. Return true if the operation was successful.
      Throws:
      AlreadyClosedException - if the reference manager has been closed.
      IOException
    • acquire

      public final G acquire() throws IOException
      Obtain the current reference. You must match every call to acquire with one call to release(G); it's best to do so in a finally clause, and set the reference to null to prevent accidental usage after it has been released.
      Throws:
      AlreadyClosedException - if the reference manager has been closed.
      IOException
    • close

      public final void close() throws IOException
      Closes this ReferenceManager to prevent future acquiring. A reference manager should be closed if the reference to the managed resource should be disposed or the application using the ReferenceManager is shutting down. The managed resource might not be released immediately, if the ReferenceManager user is holding on to a previously acquired reference. The resource will be released once when the last reference is released. Those references can still be used as if the manager was still active.

      Applications should not acquire new references from this manager once this method has been called. Acquiring a resource on a closed ReferenceManager will throw an AlreadyClosedException.

      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException - if the underlying reader of the current reference could not be closed
    • getRefCount

      protected abstract int getRefCount(G reference)
      Returns the current reference count of the given reference.
    • afterClose

      protected void afterClose() throws IOException
      Called after close(), so subclass can free any resources.
      Throws:
      IOException - if the after close operation in a sub-class throws an IOException
    • maybeRefresh

      public final boolean maybeRefresh() throws IOException
      You must call this (or maybeRefreshBlocking()), periodically, if you want that acquire() will return refreshed instances.

      Threads: it's fine for more than one thread to call this at once. Only the first thread will attempt the refresh; subsequent threads will see that another thread is already handling refresh and will return immediately. Note that this means if another thread is already refreshing then subsequent threads will return right away without waiting for the refresh to complete.

      If this method returns true it means the calling thread either refreshed or that there were no changes to refresh. If it returns false it means another thread is currently refreshing.

      Throws:
      IOException - if refreshing the resource causes an IOException
      AlreadyClosedException - if the reference manager has been closed.
    • maybeRefreshBlocking

      public final void maybeRefreshBlocking() throws IOException
      You must call this (or maybeRefresh()), periodically, if you want that acquire() will return refreshed instances.

      Threads: unlike maybeRefresh(), if another thread is currently refreshing, this method blocks until that thread completes. It is useful if you want to guarantee that the next call to acquire() will return a refreshed instance. Otherwise, consider using the non-blocking maybeRefresh().

      Throws:
      IOException - if refreshing the resource causes an IOException
      AlreadyClosedException - if the reference manager has been closed.
    • afterMaybeRefresh

      protected void afterMaybeRefresh() throws IOException
      Called after a refresh was attempted, regardless of whether a new reference was in fact created.
      Throws:
      IOException - if a low level I/O exception occurs
    • release

      public final void release(G reference) throws IOException
      Release the reference previously obtained via acquire().

      NOTE: it's safe to call this after close().

      Throws:
      IOException - if the release operation on the given resource throws an IOException
    • addListener

      public void addListener(ReferenceManager.RefreshListener listener)
      Adds a listener, to be notified when a reference is refreshed/swapped.
    • removeListener

      public void removeListener(ReferenceManager.RefreshListener listener)
      Remove a listener added with addListener(RefreshListener).