A {@code Workspace} implementation taking advantage of NRT Lucene features.{@code IndexReader} instances are obtained directly from the {@code IndexWriter}, which is not forced to flush all pending changes to the {@code Directory} structure.
Lucene requires in its current version to flush delete operations, or the {@code IndexReader}s retrieved via NRT will include deleted Document instances in queries; flushing delete operations happens to be quite expensive so this {@code Workspace} implementation attempts to detect when sucha flush operation is needed.
Applying write operations flags "indexReader requirements" with needs for either normal flush or flush including deletes, but does not update {@code IndexReader} instances. The {@code IndexReader}s are updated only if and when a fresh {@code IndexReader} is requested via {@link #openIndexReader()}. This method will check if it can return the last opened {@code IndexReader} or in case of the reader being staleopen a fresh reader from the current {@code IndexWriter}.
Generation counters are used to track need-at-least version versus last-updated-at version: shared state is avoided between index writers and reader threads to avoid high complexity. The method {@link #afterTransactionApplied(boolean,boolean)} might trigger multiple times flaggingthe index to be dirty without triggering an actual {@code IndexReader} refresh, so the version counterscan have gaps: method {@link #refreshReaders()} will always jump to latest seen version, as it willrefresh the index to satisfy both kinds of flush requirements (writes and deletes).
We keep a reference {@code IndexReader} in the {@link #currentReader} atomic reference as a fast pathfor multiple read events when the index is not dirty.
This class implements both {@code Workspace} and {@code ReaderProvider}.
@author Sanne Grinovero
(C) 2011 Red Hat Inc.