| Method from org.apache.lucene.index.DirectoryIndexReader Detail: |
protected void acquireWriteLock() throws IOException, StaleReaderException, CorruptIndexException, LockObtainFailedException {
if (segmentInfos != null) {
ensureOpen();
if (stale)
throw new StaleReaderException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
if (writeLock == null) {
Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME);
if (!writeLock.obtain(IndexWriter.WRITE_LOCK_TIMEOUT)) // obtain write lock
throw new LockObtainFailedException("Index locked for write: " + 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 (SegmentInfos.readCurrentVersion(directory) > segmentInfos.getVersion()) {
stale = true;
this.writeLock.release();
this.writeLock = null;
throw new StaleReaderException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
}
}
}
}
Tries to acquire the WriteLock on this directory.
this method is only valid if this IndexReader is directory owner. |
abstract protected void commitChanges() throws IOException
|
public Directory directory() {
ensureOpen();
return directory;
}
Returns the directory this index resides in. |
protected void doClose() throws IOException {
if(closeDirectory)
directory.close();
}
|
protected void doCommit() throws IOException {
if(hasChanges){
if (segmentInfos != null) {
// Default deleter (for backwards compatibility) is
// KeepOnlyLastCommitDeleter:
IndexFileDeleter deleter = new IndexFileDeleter(directory,
deletionPolicy == null ? new KeepOnlyLastCommitDeletionPolicy() : deletionPolicy,
segmentInfos, null, null);
// Checkpoint the state we are about to change, in
// case we have to roll back:
startCommit();
boolean success = false;
try {
commitChanges();
segmentInfos.write(directory);
success = true;
} finally {
if (!success) {
// Rollback changes that were made to
// SegmentInfos but failed to get [fully]
// committed. This way this reader instance
// remains consistent (matched to what's
// actually in the index):
rollbackCommit();
// Recompute deletable files & remove them (so
// partially written .del files, etc, are
// removed):
deleter.refresh();
}
}
// Have the deleter remove any now unreferenced
// files due to this commit:
deleter.checkpoint(segmentInfos, true);
if (writeLock != null) {
writeLock.release(); // release write lock
writeLock = null;
}
}
else
commitChanges();
}
hasChanges = false;
}
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). |
abstract protected DirectoryIndexReader doReopen(SegmentInfos infos) throws IOException, CorruptIndexException
Re-opens the index using the passed-in SegmentInfos |
protected void finalize() throws Throwable {
try {
if (writeLock != null) {
writeLock.release(); // release write lock
writeLock = null;
}
} finally {
super.finalize();
}
}
Release the write lock, if needed. |
public long getVersion() {
ensureOpen();
return segmentInfos.getVersion();
}
Version number when this IndexReader was opened. |
void init(Directory directory,
SegmentInfos segmentInfos,
boolean closeDirectory) {
this.directory = directory;
this.segmentInfos = segmentInfos;
this.closeDirectory = closeDirectory;
}
|
public boolean isCurrent() throws IOException, CorruptIndexException {
ensureOpen();
return SegmentInfos.readCurrentVersion(directory) == segmentInfos.getVersion();
}
Check whether this IndexReader is still using the
current (i.e., most recently committed) version of the
index. If a writer has committed any changes to the
index since this reader was opened, this will return
false, in which case you must open a new
IndexReader in order to see the changes. See the
description of the autoCommit
flag which controls when the IndexWriter
actually commits changes to the index. |
public boolean isOptimized() {
ensureOpen();
return segmentInfos.size() == 1 && hasDeletions() == false;
}
Checks is the index is optimized (if it has a single segment and no deletions) |
static DirectoryIndexReader open(Directory directory,
boolean closeDirectory,
IndexDeletionPolicy deletionPolicy) throws IOException, CorruptIndexException {
return (DirectoryIndexReader) new SegmentInfos.FindSegmentsFile(directory) {
protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
SegmentInfos infos = new SegmentInfos();
infos.read(directory, segmentFileName);
DirectoryIndexReader reader;
if (infos.size() == 1) { // index is optimized
reader = SegmentReader.get(infos, infos.info(0), closeDirectory);
} else {
reader = new MultiSegmentReader(directory, infos, closeDirectory);
}
reader.setDeletionPolicy(deletionPolicy);
return reader;
}
}.run();
}
|
public final synchronized IndexReader reopen() throws IOException, CorruptIndexException {
ensureOpen();
if (this.hasChanges || this.isCurrent()) {
// the index hasn't changed - nothing to do here
return this;
}
return (DirectoryIndexReader) new SegmentInfos.FindSegmentsFile(directory) {
protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
SegmentInfos infos = new SegmentInfos();
infos.read(directory, segmentFileName);
DirectoryIndexReader newReader = doReopen(infos);
if (DirectoryIndexReader.this != newReader) {
newReader.init(directory, infos, closeDirectory);
newReader.deletionPolicy = deletionPolicy;
}
return newReader;
}
}.run();
}
|
void rollbackCommit() {
if (segmentInfos != null) {
for(int i=0;i< segmentInfos.size();i++) {
// Rollback each segmentInfo. Because the
// SegmentReader holds a reference to the
// SegmentInfo we can't [easily] just replace
// segmentInfos, so we reset it in place instead:
segmentInfos.info(i).reset(rollbackSegmentInfos.info(i));
}
rollbackSegmentInfos = null;
}
hasChanges = rollbackHasChanges;
}
Rolls back state to just before the commit (this is
called by commit() if there is some exception while
committing). |
public void setDeletionPolicy(IndexDeletionPolicy deletionPolicy) {
this.deletionPolicy = deletionPolicy;
}
|
void startCommit() {
if (segmentInfos != null) {
rollbackSegmentInfos = (SegmentInfos) segmentInfos.clone();
}
rollbackHasChanges = hasChanges;
}
Should internally checkpoint state that will change
during commit so that we can rollback if necessary. |