LUCENE-2156: switch to AtomicInteger for IR's ref count; remove sync from IW's ensureOpen (it's only 'best effort')

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@891202 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2009-12-16 11:47:01 +00:00
parent c84752afb9
commit dc3f92e6e5
3 changed files with 33 additions and 31 deletions

View File

@ -32,7 +32,6 @@ import java.util.Set;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.document.FieldSelector; import org.apache.lucene.document.FieldSelector;
import org.apache.lucene.search.Similarity; import org.apache.lucene.search.Similarity;
import org.apache.lucene.store.AlreadyClosedException;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.Lock; import org.apache.lucene.store.Lock;
import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.store.LockObtainFailedException;
@ -379,10 +378,6 @@ class DirectoryReader extends IndexReader implements Cloneable {
throw new IllegalArgumentException("a reader obtained from IndexWriter.getReader() cannot currently accept a commit"); throw new IllegalArgumentException("a reader obtained from IndexWriter.getReader() cannot currently accept a commit");
} }
if (!writer.isOpen(true)) {
throw new AlreadyClosedException("cannot reopen: the IndexWriter this reader was obtained from is now closed");
}
// TODO: right now we *always* make a new reader; in // TODO: right now we *always* make a new reader; in
// the future we could have write make some effort to // the future we could have write make some effort to
// detect that no changes have occurred // detect that no changes have occurred

View File

@ -29,6 +29,7 @@ import java.io.Closeable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/** IndexReader is an abstract class, providing an interface for accessing an /** IndexReader is an abstract class, providing an interface for accessing an
index. Search of an index is done entirely through this abstract interface, index. Search of an index is done entirely through this abstract interface,
@ -116,13 +117,13 @@ public abstract class IndexReader implements Cloneable,Closeable {
private boolean closed; private boolean closed;
protected boolean hasChanges; protected boolean hasChanges;
private int refCount; private final AtomicInteger refCount = new AtomicInteger();
static int DEFAULT_TERMS_INDEX_DIVISOR = 1; static int DEFAULT_TERMS_INDEX_DIVISOR = 1;
/** Expert: returns the current refCount for this reader */ /** Expert: returns the current refCount for this reader */
public synchronized int getRefCount() { public int getRefCount() {
return refCount; return refCount.get();
} }
/** /**
@ -139,41 +140,48 @@ public abstract class IndexReader implements Cloneable,Closeable {
* *
* @see #decRef * @see #decRef
*/ */
public synchronized void incRef() { public void incRef() {
assert refCount > 0;
ensureOpen(); ensureOpen();
refCount++; refCount.incrementAndGet();
} }
/** /**
* Expert: decreases the refCount of this IndexReader * Expert: decreases the refCount of this IndexReader
* instance. If the refCount drops to 0, then pending * instance. If the refCount drops to 0, then pending
* changes (if any) are committed to the index and this * changes (if any) are committed to the index and this
* reader is closed. * reader is closed. If an exception is hit, the refCount
* * is unchanged.
*
* @throws IOException in case an IOException occurs in commit() or doClose() * @throws IOException in case an IOException occurs in commit() or doClose()
* *
* @see #incRef * @see #incRef
*/ */
public synchronized void decRef() throws IOException { public void decRef() throws IOException {
assert refCount > 0;
ensureOpen(); ensureOpen();
if (refCount == 1) { if (refCount.getAndDecrement() == 1) {
commit(); boolean success = false;
doClose(); try {
commit();
doClose();
success = true;
} finally {
if (!success) {
// Put reference back on failure
refCount.incrementAndGet();
}
}
} }
refCount--;
} }
protected IndexReader() { protected IndexReader() {
refCount = 1; refCount.set(1);
} }
/** /**
* @throws AlreadyClosedException if this IndexReader is closed * @throws AlreadyClosedException if this IndexReader is closed
*/ */
protected final void ensureOpen() throws AlreadyClosedException { protected final void ensureOpen() throws AlreadyClosedException {
if (refCount <= 0) { if (refCount.get() <= 0) {
throw new AlreadyClosedException("this IndexReader is closed"); throw new AlreadyClosedException("this IndexReader is closed");
} }
} }

View File

@ -386,6 +386,9 @@ public class IndexWriter implements Closeable {
* loading a TermInfo. The default value is 1. Set this * loading a TermInfo. The default value is 1. Set this
* to -1 to skip loading the terms index entirely. */ * to -1 to skip loading the terms index entirely. */
public IndexReader getReader(int termInfosIndexDivisor) throws IOException { public IndexReader getReader(int termInfosIndexDivisor) throws IOException {
ensureOpen();
if (infoStream != null) { if (infoStream != null) {
message("flush at getReader"); message("flush at getReader");
} }
@ -703,23 +706,19 @@ public class IndexWriter implements Closeable {
notifyAll(); notifyAll();
} }
synchronized final boolean isOpen(boolean includePendingClose) {
return !(closed || (includePendingClose && closing));
}
/** /**
* Used internally to throw an {@link * Used internally to throw an {@link
* AlreadyClosedException} if this IndexWriter has been * AlreadyClosedException} if this IndexWriter has been
* closed. * closed.
* @throws AlreadyClosedException if this IndexWriter is * @throws AlreadyClosedException if this IndexWriter is
*/ */
protected synchronized final void ensureOpen(boolean includePendingClose) throws AlreadyClosedException { protected final void ensureOpen(boolean includePendingClose) throws AlreadyClosedException {
if (!isOpen(includePendingClose)) { if (closed || (includePendingClose && closing)) {
throw new AlreadyClosedException("this IndexWriter is closed"); throw new AlreadyClosedException("this IndexWriter is closed");
} }
} }
protected synchronized final void ensureOpen() throws AlreadyClosedException { protected final void ensureOpen() throws AlreadyClosedException {
ensureOpen(true); ensureOpen(true);
} }
@ -2906,7 +2905,7 @@ public class IndexWriter implements Closeable {
releaseWrite(); releaseWrite();
} }
private void blockAddIndexes(boolean includePendingClose) { private void blockAddIndexes() {
acquireRead(); acquireRead();
@ -2915,7 +2914,7 @@ public class IndexWriter implements Closeable {
// Make sure we are still open since we could have // Make sure we are still open since we could have
// waited quite a while for last addIndexes to finish // waited quite a while for last addIndexes to finish
ensureOpen(includePendingClose); ensureOpen(false);
success = true; success = true;
} finally { } finally {
if (!success) if (!success)
@ -4588,7 +4587,7 @@ public class IndexWriter implements Closeable {
// Wait for any running addIndexes to complete // Wait for any running addIndexes to complete
// first, then block any from running until we've // first, then block any from running until we've
// copied the segmentInfos we intend to sync: // copied the segmentInfos we intend to sync:
blockAddIndexes(false); blockAddIndexes();
// On commit the segmentInfos must never // On commit the segmentInfos must never
// reference a segment in another directory: // reference a segment in another directory: