Submitted by: Christoph Goller via Dmitry

Slightly modified patch from Christoph to prohibit modifications of an
index by readers that have a stale view of it.


git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@150063 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dmitry Serebrennikov 2003-09-25 21:41:51 +00:00
parent 71bbc1396f
commit 93b5e6c230
1 changed files with 35 additions and 16 deletions

View File

@ -80,11 +80,15 @@ import org.apache.lucene.document.Field; // for javadoc
public abstract class IndexReader { public abstract class IndexReader {
protected IndexReader(Directory directory) { protected IndexReader(Directory directory) {
this.directory = directory; this.directory = directory;
segmentInfosAge = Long.MAX_VALUE;
} }
Directory directory; Directory directory;
private Lock writeLock; private Lock writeLock;
//used to determine whether index has chaged since reader was opened
private long segmentInfosAge;
/** Returns an IndexReader reading the index in an FSDirectory in the named /** Returns an IndexReader reading the index in an FSDirectory in the named
path. */ path. */
public static IndexReader open(String path) throws IOException { public static IndexReader open(String path) throws IOException {
@ -102,15 +106,21 @@ public abstract class IndexReader {
synchronized (directory) { // in- & inter-process sync synchronized (directory) { // in- & inter-process sync
return (IndexReader)new Lock.With(directory.makeLock("commit.lock"), IndexWriter.COMMIT_LOCK_TIMEOUT) { return (IndexReader)new Lock.With(directory.makeLock("commit.lock"), IndexWriter.COMMIT_LOCK_TIMEOUT) {
public Object doBody() throws IOException { public Object doBody() throws IOException {
IndexReader result = null;
SegmentInfos infos = new SegmentInfos(); SegmentInfos infos = new SegmentInfos();
infos.read(directory); infos.read(directory);
if (infos.size() == 1) // index is optimized if (infos.size() == 1) { // index is optimized
return new SegmentReader(infos.info(0), true); result = new SegmentReader(infos.info(0), true);
} else {
SegmentReader[] readers = new SegmentReader[infos.size()]; SegmentReader[] readers = new SegmentReader[infos.size()];
for (int i = 0; i < infos.size(); i++) for (int i = 0; i < infos.size(); i++)
readers[i] = new SegmentReader(infos.info(i), i==infos.size()-1); readers[i] = new SegmentReader(infos.info(i), i==infos.size()-1);
return new SegmentsReader(directory, readers); result = new SegmentsReader(directory, readers);
}
result.segmentInfosAge = lastModified(directory);
return result;
} }
}.run(); }.run();
} }
@ -258,6 +268,15 @@ public abstract class IndexReader {
if (!writeLock.obtain(IndexWriter.WRITE_LOCK_TIMEOUT)) // obtain write lock if (!writeLock.obtain(IndexWriter.WRITE_LOCK_TIMEOUT)) // obtain write lock
throw new IOException("Index locked for write: " + writeLock); throw new IOException("Index locked for write: " + writeLock);
this.writeLock = writeLock; this.writeLock = writeLock;
// we have to check whether index has changed since this reader was opened.
// if so, this reader is no longer valid for deletion
if(lastModified(directory) > segmentInfosAge){
this.writeLock.release();
this.writeLock = null;
throw new IOException(
"IndexReader out of date and no longer valid for deletion");
}
} }
doDelete(docNum); doDelete(docNum);
} }