mirror of https://github.com/apache/lucene.git
LUCENE-1411: add expert API to IndexWriter to open an index for writing on an arbitrary commit
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@706171 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
da78e20bd0
commit
0250cccacf
|
@ -20,6 +20,14 @@ Bug fixes
|
||||||
|
|
||||||
New features
|
New features
|
||||||
|
|
||||||
|
1. LUCENE-1411: Added expert API to open an IndexWriter on a prior
|
||||||
|
commit, obtained from IndexReader.listCommits. This makes it
|
||||||
|
possible to rollback changes to an index even after you've closed
|
||||||
|
the IndexWriter that made the changes, assuming you are using an
|
||||||
|
IndexDeletionPolicy that keeps past commits around. This is useful
|
||||||
|
when building transactional support on top of Lucene. (Mike
|
||||||
|
McCandless)
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
|
|
|
@ -266,6 +266,7 @@ abstract class DirectoryIndexReader extends IndexReader {
|
||||||
// Have the deleter remove any now unreferenced
|
// Have the deleter remove any now unreferenced
|
||||||
// files due to this commit:
|
// files due to this commit:
|
||||||
deleter.checkpoint(segmentInfos, true);
|
deleter.checkpoint(segmentInfos, true);
|
||||||
|
deleter.close();
|
||||||
|
|
||||||
if (writeLock != null) {
|
if (writeLock != null) {
|
||||||
writeLock.release(); // release write lock
|
writeLock.release(); // release write lock
|
||||||
|
|
|
@ -122,10 +122,8 @@ final class IndexFileDeleter {
|
||||||
/**
|
/**
|
||||||
* Initialize the deleter: find all previous commits in
|
* Initialize the deleter: find all previous commits in
|
||||||
* the Directory, incref the files they reference, call
|
* the Directory, incref the files they reference, call
|
||||||
* the policy to let it delete commits. The incoming
|
* the policy to let it delete commits. This will remove
|
||||||
* segmentInfos must have been loaded from a commit point
|
* any files not referenced by any of the commits.
|
||||||
* and not yet modified. This will remove any files not
|
|
||||||
* referenced by any of the commits.
|
|
||||||
* @throws CorruptIndexException if the index is corrupt
|
* @throws CorruptIndexException if the index is corrupt
|
||||||
* @throws IOException if there is a low-level IO error
|
* @throws IOException if there is a low-level IO error
|
||||||
*/
|
*/
|
||||||
|
@ -242,12 +240,9 @@ final class IndexFileDeleter {
|
||||||
// startup:
|
// startup:
|
||||||
policy.onInit(commits);
|
policy.onInit(commits);
|
||||||
|
|
||||||
// It's OK for the onInit to remove the current commit
|
// Always protect the incoming segmentInfos since
|
||||||
// point; we just have to checkpoint our in-memory
|
// sometime it may not be the most recent commit
|
||||||
// SegmentInfos to protect those files that it uses:
|
checkpoint(segmentInfos, false);
|
||||||
if (currentCommitPoint.deleted) {
|
|
||||||
checkpoint(segmentInfos, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteCommits();
|
deleteCommits();
|
||||||
}
|
}
|
||||||
|
@ -341,6 +336,14 @@ final class IndexFileDeleter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
// DecRef old files from the last checkpoint, if any:
|
||||||
|
int size = lastFiles.size();
|
||||||
|
if (size > 0) {
|
||||||
|
for(int i=0;i<size;i++)
|
||||||
|
decRef((List) lastFiles.get(i));
|
||||||
|
lastFiles.clear();
|
||||||
|
}
|
||||||
|
|
||||||
deletePendingFiles();
|
deletePendingFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -548,7 +548,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(String path, Analyzer a, boolean create, MaxFieldLength mfl)
|
public IndexWriter(String path, Analyzer a, boolean create, MaxFieldLength mfl)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(FSDirectory.getDirectory(path), a, create, true, null, false, mfl.getLimit());
|
init(FSDirectory.getDirectory(path), a, create, true, null, false, mfl.getLimit(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -577,7 +577,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(String path, Analyzer a, boolean create)
|
public IndexWriter(String path, Analyzer a, boolean create)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(FSDirectory.getDirectory(path), a, create, true, null, true, DEFAULT_MAX_FIELD_LENGTH);
|
init(FSDirectory.getDirectory(path), a, create, true, null, true, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -608,7 +608,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(File path, Analyzer a, boolean create, MaxFieldLength mfl)
|
public IndexWriter(File path, Analyzer a, boolean create, MaxFieldLength mfl)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(FSDirectory.getDirectory(path), a, create, true, null, false, mfl.getLimit());
|
init(FSDirectory.getDirectory(path), a, create, true, null, false, mfl.getLimit(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -637,7 +637,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(File path, Analyzer a, boolean create)
|
public IndexWriter(File path, Analyzer a, boolean create)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(FSDirectory.getDirectory(path), a, create, true, null, true, DEFAULT_MAX_FIELD_LENGTH);
|
init(FSDirectory.getDirectory(path), a, create, true, null, true, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -668,7 +668,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, Analyzer a, boolean create, MaxFieldLength mfl)
|
public IndexWriter(Directory d, Analyzer a, boolean create, MaxFieldLength mfl)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, create, false, null, false, mfl.getLimit());
|
init(d, a, create, false, null, false, mfl.getLimit(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -696,7 +696,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, Analyzer a, boolean create)
|
public IndexWriter(Directory d, Analyzer a, boolean create)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, create, false, null, true, DEFAULT_MAX_FIELD_LENGTH);
|
init(d, a, create, false, null, true, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -723,7 +723,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(String path, Analyzer a, MaxFieldLength mfl)
|
public IndexWriter(String path, Analyzer a, MaxFieldLength mfl)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(FSDirectory.getDirectory(path), a, true, null, false, mfl.getLimit());
|
init(FSDirectory.getDirectory(path), a, true, null, false, mfl.getLimit(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -747,7 +747,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(String path, Analyzer a)
|
public IndexWriter(String path, Analyzer a)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(FSDirectory.getDirectory(path), a, true, null, true, DEFAULT_MAX_FIELD_LENGTH);
|
init(FSDirectory.getDirectory(path), a, true, null, true, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -774,7 +774,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(File path, Analyzer a, MaxFieldLength mfl)
|
public IndexWriter(File path, Analyzer a, MaxFieldLength mfl)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(FSDirectory.getDirectory(path), a, true, null, false, mfl.getLimit());
|
init(FSDirectory.getDirectory(path), a, true, null, false, mfl.getLimit(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -798,7 +798,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(File path, Analyzer a)
|
public IndexWriter(File path, Analyzer a)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(FSDirectory.getDirectory(path), a, true, null, true, DEFAULT_MAX_FIELD_LENGTH);
|
init(FSDirectory.getDirectory(path), a, true, null, true, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -825,7 +825,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, Analyzer a, MaxFieldLength mfl)
|
public IndexWriter(Directory d, Analyzer a, MaxFieldLength mfl)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, false, null, false, mfl.getLimit());
|
init(d, a, false, null, false, mfl.getLimit(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -850,7 +850,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, Analyzer a)
|
public IndexWriter(Directory d, Analyzer a)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, false, null, true, DEFAULT_MAX_FIELD_LENGTH);
|
init(d, a, false, null, true, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -876,7 +876,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, boolean autoCommit, Analyzer a)
|
public IndexWriter(Directory d, boolean autoCommit, Analyzer a)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, false, null, autoCommit, DEFAULT_MAX_FIELD_LENGTH);
|
init(d, a, false, null, autoCommit, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -906,7 +906,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, boolean autoCommit, Analyzer a, boolean create)
|
public IndexWriter(Directory d, boolean autoCommit, Analyzer a, boolean create)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, create, false, null, autoCommit, DEFAULT_MAX_FIELD_LENGTH);
|
init(d, a, create, false, null, autoCommit, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -933,7 +933,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, Analyzer a, IndexDeletionPolicy deletionPolicy, MaxFieldLength mfl)
|
public IndexWriter(Directory d, Analyzer a, IndexDeletionPolicy deletionPolicy, MaxFieldLength mfl)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, false, deletionPolicy, false, mfl.getLimit());
|
init(d, a, false, deletionPolicy, false, mfl.getLimit(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -960,7 +960,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, boolean autoCommit, Analyzer a, IndexDeletionPolicy deletionPolicy)
|
public IndexWriter(Directory d, boolean autoCommit, Analyzer a, IndexDeletionPolicy deletionPolicy)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, false, deletionPolicy, autoCommit, DEFAULT_MAX_FIELD_LENGTH);
|
init(d, a, false, deletionPolicy, autoCommit, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -993,7 +993,7 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, Analyzer a, boolean create, IndexDeletionPolicy deletionPolicy, MaxFieldLength mfl)
|
public IndexWriter(Directory d, Analyzer a, boolean create, IndexDeletionPolicy deletionPolicy, MaxFieldLength mfl)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, create, false, deletionPolicy, false, mfl.getLimit());
|
init(d, a, create, false, deletionPolicy, false, mfl.getLimit(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1015,9 +1015,10 @@ public class IndexWriter {
|
||||||
* the existing one; <code>false</code> to append to the existing
|
* the existing one; <code>false</code> to append to the existing
|
||||||
* index
|
* index
|
||||||
* @param deletionPolicy see <a href="#deletionPolicy">above</a>
|
* @param deletionPolicy see <a href="#deletionPolicy">above</a>
|
||||||
|
* @param mfl whether or not to limit field lengths
|
||||||
* @param indexingChain the {@link DocConsumer} chain to be used to
|
* @param indexingChain the {@link DocConsumer} chain to be used to
|
||||||
* process documents
|
* process documents
|
||||||
* @param mfl whether or not to limit field lengths
|
* @param commit which commit to open
|
||||||
* @throws CorruptIndexException if the index is corrupt
|
* @throws CorruptIndexException if the index is corrupt
|
||||||
* @throws LockObtainFailedException if another writer
|
* @throws LockObtainFailedException if another writer
|
||||||
* has this index open (<code>write.lock</code> could not
|
* has this index open (<code>write.lock</code> could not
|
||||||
|
@ -1027,9 +1028,9 @@ public class IndexWriter {
|
||||||
* <code>false</code> or if there is any other low-level
|
* <code>false</code> or if there is any other low-level
|
||||||
* IO error
|
* IO error
|
||||||
*/
|
*/
|
||||||
IndexWriter(Directory d, Analyzer a, boolean create, IndexDeletionPolicy deletionPolicy, MaxFieldLength mfl, IndexingChain indexingChain)
|
IndexWriter(Directory d, Analyzer a, boolean create, IndexDeletionPolicy deletionPolicy, MaxFieldLength mfl, IndexingChain indexingChain, IndexCommit commit)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, create, false, deletionPolicy, false, mfl.getLimit(), indexingChain);
|
init(d, a, create, false, deletionPolicy, false, mfl.getLimit(), indexingChain, commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1062,33 +1063,63 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public IndexWriter(Directory d, boolean autoCommit, Analyzer a, boolean create, IndexDeletionPolicy deletionPolicy)
|
public IndexWriter(Directory d, boolean autoCommit, Analyzer a, boolean create, IndexDeletionPolicy deletionPolicy)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
init(d, a, create, false, deletionPolicy, autoCommit, DEFAULT_MAX_FIELD_LENGTH);
|
init(d, a, create, false, deletionPolicy, autoCommit, DEFAULT_MAX_FIELD_LENGTH, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expert: constructs an IndexWriter on specific commit
|
||||||
|
* point, with a custom {@link IndexDeletionPolicy}, for
|
||||||
|
* the index in <code>d</code>. Text will be analyzed
|
||||||
|
* with <code>a</code>.
|
||||||
|
*
|
||||||
|
* <p> This is only meaningful if you've used a {@link
|
||||||
|
* IndexDeletionPolicy} in that past that keeps more than
|
||||||
|
* just the last commit.
|
||||||
|
*
|
||||||
|
* <p>This operation is similar to {@link #rollback()},
|
||||||
|
* except that method can only rollback what's been done
|
||||||
|
* with the current instance of IndexWriter since its last
|
||||||
|
* commit, whereas this method can rollback to an
|
||||||
|
* arbitrary commit point from the past, assuming the
|
||||||
|
* {@link IndexDeletionPolicy} has preserved past
|
||||||
|
* commits.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE</b>: autoCommit (see <a
|
||||||
|
* href="#autoCommit">above</a>) is set to false with this
|
||||||
|
* constructor.
|
||||||
|
*
|
||||||
|
* @param d the index directory
|
||||||
|
* @param a the analyzer to use
|
||||||
|
* @param deletionPolicy see <a href="#deletionPolicy">above</a>
|
||||||
|
* @param mfl whether or not to limit field lengths
|
||||||
|
* @param commit which commit to open
|
||||||
|
* @throws CorruptIndexException if the index is corrupt
|
||||||
|
* @throws LockObtainFailedException if another writer
|
||||||
|
* has this index open (<code>write.lock</code> could not
|
||||||
|
* be obtained)
|
||||||
|
* @throws IOException if the directory cannot be read/written to, or
|
||||||
|
* if it does not exist and <code>create</code> is
|
||||||
|
* <code>false</code> or if there is any other low-level
|
||||||
|
* IO error
|
||||||
|
*/
|
||||||
|
public IndexWriter(Directory d, Analyzer a, IndexDeletionPolicy deletionPolicy, MaxFieldLength mfl, IndexCommit commit)
|
||||||
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
|
init(d, a, false, false, deletionPolicy, false, mfl.getLimit(), null, commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init(Directory d, Analyzer a, boolean closeDir, IndexDeletionPolicy deletionPolicy,
|
private void init(Directory d, Analyzer a, boolean closeDir, IndexDeletionPolicy deletionPolicy,
|
||||||
boolean autoCommit, int maxFieldLength)
|
boolean autoCommit, int maxFieldLength, IndexingChain indexingChain, IndexCommit commit)
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
|
||||||
init(d, a, closeDir, deletionPolicy, autoCommit, maxFieldLength, DocumentsWriter.DefaultIndexingChain);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init(Directory d, Analyzer a, boolean closeDir, IndexDeletionPolicy deletionPolicy,
|
|
||||||
boolean autoCommit, int maxFieldLength, IndexingChain indexingChain)
|
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
if (IndexReader.indexExists(d)) {
|
if (IndexReader.indexExists(d)) {
|
||||||
init(d, a, false, closeDir, deletionPolicy, autoCommit, maxFieldLength, indexingChain);
|
init(d, a, false, closeDir, deletionPolicy, autoCommit, maxFieldLength, indexingChain, commit);
|
||||||
} else {
|
} else {
|
||||||
init(d, a, true, closeDir, deletionPolicy, autoCommit, maxFieldLength, indexingChain);
|
init(d, a, true, closeDir, deletionPolicy, autoCommit, maxFieldLength, indexingChain, commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init(Directory d, Analyzer a, final boolean create, boolean closeDir,
|
private void init(Directory d, Analyzer a, final boolean create, boolean closeDir,
|
||||||
IndexDeletionPolicy deletionPolicy, boolean autoCommit, int maxFieldLength)
|
IndexDeletionPolicy deletionPolicy, boolean autoCommit, int maxFieldLength,
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
IndexingChain indexingChain, IndexCommit commit)
|
||||||
init(d, a, create, closeDir, deletionPolicy, autoCommit, maxFieldLength, DocumentsWriter.DefaultIndexingChain);
|
|
||||||
}
|
|
||||||
private void init(Directory d, Analyzer a, final boolean create, boolean closeDir,
|
|
||||||
IndexDeletionPolicy deletionPolicy, boolean autoCommit, int maxFieldLength,
|
|
||||||
IndexingChain indexingChain)
|
|
||||||
throws CorruptIndexException, LockObtainFailedException, IOException {
|
throws CorruptIndexException, LockObtainFailedException, IOException {
|
||||||
this.closeDir = closeDir;
|
this.closeDir = closeDir;
|
||||||
directory = d;
|
directory = d;
|
||||||
|
@ -1096,6 +1127,9 @@ public class IndexWriter {
|
||||||
setMessageID(defaultInfoStream);
|
setMessageID(defaultInfoStream);
|
||||||
this.maxFieldLength = maxFieldLength;
|
this.maxFieldLength = maxFieldLength;
|
||||||
|
|
||||||
|
if (indexingChain == null)
|
||||||
|
indexingChain = DocumentsWriter.DefaultIndexingChain;
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
// Clear the write lock in case it's leftover:
|
// Clear the write lock in case it's leftover:
|
||||||
directory.clearLock(WRITE_LOCK_NAME);
|
directory.clearLock(WRITE_LOCK_NAME);
|
||||||
|
@ -1122,6 +1156,21 @@ public class IndexWriter {
|
||||||
} else {
|
} else {
|
||||||
segmentInfos.read(directory);
|
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++;
|
||||||
|
message("init: loaded commit \"" + commit.getSegmentsFileName() + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
// We assume that this segments_N was previously
|
// We assume that this segments_N was previously
|
||||||
// properly sync'd:
|
// properly sync'd:
|
||||||
for(int i=0;i<segmentInfos.size();i++) {
|
for(int i=0;i<segmentInfos.size();i++) {
|
||||||
|
@ -3461,6 +3510,7 @@ public class IndexWriter {
|
||||||
try {
|
try {
|
||||||
message("commit: pendingCommit != null");
|
message("commit: pendingCommit != null");
|
||||||
pendingCommit.finishCommit(directory);
|
pendingCommit.finishCommit(directory);
|
||||||
|
message("commit: wrote segments file \"" + pendingCommit.getCurrentSegmentFileName() + "\"");
|
||||||
lastCommitChangeCount = pendingCommitChangeCount;
|
lastCommitChangeCount = pendingCommitChangeCount;
|
||||||
segmentInfos.updateGeneration(pendingCommit);
|
segmentInfos.updateGeneration(pendingCommit);
|
||||||
setRollbackSegmentInfos(pendingCommit);
|
setRollbackSegmentInfos(pendingCommit);
|
||||||
|
|
|
@ -840,4 +840,14 @@ final class SegmentInfos extends Vector {
|
||||||
}
|
}
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Replaces all segments in this instance, but keeps
|
||||||
|
* generation, version, counter so that future commits
|
||||||
|
* remain write once.
|
||||||
|
*/
|
||||||
|
void replace(SegmentInfos other) {
|
||||||
|
clear();
|
||||||
|
addAll(other);
|
||||||
|
lastGeneration = other.lastGeneration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.lucene.search.ScoreDoc;
|
||||||
import org.apache.lucene.search.TermQuery;
|
import org.apache.lucene.search.TermQuery;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.store.RAMDirectory;
|
import org.apache.lucene.store.RAMDirectory;
|
||||||
|
import org.apache.lucene.store.MockRAMDirectory;
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -344,6 +345,108 @@ public class TestDeletionPolicy extends LuceneTestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Uses KeepAllDeletionPolicy to keep all commits around,
|
||||||
|
* then, opens a new IndexWriter on a previous commit
|
||||||
|
* point. */
|
||||||
|
public void testOpenPriorSnapshot() throws IOException {
|
||||||
|
|
||||||
|
// Never deletes a commit
|
||||||
|
KeepAllDeletionPolicy policy = new KeepAllDeletionPolicy();
|
||||||
|
|
||||||
|
Directory dir = new MockRAMDirectory();
|
||||||
|
policy.dir = dir;
|
||||||
|
|
||||||
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), policy, IndexWriter.MaxFieldLength.LIMITED);
|
||||||
|
writer.setMaxBufferedDocs(2);
|
||||||
|
for(int i=0;i<10;i++) {
|
||||||
|
addDoc(writer);
|
||||||
|
if ((1+i)%2 == 0)
|
||||||
|
writer.commit();
|
||||||
|
}
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
Collection commits = IndexReader.listCommits(dir);
|
||||||
|
assertEquals(6, commits.size());
|
||||||
|
IndexCommit lastCommit = null;
|
||||||
|
Iterator it = commits.iterator();
|
||||||
|
while(it.hasNext()) {
|
||||||
|
IndexCommit commit = (IndexCommit) it.next();
|
||||||
|
if (lastCommit == null || commit.getGeneration() > lastCommit.getGeneration())
|
||||||
|
lastCommit = commit;
|
||||||
|
}
|
||||||
|
assertTrue(lastCommit != null);
|
||||||
|
|
||||||
|
// Now add 1 doc and optimize
|
||||||
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), policy, IndexWriter.MaxFieldLength.LIMITED);
|
||||||
|
addDoc(writer);
|
||||||
|
assertEquals(11, writer.numDocs());
|
||||||
|
writer.optimize();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
assertEquals(7, IndexReader.listCommits(dir).size());
|
||||||
|
|
||||||
|
// Now open writer on the commit just before optimize:
|
||||||
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), policy, IndexWriter.MaxFieldLength.LIMITED, lastCommit);
|
||||||
|
assertEquals(10, writer.numDocs());
|
||||||
|
|
||||||
|
// Should undo our rollback:
|
||||||
|
writer.rollback();
|
||||||
|
|
||||||
|
IndexReader r = IndexReader.open(dir);
|
||||||
|
// Still optimized, still 11 docs
|
||||||
|
assertTrue(r.isOptimized());
|
||||||
|
assertEquals(11, r.numDocs());
|
||||||
|
r.close();
|
||||||
|
|
||||||
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), policy, IndexWriter.MaxFieldLength.LIMITED, lastCommit);
|
||||||
|
assertEquals(10, writer.numDocs());
|
||||||
|
// Commits the rollback:
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
// Now 8 because we made another commit
|
||||||
|
assertEquals(8, IndexReader.listCommits(dir).size());
|
||||||
|
|
||||||
|
r = IndexReader.open(dir);
|
||||||
|
// Not optimized because we rolled it back, and now only
|
||||||
|
// 10 docs
|
||||||
|
assertTrue(!r.isOptimized());
|
||||||
|
assertEquals(10, r.numDocs());
|
||||||
|
r.close();
|
||||||
|
|
||||||
|
// Reoptimize
|
||||||
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), policy, IndexWriter.MaxFieldLength.LIMITED);
|
||||||
|
writer.optimize();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
r = IndexReader.open(dir);
|
||||||
|
assertTrue(r.isOptimized());
|
||||||
|
assertEquals(10, r.numDocs());
|
||||||
|
r.close();
|
||||||
|
|
||||||
|
// Now open writer on the commit just before optimize,
|
||||||
|
// but this time keeping only the last commit:
|
||||||
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), new KeepOnlyLastCommitDeletionPolicy(), IndexWriter.MaxFieldLength.LIMITED, lastCommit);
|
||||||
|
assertEquals(10, writer.numDocs());
|
||||||
|
|
||||||
|
// Reader still sees optimized index, because writer
|
||||||
|
// opened on the prior commit has not yet committed:
|
||||||
|
r = IndexReader.open(dir);
|
||||||
|
assertTrue(r.isOptimized());
|
||||||
|
assertEquals(10, r.numDocs());
|
||||||
|
r.close();
|
||||||
|
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
// Now reader sees unoptimized index:
|
||||||
|
r = IndexReader.open(dir);
|
||||||
|
assertTrue(!r.isOptimized());
|
||||||
|
assertEquals(10, r.numDocs());
|
||||||
|
r.close();
|
||||||
|
|
||||||
|
dir.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Test keeping NO commit points. This is a viable and
|
/* Test keeping NO commit points. This is a viable and
|
||||||
* useful case eg where you want to build a big index with
|
* useful case eg where you want to build a big index with
|
||||||
* autoCommit false and you know there are no readers.
|
* autoCommit false and you know there are no readers.
|
||||||
|
|
Loading…
Reference in New Issue