if (create) {
// Clear the write lock in case it's leftover:
directory.clearLock(WRITE_LOCK_NAME);
}
Lock writeLock = directory.makeLock(WRITE_LOCK_NAME);
if (!writeLock.obtain(writeLockTimeout)) // obtain write lock
throw new LockObtainFailedException("Index locked for write: " + writeLock);
this.writeLock = writeLock; // save it
boolean success = false;
try {
if (create) {
// Try to read first. This is to allow create
// against an index that's currently open for
// searching. In this case we write the next
// segments_N file with no segments:
boolean doCommit;
try {
segmentInfos.read(directory);
segmentInfos.clear();
doCommit = false;
} catch (IOException e) {
// Likely this means it's a fresh directory
doCommit = true;
}
if (autoCommit || doCommit) {
// Always commit if autoCommit=true, else only
// commit if there is no segments file in this dir
// already.
segmentInfos.commit(directory);
synced.addAll(segmentInfos.files(directory, true));
} else {
// Record that we have a change (zero out all
// segments) pending:
changeCount++;
}
} else {
segmentInfos.read(directory);
if (commit != null) {
// Swap out all segments, but, keep metadata in
// SegmentInfos, like version & generation, to
// preserve write-once. This is important if
// readers are open against the future commit
// points.
if (commit.getDirectory() != directory)
throw new IllegalArgumentException("IndexCommit's directory doesn't match my directory");
SegmentInfos oldInfos = new SegmentInfos();
oldInfos.read(directory, commit.getSegmentsFileName());
segmentInfos.replace(oldInfos);
changeCount++;
if (infoStream != null)
message("init: loaded commit \"" + commit.getSegmentsFileName() + "\"");
}
// We assume that this segments_N was previously
// properly sync'd:
synced.addAll(segmentInfos.files(directory, true));
}
this.autoCommit = autoCommit;
setRollbackSegmentInfos(segmentInfos);
docWriter = new DocumentsWriter(directory, this, indexingChain);
docWriter.setInfoStream(infoStream);
docWriter.setMaxFieldLength(maxFieldLength);
// Default deleter (for backwards compatibility) is
// KeepOnlyLastCommitDeleter:
deleter = new IndexFileDeleter(directory,
deletionPolicy == null ? new KeepOnlyLastCommitDeletionPolicy() : deletionPolicy,
segmentInfos, infoStream, docWriter, synced);
if (deleter.startingCommitDeleted)
// Deletion policy deleted the "head" commit point.
// We have to mark ourself as changed so that if we
// are closed w/o any further changes we write a new
// segments_N file.
changeCount++;
pushMaxBufferedDocs();
if (infoStream != null) {
message("init: create=" + create);
messageState();
}
success = true;
} finally {
if (!success) {
if (infoStream != null) {
message("init: hit exception on init; releasing write lock");
}
try {
writeLock.release();
} catch (Throwable t) {
// don't mask the original exception
}
writeLock = null;
}