obtain write.lock while deleting documents

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@149670 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Doug Cutting 2002-02-08 19:39:42 +00:00
parent 17b7faf67c
commit 64943029fa
4 changed files with 56 additions and 13 deletions

View File

@ -75,7 +75,12 @@ import org.apache.lucene.document.Document;
rely on a given document having the same number between sessions. */
abstract public class IndexReader {
protected IndexReader() {}
protected IndexReader(Directory directory) {
this.directory = directory;
}
Directory directory;
private Lock writeLock;
/** Returns an IndexReader reading the index in an FSDirectory in the named
path. */
@ -102,7 +107,7 @@ abstract public class IndexReader {
SegmentReader[] readers = new SegmentReader[infos.size()];
for (int i = 0; i < infos.size(); i++)
readers[i] = new SegmentReader(infos.info(i), i==infos.size()-1);
return new SegmentsReader(readers);
return new SegmentsReader(directory, readers);
}
}.run();
}
@ -240,7 +245,16 @@ abstract public class IndexReader {
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. */
abstract public void delete(int docNum) throws IOException;
public synchronized final void delete(int docNum) throws IOException {
if (writeLock == null) {
Lock writeLock = directory.makeLock("write.lock");
if (!writeLock.obtain()) // obtain write lock
throw new IOException("Index locked for write: " + writeLock);
this.writeLock = writeLock;
}
doDelete(docNum);
}
abstract void doDelete(int docNum) throws IOException;
/** Deletes all documents containing <code>term</code>.
This is useful if one uses a document field to hold a unique ID string for
@ -267,7 +281,24 @@ abstract public class IndexReader {
* Also saves any new deletions to disk.
* No other methods should be called after this has been called.
*/
abstract public void close() throws IOException;
public final synchronized void close() throws IOException {
doClose();
if (writeLock != null) {
writeLock.release(); // release write lock
writeLock = null;
}
}
/** Implements close. */
abstract void doClose() throws IOException;
/** Release the write lock, if needed. */
protected final void finalize() throws IOException {
if (writeLock != null) {
writeLock.release(); // release write lock
writeLock = null;
}
}
/**
* Returns <code>true</code> iff the index in the named directory is

View File

@ -91,6 +91,8 @@ public final class IndexWriter {
private SegmentInfos segmentInfos = new SegmentInfos(); // the segments
private final Directory ramDirectory = new RAMDirectory(); // for temp segs
private Lock writeLock;
/** Constructs an IndexWriter for the index in <code>path</code>. Text will
be analyzed with <code>a</code>. If <code>create</code> is true, then a
new, empty index will be created in <code>path</code>, replacing the index
@ -119,8 +121,9 @@ public final class IndexWriter {
analyzer = a;
Lock writeLock = directory.makeLock("write.lock");
if (!writeLock.obtain()) // obtain write lock
if (!writeLock.obtain()) // obtain write lock
throw new IOException("Index locked for write: " + writeLock);
this.writeLock = writeLock; // save it
synchronized (directory) { // in- & inter-process sync
new Lock.With(directory.makeLock("commit.lock")) {
@ -140,10 +143,19 @@ public final class IndexWriter {
public final synchronized void close() throws IOException {
flushRamSegments();
ramDirectory.close();
directory.makeLock("write.lock").release(); // release write lock
writeLock.release(); // release write lock
writeLock = null;
directory.close();
}
/** Release the write lock, if needed. */
protected final void finalize() throws IOException {
if (writeLock != null) {
writeLock.release(); // release write lock
writeLock = null;
}
}
/** Returns the number of documents currently in this index. */
public final synchronized int docCount() {
int count = 0;

View File

@ -66,7 +66,6 @@ import org.apache.lucene.store.InputStream;
import org.apache.lucene.document.Document;
final class SegmentReader extends IndexReader {
Directory directory;
private boolean closeDirectory = false;
private String segment;
@ -97,7 +96,7 @@ final class SegmentReader extends IndexReader {
SegmentReader(SegmentInfo si)
throws IOException {
directory = si.dir;
super(si.dir);
segment = si.name;
fieldInfos = new FieldInfos(directory, segment + ".fnm");
@ -115,7 +114,7 @@ final class SegmentReader extends IndexReader {
openNorms();
}
public final synchronized void close() throws IOException {
final synchronized void doClose() throws IOException {
if (deletedDocsDirty) {
synchronized (directory) { // in- & inter-process sync
new Lock.With(directory.makeLock("commit.lock")) {
@ -147,7 +146,7 @@ final class SegmentReader extends IndexReader {
return si.dir.fileExists(si.name + ".del");
}
public final synchronized void delete(int docNum) throws IOException {
final synchronized void doDelete(int docNum) throws IOException {
if (deletedDocs == null)
deletedDocs = new BitVector(maxDoc());
deletedDocsDirty = true;

View File

@ -67,7 +67,8 @@ final class SegmentsReader extends IndexReader {
private int maxDoc = 0;
private int numDocs = -1;
SegmentsReader(SegmentReader[] r) throws IOException {
SegmentsReader(Directory directory, SegmentReader[] r) throws IOException {
super(directory);
readers = r;
starts = new int[readers.length + 1]; // build starts array
for (int i = 0; i < readers.length; i++) {
@ -101,7 +102,7 @@ final class SegmentsReader extends IndexReader {
return readers[i].isDeleted(n - starts[i]); // dispatch to segment reader
}
public synchronized final void delete(int n) throws IOException {
synchronized final void doDelete(int n) throws IOException {
numDocs = -1; // invalidate cache
int i = readerIndex(n); // find segment num
readers[i].delete(n - starts[i]); // dispatch to segment reader
@ -159,7 +160,7 @@ final class SegmentsReader extends IndexReader {
return new SegmentsTermPositions(readers, starts);
}
public final void close() throws IOException {
final synchronized void doClose() throws IOException {
for (int i = 0; i < readers.length; i++)
readers[i].close();
}