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.FieldSelector;
import org.apache.lucene.search.Similarity;
import org.apache.lucene.store.AlreadyClosedException;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.Lock;
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");
}
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
// the future we could have write make some effort to
// detect that no changes have occurred

View File

@ -29,6 +29,7 @@ import java.io.Closeable;
import java.util.Arrays;
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,
@ -116,13 +117,13 @@ public abstract class IndexReader implements Cloneable,Closeable {
private boolean closed;
protected boolean hasChanges;
private int refCount;
private final AtomicInteger refCount = new AtomicInteger();
static int DEFAULT_TERMS_INDEX_DIVISOR = 1;
/** Expert: returns the current refCount for this reader */
public synchronized int getRefCount() {
return refCount;
public int getRefCount() {
return refCount.get();
}
/**
@ -139,41 +140,48 @@ public abstract class IndexReader implements Cloneable,Closeable {
*
* @see #decRef
*/
public synchronized void incRef() {
assert refCount > 0;
public void incRef() {
ensureOpen();
refCount++;
refCount.incrementAndGet();
}
/**
* 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.
*
* 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 synchronized void decRef() throws IOException {
assert refCount > 0;
public void decRef() throws IOException {
ensureOpen();
if (refCount == 1) {
commit();
doClose();
if (refCount.getAndDecrement() == 1) {
boolean success = false;
try {
commit();
doClose();
success = true;
} finally {
if (!success) {
// Put reference back on failure
refCount.incrementAndGet();
}
}
}
refCount--;
}
protected IndexReader() {
refCount = 1;
refCount.set(1);
}
/**
* @throws AlreadyClosedException if this IndexReader is closed
*/
protected final void ensureOpen() throws AlreadyClosedException {
if (refCount <= 0) {
if (refCount.get() <= 0) {
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
* to -1 to skip loading the terms index entirely. */
public IndexReader getReader(int termInfosIndexDivisor) throws IOException {
ensureOpen();
if (infoStream != null) {
message("flush at getReader");
}
@ -703,23 +706,19 @@ public class IndexWriter implements Closeable {
notifyAll();
}
synchronized final boolean isOpen(boolean includePendingClose) {
return !(closed || (includePendingClose && closing));
}
/**
* Used internally to throw an {@link
* AlreadyClosedException} if this IndexWriter has been
* closed.
* @throws AlreadyClosedException if this IndexWriter is
*/
protected synchronized final void ensureOpen(boolean includePendingClose) throws AlreadyClosedException {
if (!isOpen(includePendingClose)) {
protected final void ensureOpen(boolean includePendingClose) throws AlreadyClosedException {
if (closed || (includePendingClose && closing)) {
throw new AlreadyClosedException("this IndexWriter is closed");
}
}
protected synchronized final void ensureOpen() throws AlreadyClosedException {
protected final void ensureOpen() throws AlreadyClosedException {
ensureOpen(true);
}
@ -2906,7 +2905,7 @@ public class IndexWriter implements Closeable {
releaseWrite();
}
private void blockAddIndexes(boolean includePendingClose) {
private void blockAddIndexes() {
acquireRead();
@ -2915,7 +2914,7 @@ public class IndexWriter implements Closeable {
// Make sure we are still open since we could have
// waited quite a while for last addIndexes to finish
ensureOpen(includePendingClose);
ensureOpen(false);
success = true;
} finally {
if (!success)
@ -4588,7 +4587,7 @@ public class IndexWriter implements Closeable {
// Wait for any running addIndexes to complete
// first, then block any from running until we've
// copied the segmentInfos we intend to sync:
blockAddIndexes(false);
blockAddIndexes();
// On commit the segmentInfos must never
// reference a segment in another directory: