+++ /dev/null
-package org.apache.lucene.index;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.FieldSelector;
-import org.apache.lucene.search.FieldCache; // javadocs
-import org.apache.lucene.search.Similarity;
-import org.apache.lucene.store.*;
-import org.apache.lucene.util.ArrayUtil;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.Closeable;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/** IndexReader is an abstract class, providing an interface for accessing an
- index. Search of an index is done entirely through this abstract interface,
- so that any subclass which implements it is searchable.
-
- <p> Concrete subclasses of IndexReader are usually constructed with a call to
- one of the static <code>open()</code> methods, e.g. {@link
- #open(Directory, boolean)}.
-
- <p> For efficiency, in this API documents are often referred to via
- <i>document numbers</i>, non-negative integers which each name a unique
- document in the index. These document numbers are ephemeral--they may change
- as documents are added to and deleted from an index. Clients should thus not
- rely on a given document having the same number between sessions.
-
- <p> An IndexReader can be opened on a directory for which an IndexWriter is
- opened already, but it cannot be used to delete documents from the index then.
-
- <p>
- <b>NOTE</b>: for backwards API compatibility, several methods are not listed
- as abstract, but have no useful implementations in this base class and
- instead always throw UnsupportedOperationException. Subclasses are
- strongly encouraged to override these methods, but in many cases may not
- need to.
- </p>
-
- <p>
-
- <b>NOTE</b>: as of 2.4, it's possible to open a read-only
- IndexReader using the static open methods that accept the
- boolean readOnly parameter. Such a reader has better
- concurrency as it's not necessary to synchronize on the
- isDeleted method. You must specify false if you want to
- make changes with the resulting IndexReader.
- </p>
-
- <a name="thread-safety"></a><p><b>NOTE</b>: {@link
- IndexReader} instances are completely thread
- safe, meaning multiple threads can call any of its methods,
- concurrently. If your application requires external
- synchronization, you should <b>not</b> synchronize on the
- <code>IndexReader</code> instance; use your own
- (non-Lucene) objects instead.
-*/
-public abstract class IndexReader implements Cloneable,Closeable {
-
- /**
- * A custom listener that's invoked when the IndexReader
- * is finished.
- *
- * <p>For a SegmentReader, this listener is called only
- * once all SegmentReaders sharing the same core are
- * closed. At this point it is safe for apps to evict
- * this reader from any caches keyed on {@link
- * #getCoreCacheKey}. This is the same interface that
- * {@link FieldCache} uses, internally, to evict
- * entries.</p>
- *
- * <p>For other readers, this listener is called when they
- * are closed.</p>
- *
- * @lucene.experimental
- */
- public static interface ReaderFinishedListener {
- public void finished(IndexReader reader);
- }
-
- // Impls must set this if they may call add/removeReaderFinishedListener:
- protected volatile Collection<ReaderFinishedListener> readerFinishedListeners;
-
- /** Expert: adds a {@link ReaderFinishedListener}. The
- * provided listener is also added to any sub-readers, if
- * this is a composite reader. Also, any reader reopened
- * or cloned from this one will also copy the listeners at
- * the time of reopen.
- *
- * @lucene.experimental */
- public void addReaderFinishedListener(ReaderFinishedListener listener) {
- readerFinishedListeners.add(listener);
- }
-
- /** Expert: remove a previously added {@link ReaderFinishedListener}.
- *
- * @lucene.experimental */
- public void removeReaderFinishedListener(ReaderFinishedListener listener) {
- readerFinishedListeners.remove(listener);
- }
-
- protected void notifyReaderFinishedListeners() {
- // Defensive (should never be null -- all impls must set
- // this):
- if (readerFinishedListeners != null) {
- for(ReaderFinishedListener listener : readerFinishedListeners) {
- listener.finished(this);
- }
- }
- }
-
- protected void readerFinished() {
- notifyReaderFinishedListeners();
- }
-
- /**
- * Constants describing field properties, for example used for
- * {@link IndexReader#getFieldNames(FieldOption)}.
- */
- public static enum FieldOption {
- /** All fields */
- ALL,
- /** All indexed fields */
- INDEXED,
- /** All fields that store payloads */
- STORES_PAYLOADS,
- /** All fields that omit tf */
- OMIT_TERM_FREQ_AND_POSITIONS,
- /** All fields that omit positions */
- OMIT_POSITIONS,
- /** All fields which are not indexed */
- UNINDEXED,
- /** All fields which are indexed with termvectors enabled */
- INDEXED_WITH_TERMVECTOR,
- /** All fields which are indexed but don't have termvectors enabled */
- INDEXED_NO_TERMVECTOR,
- /** All fields with termvectors enabled. Please note that only standard termvector fields are returned */
- TERMVECTOR,
- /** All fields with termvectors with position values enabled */
- TERMVECTOR_WITH_POSITION,
- /** All fields with termvectors with offset values enabled */
- TERMVECTOR_WITH_OFFSET,
- /** All fields with termvectors with offset values and position values enabled */
- TERMVECTOR_WITH_POSITION_OFFSET,
- }
-
- private boolean closed;
- protected boolean hasChanges;
-
- private final AtomicInteger refCount = new AtomicInteger();
-
- static int DEFAULT_TERMS_INDEX_DIVISOR = 1;
-
- /** Expert: returns the current refCount for this reader */
- public int getRefCount() {
- return refCount.get();
- }
-
- /**
- * Expert: increments the refCount of this IndexReader
- * instance. RefCounts are used to determine when a
- * reader can be closed safely, i.e. as soon as there are
- * no more references. Be sure to always call a
- * corresponding {@link #decRef}, in a finally clause;
- * otherwise the reader may never be closed. Note that
- * {@link #close} simply calls decRef(), which means that
- * the IndexReader will not really be closed until {@link
- * #decRef} has been called for all outstanding
- * references.
- *
- * @see #decRef
- */
- public void incRef() {
- ensureOpen();
- refCount.incrementAndGet();
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- final StringBuilder buffer = new StringBuilder();
- if (hasChanges) {
- buffer.append('*');
- }
- buffer.append(getClass().getSimpleName());
- buffer.append('(');
- final IndexReader[] subReaders = getSequentialSubReaders();
- if ((subReaders != null) && (subReaders.length > 0)) {
- buffer.append(subReaders[0]);
- for (int i = 1; i < subReaders.length; ++i) {
- buffer.append(" ").append(subReaders[i]);
- }
- }
- buffer.append(')');
- return buffer.toString();
- }
-
- /**
- * Expert: decreases the refCount of this IndexReader
- * instance. If the refCount drops to 0, then pending
- * changes (if any) are committed to the index and this
- * reader is closed. If an exception is hit, the refCount
- * is unchanged.
- *
- * @throws IOException in case an IOException occurs in commit() or doClose()
- *
- * @see #incRef
- */
- public void decRef() throws IOException {
- ensureOpen();
- if (refCount.getAndDecrement() == 1) {
- boolean success = false;
- try {
- commit();
- doClose();
- success = true;
- } finally {
- if (!success) {
- // Put reference back on failure
- refCount.incrementAndGet();
- }
- }
- readerFinished();
- }
- }
-
- protected IndexReader() {
- refCount.set(1);
- }
-
- /**
- * @throws AlreadyClosedException if this IndexReader is closed
- */
- protected final void ensureOpen() throws AlreadyClosedException {
- if (refCount.get() <= 0) {
- throw new AlreadyClosedException("this IndexReader is closed");
- }
- }
-
- /** Returns a IndexReader reading the index in the given
- * Directory, with readOnly=true.
- * @param directory the index directory
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static IndexReader open(final Directory directory) throws CorruptIndexException, IOException {
- return open(directory, null, null, true, DEFAULT_TERMS_INDEX_DIVISOR);
- }
-
- /** Returns an IndexReader reading the index in the given
- * Directory. You should pass readOnly=true, since it
- * gives much better concurrent performance, unless you
- * intend to do write operations (delete documents or
- * change norms) with the reader.
- * @param directory the index directory
- * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static IndexReader open(final Directory directory, boolean readOnly) throws CorruptIndexException, IOException {
- return open(directory, null, null, readOnly, DEFAULT_TERMS_INDEX_DIVISOR);
- }
-
- /**
- * Open a near real time IndexReader from the {@link org.apache.lucene.index.IndexWriter}.
- *
- * @param writer The IndexWriter to open from
- * @param applyAllDeletes If true, all buffered deletes will
- * be applied (made visible) in the returned reader. If
- * false, the deletes are not applied but remain buffered
- * (in IndexWriter) so that they will be applied in the
- * future. Applying deletes can be costly, so if your app
- * can tolerate deleted documents being returned you might
- * gain some performance by passing false.
- * @return The new IndexReader
- * @throws CorruptIndexException
- * @throws IOException if there is a low-level IO error
- *
- * @see #reopen(IndexWriter,boolean)
- *
- * @lucene.experimental
- */
- public static IndexReader open(final IndexWriter writer, boolean applyAllDeletes) throws CorruptIndexException, IOException {
- return writer.getReader(applyAllDeletes);
- }
-
- /** Expert: returns an IndexReader reading the index in the given
- * {@link IndexCommit}. You should pass readOnly=true, since it
- * gives much better concurrent performance, unless you
- * intend to do write operations (delete documents or
- * change norms) with the reader.
- * @param commit the commit point to open
- * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static IndexReader open(final IndexCommit commit, boolean readOnly) throws CorruptIndexException, IOException {
- return open(commit.getDirectory(), null, commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR);
- }
-
- /** Expert: returns an IndexReader reading the index in
- * the given Directory, with a custom {@link
- * IndexDeletionPolicy}. You should pass readOnly=true,
- * since it gives much better concurrent performance,
- * unless you intend to do write operations (delete
- * documents or change norms) with the reader.
- * @param directory the index directory
- * @param deletionPolicy a custom deletion policy (only used
- * if you use this reader to perform deletes or to set
- * norms); see {@link IndexWriter} for details.
- * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static IndexReader open(final Directory directory, IndexDeletionPolicy deletionPolicy, boolean readOnly) throws CorruptIndexException, IOException {
- return open(directory, deletionPolicy, null, readOnly, DEFAULT_TERMS_INDEX_DIVISOR);
- }
-
- /** Expert: returns an IndexReader reading the index in
- * the given Directory, with a custom {@link
- * IndexDeletionPolicy}. You should pass readOnly=true,
- * since it gives much better concurrent performance,
- * unless you intend to do write operations (delete
- * documents or change norms) with the reader.
- * @param directory the index directory
- * @param deletionPolicy a custom deletion policy (only used
- * if you use this reader to perform deletes or to set
- * norms); see {@link IndexWriter} for details.
- * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader
- * @param termInfosIndexDivisor Subsamples which indexed
- * terms are loaded into RAM. This has the same effect as {@link
- * IndexWriter#setTermIndexInterval} except that setting
- * must be done at indexing time while this setting can be
- * set per reader. When set to N, then one in every
- * N*termIndexInterval terms in the index is loaded into
- * memory. By setting this to a value > 1 you can reduce
- * memory usage, at the expense of higher latency when
- * loading a TermInfo. The default value is 1. Set this
- * to -1 to skip loading the terms index entirely.
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static IndexReader open(final Directory directory, IndexDeletionPolicy deletionPolicy, boolean readOnly, int termInfosIndexDivisor) throws CorruptIndexException, IOException {
- return open(directory, deletionPolicy, null, readOnly, termInfosIndexDivisor);
- }
-
- /** Expert: returns an IndexReader reading the index in
- * the given Directory, using a specific commit and with
- * a custom {@link IndexDeletionPolicy}. You should pass
- * readOnly=true, since it gives much better concurrent
- * performance, unless you intend to do write operations
- * (delete documents or change norms) with the reader.
- * @param commit the specific {@link IndexCommit} to open;
- * see {@link IndexReader#listCommits} to list all commits
- * in a directory
- * @param deletionPolicy a custom deletion policy (only used
- * if you use this reader to perform deletes or to set
- * norms); see {@link IndexWriter} for details.
- * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static IndexReader open(final IndexCommit commit, IndexDeletionPolicy deletionPolicy, boolean readOnly) throws CorruptIndexException, IOException {
- return open(commit.getDirectory(), deletionPolicy, commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR);
- }
-
- /** Expert: returns an IndexReader reading the index in
- * the given Directory, using a specific commit and with
- * a custom {@link IndexDeletionPolicy}. You should pass
- * readOnly=true, since it gives much better concurrent
- * performance, unless you intend to do write operations
- * (delete documents or change norms) with the reader.
- * @param commit the specific {@link IndexCommit} to open;
- * see {@link IndexReader#listCommits} to list all commits
- * in a directory
- * @param deletionPolicy a custom deletion policy (only used
- * if you use this reader to perform deletes or to set
- * norms); see {@link IndexWriter} for details.
- * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader
- * @param termInfosIndexDivisor Subsamples which indexed
- * terms are loaded into RAM. This has the same effect as {@link
- * IndexWriter#setTermIndexInterval} except that setting
- * must be done at indexing time while this setting can be
- * set per reader. When set to N, then one in every
- * N*termIndexInterval terms in the index is loaded into
- * memory. By setting this to a value > 1 you can reduce
- * memory usage, at the expense of higher latency when
- * loading a TermInfo. The default value is 1. Set this
- * to -1 to skip loading the terms index entirely. This is only useful in
- * advanced situations when you will only .next() through all terms;
- * attempts to seek will hit an exception.
- *
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static IndexReader open(final IndexCommit commit, IndexDeletionPolicy deletionPolicy, boolean readOnly, int termInfosIndexDivisor) throws CorruptIndexException, IOException {
- return open(commit.getDirectory(), deletionPolicy, commit, readOnly, termInfosIndexDivisor);
- }
-
- private static IndexReader open(final Directory directory, final IndexDeletionPolicy deletionPolicy, final IndexCommit commit, final boolean readOnly, int termInfosIndexDivisor) throws CorruptIndexException, IOException {
- return DirectoryReader.open(directory, deletionPolicy, commit, readOnly, termInfosIndexDivisor);
- }
-
- /**
- * Refreshes an IndexReader if the index has changed since this instance
- * was (re)opened.
- * <p>
- * Opening an IndexReader is an expensive operation. This method can be used
- * to refresh an existing IndexReader to reduce these costs. This method
- * tries to only load segments that have changed or were created after the
- * IndexReader was (re)opened.
- * <p>
- * If the index has not changed since this instance was (re)opened, then this
- * call is a NOOP and returns this instance. Otherwise, a new instance is
- * returned. The old instance is <b>not</b> closed and remains usable.<br>
- * <p>
- * If the reader is reopened, even though they share
- * resources internally, it's safe to make changes
- * (deletions, norms) with the new reader. All shared
- * mutable state obeys "copy on write" semantics to ensure
- * the changes are not seen by other readers.
- * <p>
- * You can determine whether a reader was actually reopened by comparing the
- * old instance with the instance returned by this method:
- * <pre>
- * IndexReader reader = ...
- * ...
- * IndexReader newReader = r.reopen();
- * if (newReader != reader) {
- * ... // reader was reopened
- * reader.close();
- * }
- * reader = newReader;
- * ...
- * </pre>
- *
- * Be sure to synchronize that code so that other threads,
- * if present, can never use reader after it has been
- * closed and before it's switched to newReader.
- *
- * <p><b>NOTE</b>: If this reader is a near real-time
- * reader (obtained from {@link IndexWriter#getReader()},
- * reopen() will simply call writer.getReader() again for
- * you, though this may change in the future.
- *
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public synchronized IndexReader reopen() throws CorruptIndexException, IOException {
- throw new UnsupportedOperationException("This reader does not support reopen().");
- }
-
-
- /** Just like {@link #reopen()}, except you can change the
- * readOnly of the original reader. If the index is
- * unchanged but readOnly is different then a new reader
- * will be returned. */
- public synchronized IndexReader reopen(boolean openReadOnly) throws CorruptIndexException, IOException {
- throw new UnsupportedOperationException("This reader does not support reopen().");
- }
-
- /** Expert: reopen this reader on a specific commit point.
- * This always returns a readOnly reader. If the
- * specified commit point matches what this reader is
- * already on, and this reader is already readOnly, then
- * this same instance is returned; if it is not already
- * readOnly, a readOnly clone is returned. */
- public synchronized IndexReader reopen(final IndexCommit commit) throws CorruptIndexException, IOException {
- throw new UnsupportedOperationException("This reader does not support reopen(IndexCommit).");
- }
-
- /**
- * Expert: returns a readonly reader, covering all
- * committed as well as un-committed changes to the index.
- * This provides "near real-time" searching, in that
- * changes made during an IndexWriter session can be
- * quickly made available for searching without closing
- * the writer nor calling {@link #commit}.
- *
- * <p>Note that this is functionally equivalent to calling
- * {#flush} (an internal IndexWriter operation) and then using {@link IndexReader#open} to
- * open a new reader. But the turnaround time of this
- * method should be faster since it avoids the potentially
- * costly {@link #commit}.</p>
- *
- * <p>You must close the {@link IndexReader} returned by
- * this method once you are done using it.</p>
- *
- * <p>It's <i>near</i> real-time because there is no hard
- * guarantee on how quickly you can get a new reader after
- * making changes with IndexWriter. You'll have to
- * experiment in your situation to determine if it's
- * fast enough. As this is a new and experimental
- * feature, please report back on your findings so we can
- * learn, improve and iterate.</p>
- *
- * <p>The resulting reader supports {@link
- * IndexReader#reopen}, but that call will simply forward
- * back to this method (though this may change in the
- * future).</p>
- *
- * <p>The very first time this method is called, this
- * writer instance will make every effort to pool the
- * readers that it opens for doing merges, applying
- * deletes, etc. This means additional resources (RAM,
- * file descriptors, CPU time) will be consumed.</p>
- *
- * <p>For lower latency on reopening a reader, you should
- * call {@link IndexWriterConfig#setMergedSegmentWarmer} to
- * pre-warm a newly merged segment before it's committed
- * to the index. This is important for minimizing
- * index-to-search delay after a large merge. </p>
- *
- * <p>If an addIndexes* call is running in another thread,
- * then this reader will only search those segments from
- * the foreign index that have been successfully copied
- * over, so far</p>.
- *
- * <p><b>NOTE</b>: Once the writer is closed, any
- * outstanding readers may continue to be used. However,
- * if you attempt to reopen any of those readers, you'll
- * hit an {@link AlreadyClosedException}.</p>
- *
- * @return IndexReader that covers entire index plus all
- * changes made so far by this IndexWriter instance
- *
- * @param writer The IndexWriter to open from
- * @param applyAllDeletes If true, all buffered deletes will
- * be applied (made visible) in the returned reader. If
- * false, the deletes are not applied but remain buffered
- * (in IndexWriter) so that they will be applied in the
- * future. Applying deletes can be costly, so if your app
- * can tolerate deleted documents being returned you might
- * gain some performance by passing false.
- *
- * @throws IOException
- *
- * @lucene.experimental
- */
- public IndexReader reopen(IndexWriter writer, boolean applyAllDeletes) throws CorruptIndexException, IOException {
- return writer.getReader(applyAllDeletes);
- }
-
- /**
- * Efficiently clones the IndexReader (sharing most
- * internal state).
- * <p>
- * On cloning a reader with pending changes (deletions,
- * norms), the original reader transfers its write lock to
- * the cloned reader. This means only the cloned reader
- * may make further changes to the index, and commit the
- * changes to the index on close, but the old reader still
- * reflects all changes made up until it was cloned.
- * <p>
- * Like {@link #reopen()}, it's safe to make changes to
- * either the original or the cloned reader: all shared
- * mutable state obeys "copy on write" semantics to ensure
- * the changes are not seen by other readers.
- * <p>
- */
- @Override
- public synchronized Object clone() {
- throw new UnsupportedOperationException("This reader does not implement clone()");
- }
-
- /**
- * Clones the IndexReader and optionally changes readOnly. A readOnly
- * reader cannot open a writeable reader.
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public synchronized IndexReader clone(boolean openReadOnly) throws CorruptIndexException, IOException {
- throw new UnsupportedOperationException("This reader does not implement clone()");
- }
-
- /**
- * Returns the directory associated with this index. The Default
- * implementation returns the directory specified by subclasses when
- * delegating to the IndexReader(Directory) constructor, or throws an
- * UnsupportedOperationException if one was not specified.
- * @throws UnsupportedOperationException if no directory
- */
- public Directory directory() {
- ensureOpen();
- throw new UnsupportedOperationException("This reader does not support this method.");
- }
-
- /**
- * Returns the time the index in the named directory was last modified.
- * Do not use this to check whether the reader is still up-to-date, use
- * {@link #isCurrent()} instead.
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static long lastModified(final Directory directory2) throws CorruptIndexException, IOException {
- return ((Long) new SegmentInfos.FindSegmentsFile(directory2) {
- @Override
- public Object doBody(String segmentFileName) throws IOException {
- return Long.valueOf(directory2.fileModified(segmentFileName));
- }
- }.run()).longValue();
- }
-
- /**
- * Reads version number from segments files. The version number is
- * initialized with a timestamp and then increased by one for each change of
- * the index.
- *
- * @param directory where the index resides.
- * @return version number.
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public static long getCurrentVersion(Directory directory) throws CorruptIndexException, IOException {
- return SegmentInfos.readCurrentVersion(directory);
- }
-
- /**
- * Reads commitUserData, previously passed to {@link
- * IndexWriter#commit(Map)}, from current index
- * segments file. This will return null if {@link
- * IndexWriter#commit(Map)} has never been called for
- * this index.
- *
- * @param directory where the index resides.
- * @return commit userData.
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- *
- * @see #getCommitUserData()
- */
- public static Map<String,String> getCommitUserData(Directory directory) throws CorruptIndexException, IOException {
- return SegmentInfos.readCurrentUserData(directory);
- }
-
- /**
- * Version number when this IndexReader was opened. Not
- * implemented in the IndexReader base class.
- *
- * <p>If this reader is based on a Directory (ie, was
- * created by calling {@link #open}, or {@link #reopen} on
- * a reader based on a Directory), then this method
- * returns the version recorded in the commit that the
- * reader opened. This version is advanced every time
- * {@link IndexWriter#commit} is called.</p>
- *
- * <p>If instead this reader is a near real-time reader
- * (ie, obtained by a call to {@link
- * IndexWriter#getReader}, or by calling {@link #reopen}
- * on a near real-time reader), then this method returns
- * the version of the last commit done by the writer.
- * Note that even as further changes are made with the
- * writer, the version will not changed until a commit is
- * completed. Thus, you should not rely on this method to
- * determine when a near real-time reader should be
- * opened. Use {@link #isCurrent} instead.</p>
- *
- * @throws UnsupportedOperationException unless overridden in subclass
- */
- public long getVersion() {
- throw new UnsupportedOperationException("This reader does not support this method.");
- }
-
- /**
- * Retrieve the String userData optionally passed to
- * IndexWriter#commit. This will return null if {@link
- * IndexWriter#commit(Map)} has never been called for
- * this index.
- *
- * @see #getCommitUserData(Directory)
- */
- public Map<String,String> getCommitUserData() {
- throw new UnsupportedOperationException("This reader does not support this method.");
- }
-
-
- /**
- * Check whether any new changes have occurred to the
- * index since this reader was opened.
- *
- * <p>If this reader is based on a Directory (ie, was
- * created by calling {@link #open}, or {@link #reopen} on
- * a reader based on a Directory), then this method checks
- * if any further commits (see {@link IndexWriter#commit}
- * have occurred in that directory).</p>
- *
- * <p>If instead this reader is a near real-time reader
- * (ie, obtained by a call to {@link
- * IndexWriter#getReader}, or by calling {@link #reopen}
- * on a near real-time reader), then this method checks if
- * either a new commmit has occurred, or any new
- * uncommitted changes have taken place via the writer.
- * Note that even if the writer has only performed
- * merging, this method will still return false.</p>
- *
- * <p>In any event, if this returns false, you should call
- * {@link #reopen} to get a new reader that sees the
- * changes.</p>
- *
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- * @throws UnsupportedOperationException unless overridden in subclass
- */
- public boolean isCurrent() throws CorruptIndexException, IOException {
- throw new UnsupportedOperationException("This reader does not support this method.");
- }
-
- /**
- * Checks is the index is optimized (if it has a single segment and
- * no deletions). Not implemented in the IndexReader base class.
- * @return <code>true</code> if the index is optimized; <code>false</code> otherwise
- * @throws UnsupportedOperationException unless overridden in subclass
- */
- public boolean isOptimized() {
- throw new UnsupportedOperationException("This reader does not support this method.");
- }
-
- /**
- * Return an array of term frequency vectors for the specified document.
- * The array contains a vector for each vectorized field in the document.
- * Each vector contains terms and frequencies for all terms in a given vectorized field.
- * If no such fields existed, the method returns null. The term vectors that are
- * returned may either be of type {@link TermFreqVector}
- * or of type {@link TermPositionVector} if
- * positions or offsets have been stored.
- *
- * @param docNumber document for which term frequency vectors are returned
- * @return array of term frequency vectors. May be null if no term vectors have been
- * stored for the specified document.
- * @throws IOException if index cannot be accessed
- * @see org.apache.lucene.document.Field.TermVector
- */
- abstract public TermFreqVector[] getTermFreqVectors(int docNumber)
- throws IOException;
-
-
- /**
- * Return a term frequency vector for the specified document and field. The
- * returned vector contains terms and frequencies for the terms in
- * the specified field of this document, if the field had the storeTermVector
- * flag set. If termvectors had been stored with positions or offsets, a
- * {@link TermPositionVector} is returned.
- *
- * @param docNumber document for which the term frequency vector is returned
- * @param field field for which the term frequency vector is returned.
- * @return term frequency vector May be null if field does not exist in the specified
- * document or term vector was not stored.
- * @throws IOException if index cannot be accessed
- * @see org.apache.lucene.document.Field.TermVector
- */
- abstract public TermFreqVector getTermFreqVector(int docNumber, String field)
- throws IOException;
-
- /**
- * Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays of
- * the {@link TermFreqVector}.
- * @param docNumber The number of the document to load the vector for
- * @param field The name of the field to load
- * @param mapper The {@link TermVectorMapper} to process the vector. Must not be null
- * @throws IOException if term vectors cannot be accessed or if they do not exist on the field and doc. specified.
- *
- */
- abstract public void getTermFreqVector(int docNumber, String field, TermVectorMapper mapper) throws IOException;
-
- /**
- * Map all the term vectors for all fields in a Document
- * @param docNumber The number of the document to load the vector for
- * @param mapper The {@link TermVectorMapper} to process the vector. Must not be null
- * @throws IOException if term vectors cannot be accessed or if they do not exist on the field and doc. specified.
- */
- abstract public void getTermFreqVector(int docNumber, TermVectorMapper mapper) throws IOException;
-
- /**
- * Returns <code>true</code> if an index exists at the specified directory.
- * @param directory the directory to check for an index
- * @return <code>true</code> if an index exists; <code>false</code> otherwise
- * @throws IOException if there is a problem with accessing the index
- */
- public static boolean indexExists(Directory directory) throws IOException {
- try {
- new SegmentInfos().read(directory);
- return true;
- } catch (IOException ioe) {
- return false;
- }
- }
-
- /** Returns the number of documents in this index. */
- public abstract int numDocs();
-
- /** Returns one greater than the largest possible document number.
- * This may be used to, e.g., determine how big to allocate an array which
- * will have an element for every document number in an index.
- */
- public abstract int maxDoc();
-
- /** Returns the number of deleted documents. */
- public int numDeletedDocs() {
- return maxDoc() - numDocs();
- }
-
- /**
- * Returns the stored fields of the <code>n</code><sup>th</sup>
- * <code>Document</code> in this index.
- * <p>
- * <b>NOTE:</b> for performance reasons, this method does not check if the
- * requested document is deleted, and therefore asking for a deleted document
- * may yield unspecified results. Usually this is not required, however you
- * can call {@link #isDeleted(int)} with the requested document ID to verify
- * the document is not deleted.
- *
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public Document document(int n) throws CorruptIndexException, IOException {
- ensureOpen();
- if (n < 0 || n >= maxDoc()) {
- throw new IllegalArgumentException("docID must be >= 0 and < maxDoc=" + maxDoc() + " (got docID=" + n + ")");
- }
- return document(n, null);
- }
-
- /**
- * Get the {@link org.apache.lucene.document.Document} at the <code>n</code>
- * <sup>th</sup> position. The {@link FieldSelector} may be used to determine
- * what {@link org.apache.lucene.document.Field}s to load and how they should
- * be loaded. <b>NOTE:</b> If this Reader (more specifically, the underlying
- * <code>FieldsReader</code>) is closed before the lazy
- * {@link org.apache.lucene.document.Field} is loaded an exception may be
- * thrown. If you want the value of a lazy
- * {@link org.apache.lucene.document.Field} to be available after closing you
- * must explicitly load it or fetch the Document again with a new loader.
- * <p>
- * <b>NOTE:</b> for performance reasons, this method does not check if the
- * requested document is deleted, and therefore asking for a deleted document
- * may yield unspecified results. Usually this is not required, however you
- * can call {@link #isDeleted(int)} with the requested document ID to verify
- * the document is not deleted.
- *
- * @param n Get the document at the <code>n</code><sup>th</sup> position
- * @param fieldSelector The {@link FieldSelector} to use to determine what
- * Fields should be loaded on the Document. May be null, in which case
- * all Fields will be loaded.
- * @return The stored fields of the
- * {@link org.apache.lucene.document.Document} at the nth position
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- * @see org.apache.lucene.document.Fieldable
- * @see org.apache.lucene.document.FieldSelector
- * @see org.apache.lucene.document.SetBasedFieldSelector
- * @see org.apache.lucene.document.LoadFirstFieldSelector
- */
- // TODO (1.5): When we convert to JDK 1.5 make this Set<String>
- public abstract Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException;
-
- /** Returns true if document <i>n</i> has been deleted */
- public abstract boolean isDeleted(int n);
-
- /** Returns true if any documents have been deleted */
- public abstract boolean hasDeletions();
-
- /** Returns true if there are norms stored for this field. */
- public boolean hasNorms(String field) throws IOException {
- // backward compatible implementation.
- // SegmentReader has an efficient implementation.
- ensureOpen();
- return norms(field) != null;
- }
-
- /** Returns the byte-encoded normalization factor for the named field of
- * every document. This is used by the search code to score documents.
- * Returns null if norms were not indexed for this field.
- *
- * @see org.apache.lucene.document.Field#setBoost(float)
- */
- public abstract byte[] norms(String field) throws IOException;
-
- /** Reads the byte-encoded normalization factor for the named field of every
- * document. This is used by the search code to score documents.
- *
- * @see org.apache.lucene.document.Field#setBoost(float)
- */
- public abstract void norms(String field, byte[] bytes, int offset)
- throws IOException;
-
- /** Expert: Resets the normalization factor for the named field of the named
- * document. The norm represents the product of the field's {@link
- * org.apache.lucene.document.Fieldable#setBoost(float) boost} and its {@link Similarity#lengthNorm(String,
- * int) length normalization}. Thus, to preserve the length normalization
- * values when resetting this, one should base the new value upon the old.
- *
- * <b>NOTE:</b> If this field does not index norms, then
- * this method throws {@link IllegalStateException}.
- *
- * @see #norms(String)
- * @see Similarity#decodeNormValue(byte)
- * @throws StaleReaderException if the index has changed
- * since this reader was opened
- * @throws CorruptIndexException if the index is corrupt
- * @throws LockObtainFailedException if another writer
- * has this index open (<code>write.lock</code> could not
- * be obtained)
- * @throws IOException if there is a low-level IO error
- * @throws IllegalStateException if the field does not index norms
- */
- public synchronized void setNorm(int doc, String field, byte value)
- throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
- ensureOpen();
- acquireWriteLock();
- hasChanges = true;
- doSetNorm(doc, field, value);
- }
-
- /** Implements setNorm in subclass.*/
- protected abstract void doSetNorm(int doc, String field, byte value)
- throws CorruptIndexException, IOException;
-
- /** Expert: Resets the normalization factor for the named field of the named
- * document.
- *
- * @see #norms(String)
- * @see Similarity#decodeNormValue(byte)
- *
- * @throws StaleReaderException if the index has changed
- * since this reader was opened
- * @throws CorruptIndexException if the index is corrupt
- * @throws LockObtainFailedException if another writer
- * has this index open (<code>write.lock</code> could not
- * be obtained)
- * @throws IOException if there is a low-level IO error
- * @deprecated Use {@link #setNorm(int, String, byte)} instead, encoding the
- * float to byte with your Similarity's {@link Similarity#encodeNormValue(float)}.
- * This method will be removed in Lucene 4.0
- */
- @Deprecated
- public void setNorm(int doc, String field, float value)
- throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
- ensureOpen();
- setNorm(doc, field, Similarity.getDefault().encodeNormValue(value));
- }
-
- /** Returns an enumeration of all the terms in the index. The
- * enumeration is ordered by Term.compareTo(). Each term is greater
- * than all that precede it in the enumeration. Note that after
- * calling terms(), {@link TermEnum#next()} must be called
- * on the resulting enumeration before calling other methods such as
- * {@link TermEnum#term()}.
- * @throws IOException if there is a low-level IO error
- */
- public abstract TermEnum terms() throws IOException;
-
- /** Returns an enumeration of all terms starting at a given term. If
- * the given term does not exist, the enumeration is positioned at the
- * first term greater than the supplied term. The enumeration is
- * ordered by Term.compareTo(). Each term is greater than all that
- * precede it in the enumeration.
- * @throws IOException if there is a low-level IO error
- */
- public abstract TermEnum terms(Term t) throws IOException;
-
- /** Returns the number of documents containing the term <code>t</code>.
- * @throws IOException if there is a low-level IO error
- */
- public abstract int docFreq(Term t) throws IOException;
-
- /** Returns an enumeration of all the documents which contain
- * <code>term</code>. For each document, the document number, the frequency of
- * the term in that document is also provided, for use in
- * search scoring. If term is null, then all non-deleted
- * docs are returned with freq=1.
- * Thus, this method implements the mapping:
- * <p><ul>
- * Term => <docNum, freq><sup>*</sup>
- * </ul>
- * <p>The enumeration is ordered by document number. Each document number
- * is greater than all that precede it in the enumeration.
- * @throws IOException if there is a low-level IO error
- */
- public TermDocs termDocs(Term term) throws IOException {
- ensureOpen();
- TermDocs termDocs = termDocs();
- termDocs.seek(term);
- return termDocs;
- }
-
- /** Returns an unpositioned {@link TermDocs} enumerator.
- * <p>
- * Note: the TermDocs returned is unpositioned. Before using it, ensure
- * that you first position it with {@link TermDocs#seek(Term)} or
- * {@link TermDocs#seek(TermEnum)}.
- *
- * @throws IOException if there is a low-level IO error
- */
- public abstract TermDocs termDocs() throws IOException;
-
- /** Returns an enumeration of all the documents which contain
- * <code>term</code>. For each document, in addition to the document number
- * and frequency of the term in that document, a list of all of the ordinal
- * positions of the term in the document is available. Thus, this method
- * implements the mapping:
- *
- * <p><ul>
- * Term => <docNum, freq,
- * <pos<sub>1</sub>, pos<sub>2</sub>, ...
- * pos<sub>freq-1</sub>>
- * ><sup>*</sup>
- * </ul>
- * <p> This positional information facilitates phrase and proximity searching.
- * <p>The enumeration is ordered by document number. Each document number is
- * greater than all that precede it in the enumeration.
- * @throws IOException if there is a low-level IO error
- */
- public TermPositions termPositions(Term term) throws IOException {
- ensureOpen();
- TermPositions termPositions = termPositions();
- termPositions.seek(term);
- return termPositions;
- }
-
- /** Returns an unpositioned {@link TermPositions} enumerator.
- * @throws IOException if there is a low-level IO error
- */
- public abstract TermPositions termPositions() throws IOException;
-
-
-
- /** Deletes the document numbered <code>docNum</code>. Once a document is
- * deleted it will not appear in TermDocs or TermPostitions enumerations.
- * Attempts to read its field with the {@link #document}
- * method will result in an error. The presence of this document may still be
- * reflected in the {@link #docFreq} statistic, though
- * this will be corrected eventually as the index is further modified.
- *
- * @throws StaleReaderException if the index has changed
- * since this reader was opened
- * @throws CorruptIndexException if the index is corrupt
- * @throws LockObtainFailedException if another writer
- * has this index open (<code>write.lock</code> could not
- * be obtained)
- * @throws IOException if there is a low-level IO error
- */
- public synchronized void deleteDocument(int docNum) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
- ensureOpen();
- acquireWriteLock();
- hasChanges = true;
- doDelete(docNum);
- }
-
-
- /** Implements deletion of the document numbered <code>docNum</code>.
- * Applications should call {@link #deleteDocument(int)} or {@link #deleteDocuments(Term)}.
- */
- protected abstract void doDelete(int docNum) throws CorruptIndexException, IOException;
-
-
- /** Deletes all documents that have a given <code>term</code> indexed.
- * This is useful if one uses a document field to hold a unique ID string for
- * the document. Then to delete such a document, one merely constructs a
- * term with the appropriate field and the unique ID string as its text and
- * passes it to this method.
- * See {@link #deleteDocument(int)} for information about when this deletion will
- * become effective.
- *
- * @return the number of documents deleted
- * @throws StaleReaderException if the index has changed
- * since this reader was opened
- * @throws CorruptIndexException if the index is corrupt
- * @throws LockObtainFailedException if another writer
- * has this index open (<code>write.lock</code> could not
- * be obtained)
- * @throws IOException if there is a low-level IO error
- */
- public int deleteDocuments(Term term) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
- ensureOpen();
- TermDocs docs = termDocs(term);
- if (docs == null) return 0;
- int n = 0;
- try {
- while (docs.next()) {
- deleteDocument(docs.doc());
- n++;
- }
- } finally {
- docs.close();
- }
- return n;
- }
-
- /** Undeletes all documents currently marked as deleted in
- * this index.
- *
- * <p>NOTE: this method can only recover documents marked
- * for deletion but not yet removed from the index; when
- * and how Lucene removes deleted documents is an
- * implementation detail, subject to change from release
- * to release. However, you can use {@link
- * #numDeletedDocs} on the current IndexReader instance to
- * see how many documents will be un-deleted.
- *
- * @throws StaleReaderException if the index has changed
- * since this reader was opened
- * @throws LockObtainFailedException if another writer
- * has this index open (<code>write.lock</code> could not
- * be obtained)
- * @throws CorruptIndexException if the index is corrupt
- * @throws IOException if there is a low-level IO error
- */
- public synchronized void undeleteAll() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
- ensureOpen();
- acquireWriteLock();
- hasChanges = true;
- doUndeleteAll();
- }
-
- /** Implements actual undeleteAll() in subclass. */
- protected abstract void doUndeleteAll() throws CorruptIndexException, IOException;
-
- /** Does nothing by default. Subclasses that require a write lock for
- * index modifications must implement this method. */
- protected synchronized void acquireWriteLock() throws IOException {
- /* NOOP */
- }
-
- /**
- *
- * @throws IOException
- */
- public final synchronized void flush() throws IOException {
- ensureOpen();
- commit();
- }
-
- /**
- * @param commitUserData Opaque Map (String -> String)
- * that's recorded into the segments file in the index,
- * and retrievable by {@link
- * IndexReader#getCommitUserData}.
- * @throws IOException
- */
- public final synchronized void flush(Map<String, String> commitUserData) throws IOException {
- ensureOpen();
- commit(commitUserData);
- }
-
- /**
- * Commit changes resulting from delete, undeleteAll, or
- * setNorm operations
- *
- * If an exception is hit, then either no changes or all
- * changes will have been committed to the index
- * (transactional semantics).
- * @throws IOException if there is a low-level IO error
- */
- protected final synchronized void commit() throws IOException {
- commit(null);
- }
-
- /**
- * Commit changes resulting from delete, undeleteAll, or
- * setNorm operations
- *
- * If an exception is hit, then either no changes or all
- * changes will have been committed to the index
- * (transactional semantics).
- * @throws IOException if there is a low-level IO error
- */
- public final synchronized void commit(Map<String, String> commitUserData) throws IOException {
- if (hasChanges) {
- doCommit(commitUserData);
- }
- hasChanges = false;
- }
-
- /** Implements commit. */
- protected abstract void doCommit(Map<String, String> commitUserData) throws IOException;
-
- /**
- * Closes files associated with this index.
- * Also saves any new deletions to disk.
- * No other methods should be called after this has been called.
- * @throws IOException if there is a low-level IO error
- */
- public final synchronized void close() throws IOException {
- if (!closed) {
- decRef();
- closed = true;
- }
- }
-
- /** Implements close. */
- protected abstract void doClose() throws IOException;
-
-
- /**
- * Get a list of unique field names that exist in this index and have the specified
- * field option information.
- * @param fldOption specifies which field option should be available for the returned fields
- * @return Collection of Strings indicating the names of the fields.
- * @see IndexReader.FieldOption
- */
- public abstract Collection<String> getFieldNames(FieldOption fldOption);
-
- /**
- * Expert: return the IndexCommit that this reader has
- * opened. This method is only implemented by those
- * readers that correspond to a Directory with its own
- * segments_N file.
- *
- * @lucene.experimental
- */
- public IndexCommit getIndexCommit() throws IOException {
- throw new UnsupportedOperationException("This reader does not support this method.");
- }
-
- /**
- * Prints the filename and size of each file within a given compound file.
- * Add the -extract flag to extract files to the current working directory.
- * In order to make the extracted version of the index work, you have to copy
- * the segments file from the compound index into the directory where the extracted files are stored.
- * @param args Usage: org.apache.lucene.index.IndexReader [-extract] <cfsfile>
- */
- public static void main(String [] args) {
- String filename = null;
- boolean extract = false;
-
- for (int i = 0; i < args.length; ++i) {
- if (args[i].equals("-extract")) {
- extract = true;
- } else if (filename == null) {
- filename = args[i];
- }
- }
-
- if (filename == null) {
- System.out.println("Usage: org.apache.lucene.index.IndexReader [-extract] <cfsfile>");
- return;
- }
-
- Directory dir = null;
- CompoundFileReader cfr = null;
-
- try {
- File file = new File(filename);
- String dirname = file.getAbsoluteFile().getParent();
- filename = file.getName();
- dir = FSDirectory.open(new File(dirname));
- cfr = new CompoundFileReader(dir, filename);
-
- String [] files = cfr.listAll();
- ArrayUtil.mergeSort(files); // sort the array of filename so that the output is more readable
-
- for (int i = 0; i < files.length; ++i) {
- long len = cfr.fileLength(files[i]);
-
- if (extract) {
- System.out.println("extract " + files[i] + " with " + len + " bytes to local directory...");
- IndexInput ii = cfr.openInput(files[i]);
-
- FileOutputStream f = new FileOutputStream(files[i]);
-
- // read and write with a small buffer, which is more effective than reading byte by byte
- byte[] buffer = new byte[1024];
- int chunk = buffer.length;
- while(len > 0) {
- final int bufLen = (int) Math.min(chunk, len);
- ii.readBytes(buffer, 0, bufLen);
- f.write(buffer, 0, bufLen);
- len -= bufLen;
- }
-
- f.close();
- ii.close();
- }
- else
- System.out.println(files[i] + ": " + len + " bytes");
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- finally {
- try {
- if (dir != null)
- dir.close();
- if (cfr != null)
- cfr.close();
- }
- catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
-
- /** Returns all commit points that exist in the Directory.
- * Normally, because the default is {@link
- * KeepOnlyLastCommitDeletionPolicy}, there would be only
- * one commit point. But if you're using a custom {@link
- * IndexDeletionPolicy} then there could be many commits.
- * Once you have a given commit, you can open a reader on
- * it by calling {@link IndexReader#open(IndexCommit,boolean)}
- * There must be at least one commit in
- * the Directory, else this method throws {@link
- * IndexNotFoundException}. Note that if a commit is in
- * progress while this method is running, that commit
- * may or may not be returned.
- *
- * @return a sorted list of {@link IndexCommit}s, from oldest
- * to latest. */
- public static Collection<IndexCommit> listCommits(Directory dir) throws IOException {
- return DirectoryReader.listCommits(dir);
- }
-
- /** Expert: returns the sequential sub readers that this
- * reader is logically composed of. For example,
- * IndexSearcher uses this API to drive searching by one
- * sub reader at a time. If this reader is not composed
- * of sequential child readers, it should return null.
- * If this method returns an empty array, that means this
- * reader is a null reader (for example a MultiReader
- * that has no sub readers).
- * <p>
- * NOTE: You should not try using sub-readers returned by
- * this method to make any changes (setNorm, deleteDocument,
- * etc.). While this might succeed for one composite reader
- * (like MultiReader), it will most likely lead to index
- * corruption for other readers (like DirectoryReader obtained
- * through {@link #open}. Use the parent reader directly. */
- public IndexReader[] getSequentialSubReaders() {
- return null;
- }
-
- /** Expert */
- public Object getCoreCacheKey() {
- return this;
- }
-
- /** Expert. Warning: this returns null if the reader has
- * no deletions */
- public Object getDeletesCacheKey() {
- return this;
- }
-
- /** Returns the number of unique terms (across all fields)
- * in this reader.
- *
- * This method returns long, even though internally
- * Lucene cannot handle more than 2^31 unique terms, for
- * a possible future when this limitation is removed.
- *
- * @throws UnsupportedOperationException if this count
- * cannot be easily determined (eg Multi*Readers).
- * Instead, you should call {@link
- * #getSequentialSubReaders} and ask each sub reader for
- * its unique term count. */
- public long getUniqueTermCount() throws IOException {
- throw new UnsupportedOperationException("this reader does not implement getUniqueTermCount()");
- }
-
- /** For IndexReader implementations that use
- * TermInfosReader to read terms, this returns the
- * current indexDivisor as specified when the reader was
- * opened.
- */
- public int getTermInfosIndexDivisor() {
- throw new UnsupportedOperationException("This reader does not support this method.");
- }
-}