mirror of https://github.com/apache/lucene.git
LUCENE-4575: add IndexWriter.setCommitData
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1416361 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b9917b5f0c
commit
afc68d0a52
|
@ -59,6 +59,11 @@ Changes in backwards compatibility policy
|
|||
invalidated on reopen if even a single delete was posted against the segment).
|
||||
(Robert Muir)
|
||||
|
||||
* LUCENE-4575: Replace IndexWriter's commit/prepareCommit versions that take
|
||||
commitData with setCommitData(). That allows committing changes to IndexWriter
|
||||
even if the commitData is the only thing that changes.
|
||||
(Shai Erera, Michael McCandless)
|
||||
|
||||
New Features
|
||||
|
||||
* LUCENE-4226: New experimental StoredFieldsFormat that compresses chunks of
|
||||
|
|
|
@ -49,7 +49,8 @@ public class CommitIndexTask extends PerfTask {
|
|||
public int doLogic() throws Exception {
|
||||
IndexWriter iw = getRunData().getIndexWriter();
|
||||
if (iw != null) {
|
||||
iw.commit(commitUserData);
|
||||
iw.setCommitData(commitUserData);
|
||||
iw.commit();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -107,7 +107,7 @@ public abstract class IndexCommit implements Comparable<IndexCommit> {
|
|||
public abstract long getGeneration();
|
||||
|
||||
/** Returns userData, previously passed to {@link
|
||||
* IndexWriter#commit(Map)} for this commit. Map is
|
||||
* IndexWriter#setCommitData(Map)} for this commit. Map is
|
||||
* String -> String. */
|
||||
public abstract Map<String,String> getUserData() throws IOException;
|
||||
|
||||
|
|
|
@ -540,15 +540,15 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
}
|
||||
|
||||
/**
|
||||
* Used internally to throw an {@link
|
||||
* AlreadyClosedException} if this IndexWriter has been
|
||||
* closed.
|
||||
* @param failIfClosing if true, also fail when
|
||||
* {@code IndexWriter} is in the process of closing
|
||||
* ({@code closing=true}) but not yet done closing ({@code
|
||||
* closed=false})
|
||||
* @throws AlreadyClosedException if this IndexWriter is
|
||||
* closed
|
||||
* Used internally to throw an {@link AlreadyClosedException} if this
|
||||
* IndexWriter has been closed or is in the process of closing.
|
||||
*
|
||||
* @param failIfClosing
|
||||
* if true, also fail when {@code IndexWriter} is in the process of
|
||||
* closing ({@code closing=true}) but not yet done closing (
|
||||
* {@code closed=false})
|
||||
* @throws AlreadyClosedException
|
||||
* if this IndexWriter is closed or in the process of closing
|
||||
*/
|
||||
protected final void ensureOpen(boolean failIfClosing) throws AlreadyClosedException {
|
||||
if (closed || (failIfClosing && closing)) {
|
||||
|
@ -960,7 +960,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
}
|
||||
|
||||
if (doFlush) {
|
||||
commitInternal(null);
|
||||
commitInternal();
|
||||
}
|
||||
|
||||
if (infoStream.isEnabled("IW")) {
|
||||
|
@ -2559,20 +2559,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
*/
|
||||
protected void doBeforeFlush() throws IOException {}
|
||||
|
||||
/** Expert: prepare for commit.
|
||||
*
|
||||
* <p><b>NOTE</b>: if this method hits an OutOfMemoryError
|
||||
* you should immediately close the writer. See <a
|
||||
* href="#OOME">above</a> for details.</p>
|
||||
*
|
||||
* @see #prepareCommit(Map) */
|
||||
public final void prepareCommit() throws IOException {
|
||||
ensureOpen();
|
||||
prepareCommit(null);
|
||||
}
|
||||
|
||||
/** <p>Expert: prepare for commit, specifying
|
||||
* commitUserData Map (String -> String). This does the
|
||||
/** <p>Expert: prepare for commit. This does the
|
||||
* first phase of 2-phase commit. This method does all
|
||||
* steps necessary to commit changes since this writer
|
||||
* was opened: flushes pending added and deleted docs,
|
||||
|
@ -2582,29 +2569,22 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
* #rollback()} to revert the commit and undo all changes
|
||||
* done since the writer was opened.</p>
|
||||
*
|
||||
* <p>You can also just call {@link #commit(Map)} directly
|
||||
* <p>You can also just call {@link #commit()} directly
|
||||
* without prepareCommit first in which case that method
|
||||
* will internally call prepareCommit.
|
||||
*
|
||||
* <p><b>NOTE</b>: if this method hits an OutOfMemoryError
|
||||
* you should immediately close the writer. See <a
|
||||
* href="#OOME">above</a> for details.</p>
|
||||
*
|
||||
* @param commitUserData Opaque Map (String->String)
|
||||
* that's recorded into the segments file in the index,
|
||||
* and retrievable by {@link
|
||||
* IndexCommit#getUserData}. Note that when
|
||||
* IndexWriter commits itself during {@link #close}, the
|
||||
* commitUserData is unchanged (just carried over from
|
||||
* the prior commit). If this is null then the previous
|
||||
* commitUserData is kept. Also, the commitUserData will
|
||||
* only "stick" if there are actually changes in the
|
||||
* index to commit.
|
||||
*/
|
||||
public final void prepareCommit(Map<String,String> commitUserData) throws IOException {
|
||||
ensureOpen(false);
|
||||
public final void prepareCommit() throws IOException {
|
||||
ensureOpen();
|
||||
prepareCommitInternal();
|
||||
}
|
||||
|
||||
private void prepareCommitInternal() throws IOException {
|
||||
synchronized(commitLock) {
|
||||
ensureOpen(false);
|
||||
if (infoStream.isEnabled("IW")) {
|
||||
infoStream.message("IW", "prepareCommit: flush");
|
||||
infoStream.message("IW", " index before flush " + segString());
|
||||
|
@ -2694,10 +2674,33 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
}
|
||||
}
|
||||
|
||||
startCommit(toCommit, commitUserData);
|
||||
startCommit(toCommit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the commit user data map. That method is considered a transaction by
|
||||
* {@link IndexWriter} and will be {@link #commit() committed} even if no other
|
||||
* changes were made to the writer instance. Note that you must call this method
|
||||
* before {@link #prepareCommit()}, or otherwise it won't be included in the
|
||||
* follow-on {@link #commit()}.
|
||||
* <p>
|
||||
* <b>NOTE:</b> the map is cloned internally, therefore altering the map's
|
||||
* contents after calling this method has no effect.
|
||||
*/
|
||||
public final synchronized void setCommitData(Map<String,String> commitUserData) {
|
||||
segmentInfos.setUserData(new HashMap<String,String>(commitUserData));
|
||||
++changeCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the commit user data map that was last committed, or the one that
|
||||
* was set on {@link #setCommitData(Map)}.
|
||||
*/
|
||||
public final synchronized Map<String,String> getCommitData() {
|
||||
return segmentInfos.getUserData();
|
||||
}
|
||||
|
||||
// Used only by commit and prepareCommit, below; lock
|
||||
// order is commitLock -> IW
|
||||
private final Object commitLock = new Object();
|
||||
|
@ -2730,29 +2733,13 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
* href="#OOME">above</a> for details.</p>
|
||||
*
|
||||
* @see #prepareCommit
|
||||
* @see #commit(Map)
|
||||
*/
|
||||
public final void commit() throws IOException {
|
||||
commit(null);
|
||||
}
|
||||
|
||||
/** Commits all changes to the index, specifying a
|
||||
* commitUserData Map (String -> String). This just
|
||||
* calls {@link #prepareCommit(Map)} (if you didn't
|
||||
* already call it) and then {@link #commit}.
|
||||
*
|
||||
* <p><b>NOTE</b>: if this method hits an OutOfMemoryError
|
||||
* you should immediately close the writer. See <a
|
||||
* href="#OOME">above</a> for details.</p>
|
||||
*/
|
||||
public final void commit(Map<String,String> commitUserData) throws IOException {
|
||||
|
||||
ensureOpen();
|
||||
|
||||
commitInternal(commitUserData);
|
||||
commitInternal();
|
||||
}
|
||||
|
||||
private final void commitInternal(Map<String,String> commitUserData) throws IOException {
|
||||
private final void commitInternal() throws IOException {
|
||||
|
||||
if (infoStream.isEnabled("IW")) {
|
||||
infoStream.message("IW", "commit: start");
|
||||
|
@ -2769,7 +2756,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
if (infoStream.isEnabled("IW")) {
|
||||
infoStream.message("IW", "commit: now prepare");
|
||||
}
|
||||
prepareCommit(commitUserData);
|
||||
prepareCommitInternal();
|
||||
} else {
|
||||
if (infoStream.isEnabled("IW")) {
|
||||
infoStream.message("IW", "commit: already prepared");
|
||||
|
@ -2793,7 +2780,6 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
}
|
||||
lastCommitChangeCount = pendingCommitChangeCount;
|
||||
segmentInfos.updateGeneration(pendingCommit);
|
||||
segmentInfos.setUserData(pendingCommit.getUserData());
|
||||
rollbackSegments = pendingCommit.createBackupSegmentInfos();
|
||||
deleter.checkpoint(pendingCommit, true);
|
||||
} finally {
|
||||
|
@ -3912,7 +3898,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
* if it wasn't already. If that succeeds, then we
|
||||
* prepare a new segments_N file but do not fully commit
|
||||
* it. */
|
||||
private void startCommit(final SegmentInfos toSync, final Map<String,String> commitUserData) throws IOException {
|
||||
private void startCommit(final SegmentInfos toSync) throws IOException {
|
||||
|
||||
assert testPoint("startStartCommit");
|
||||
assert pendingCommit == null;
|
||||
|
@ -3945,10 +3931,6 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
|
|||
}
|
||||
|
||||
assert filesExist(toSync);
|
||||
|
||||
if (commitUserData != null) {
|
||||
toSync.setUserData(commitUserData);
|
||||
}
|
||||
}
|
||||
|
||||
assert testPoint("midStartCommit");
|
||||
|
|
|
@ -103,8 +103,8 @@ import org.apache.lucene.util.ThreadInterruptedException;
|
|||
* <li>SegCodec is the {@link Codec#getName() name} of the Codec that encoded
|
||||
* this segment.</li>
|
||||
* <li>CommitUserData stores an optional user-supplied opaque
|
||||
* Map<String,String> that was passed to {@link IndexWriter#commit(java.util.Map)}
|
||||
* or {@link IndexWriter#prepareCommit(java.util.Map)}.</li>
|
||||
* Map<String,String> that was passed to
|
||||
* {@link IndexWriter#setCommitData(java.util.Map)}.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
|
@ -903,7 +903,7 @@ public final class SegmentInfos implements Cloneable, Iterable<SegmentInfoPerCom
|
|||
|
||||
/** Return {@code userData} saved with this commit.
|
||||
*
|
||||
* @see IndexWriter#commit(Map)
|
||||
* @see IndexWriter#commit()
|
||||
*/
|
||||
public Map<String,String> getUserData() {
|
||||
return userData;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.apache.lucene.index;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
|
@ -37,18 +36,6 @@ public interface TwoPhaseCommit {
|
|||
*/
|
||||
public void prepareCommit() throws IOException;
|
||||
|
||||
/**
|
||||
* Like {@link #commit()}, but takes an additional commit data to be included
|
||||
* w/ the commit.
|
||||
* <p>
|
||||
* <b>NOTE:</b> some implementations may not support any custom data to be
|
||||
* included w/ the commit and may discard it altogether. Consult the actual
|
||||
* implementation documentation for verifying if this is supported.
|
||||
*
|
||||
* @see #prepareCommit()
|
||||
*/
|
||||
public void prepareCommit(Map<String, String> commitData) throws IOException;
|
||||
|
||||
/**
|
||||
* The second phase of a 2-phase commit. Implementations should ideally do
|
||||
* very little work in this method (following {@link #prepareCommit()}, and
|
||||
|
@ -57,15 +44,6 @@ public interface TwoPhaseCommit {
|
|||
*/
|
||||
public void commit() throws IOException;
|
||||
|
||||
/**
|
||||
* Like {@link #commit()}, but takes an additional commit data to be included
|
||||
* w/ the commit.
|
||||
*
|
||||
* @see #commit()
|
||||
* @see #prepareCommit(Map)
|
||||
*/
|
||||
public void commit(Map<String, String> commitData) throws IOException;
|
||||
|
||||
/**
|
||||
* Discards any changes that have occurred since the last commit. In a 2-phase
|
||||
* commit algorithm, where one of the objects failed to {@link #commit()} or
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.apache.lucene.index;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
|
@ -31,44 +30,6 @@ public final class TwoPhaseCommitTool {
|
|||
/** No instance */
|
||||
private TwoPhaseCommitTool() {}
|
||||
|
||||
/**
|
||||
* A wrapper of a {@link TwoPhaseCommit}, which delegates all calls to the
|
||||
* wrapped object, passing the specified commitData. This object is useful for
|
||||
* use with {@link TwoPhaseCommitTool#execute(TwoPhaseCommit...)} if one would
|
||||
* like to store commitData as part of the commit.
|
||||
*/
|
||||
public static final class TwoPhaseCommitWrapper implements TwoPhaseCommit {
|
||||
|
||||
private final TwoPhaseCommit tpc;
|
||||
private final Map<String, String> commitData;
|
||||
|
||||
/** Sole constructor. */
|
||||
public TwoPhaseCommitWrapper(TwoPhaseCommit tpc, Map<String, String> commitData) {
|
||||
this.tpc = tpc;
|
||||
this.commitData = commitData;
|
||||
}
|
||||
|
||||
public void prepareCommit() throws IOException {
|
||||
prepareCommit(commitData);
|
||||
}
|
||||
|
||||
public void prepareCommit(Map<String, String> commitData) throws IOException {
|
||||
tpc.prepareCommit(this.commitData);
|
||||
}
|
||||
|
||||
public void commit() throws IOException {
|
||||
commit(commitData);
|
||||
}
|
||||
|
||||
public void commit(Map<String, String> commitData) throws IOException {
|
||||
tpc.commit(this.commitData);
|
||||
}
|
||||
|
||||
public void rollback() throws IOException {
|
||||
tpc.rollback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown by {@link TwoPhaseCommitTool#execute(TwoPhaseCommit...)} when an
|
||||
* object fails to prepareCommit().
|
||||
|
|
|
@ -212,7 +212,8 @@ public class TestDeletionPolicy extends LuceneTestCase {
|
|||
IndexWriter writer = new IndexWriter(dir, conf);
|
||||
Map<String,String> commitData = new HashMap<String,String>();
|
||||
commitData.put("commitTime", String.valueOf(System.currentTimeMillis()));
|
||||
writer.commit(commitData);
|
||||
writer.setCommitData(commitData);
|
||||
writer.commit();
|
||||
writer.close();
|
||||
|
||||
long lastDeleteTime = 0;
|
||||
|
@ -234,7 +235,8 @@ public class TestDeletionPolicy extends LuceneTestCase {
|
|||
}
|
||||
commitData = new HashMap<String,String>();
|
||||
commitData.put("commitTime", String.valueOf(System.currentTimeMillis()));
|
||||
writer.commit(commitData);
|
||||
writer.setCommitData(commitData);
|
||||
writer.commit();
|
||||
writer.close();
|
||||
|
||||
Thread.sleep((int) (1000.0*(SECONDS/5.0)));
|
||||
|
|
|
@ -554,13 +554,15 @@ public class TestDirectoryReaderReopen extends LuceneTestCase {
|
|||
writer.addDocument(doc);
|
||||
Map<String,String> data = new HashMap<String,String>();
|
||||
data.put("index", i+"");
|
||||
writer.commit(data);
|
||||
writer.setCommitData(data);
|
||||
writer.commit();
|
||||
}
|
||||
for(int i=0;i<4;i++) {
|
||||
writer.deleteDocuments(new Term("id", ""+i));
|
||||
Map<String,String> data = new HashMap<String,String>();
|
||||
data.put("index", (4+i)+"");
|
||||
writer.commit(data);
|
||||
writer.setCommitData(data);
|
||||
writer.commit();
|
||||
}
|
||||
writer.close();
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.io.Reader;
|
|||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -60,6 +61,7 @@ import org.apache.lucene.util.LuceneTestCase;
|
|||
import org.apache.lucene.util.ThreadInterruptedException;
|
||||
import org.apache.lucene.util._TestUtil;
|
||||
import org.apache.lucene.util.packed.PackedInts;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestIndexWriter extends LuceneTestCase {
|
||||
|
||||
|
@ -1932,4 +1934,65 @@ public class TestIndexWriter extends LuceneTestCase {
|
|||
w.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
// LUCENE-4575
|
||||
public void testCommitWithUserDataOnly() throws Exception {
|
||||
Directory dir = newDirectory();
|
||||
IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, null));
|
||||
writer.commit(); // first commit to complete IW create transaction.
|
||||
|
||||
// this should store the commit data, even though no other changes were made
|
||||
writer.setCommitData(new HashMap<String,String>() {{
|
||||
put("key", "value");
|
||||
}});
|
||||
writer.commit();
|
||||
|
||||
DirectoryReader r = DirectoryReader.open(dir);
|
||||
assertEquals("value", r.getIndexCommit().getUserData().get("key"));
|
||||
r.close();
|
||||
|
||||
// now check setCommitData and prepareCommit/commit sequence
|
||||
writer.setCommitData(new HashMap<String,String>() {{
|
||||
put("key", "value1");
|
||||
}});
|
||||
writer.prepareCommit();
|
||||
writer.setCommitData(new HashMap<String,String>() {{
|
||||
put("key", "value2");
|
||||
}});
|
||||
writer.commit(); // should commit the first commitData only, per protocol
|
||||
|
||||
r = DirectoryReader.open(dir);
|
||||
assertEquals("value1", r.getIndexCommit().getUserData().get("key"));
|
||||
r.close();
|
||||
|
||||
// now should commit the second commitData - there was a bug where
|
||||
// IndexWriter.finishCommit overrode the second commitData
|
||||
writer.commit();
|
||||
r = DirectoryReader.open(dir);
|
||||
assertEquals("IndexWriter.finishCommit may have overridden the second commitData",
|
||||
"value2", r.getIndexCommit().getUserData().get("key"));
|
||||
r.close();
|
||||
|
||||
writer.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommitData() throws Exception {
|
||||
Directory dir = newDirectory();
|
||||
IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, null));
|
||||
writer.setCommitData(new HashMap<String,String>() {{
|
||||
put("key", "value");
|
||||
}});
|
||||
assertEquals("value", writer.getCommitData().get("key"));
|
||||
writer.close();
|
||||
|
||||
// validate that it's also visible when opening a new IndexWriter
|
||||
writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, null).setOpenMode(OpenMode.APPEND));
|
||||
assertEquals("value", writer.getCommitData().get("key"));
|
||||
writer.close();
|
||||
|
||||
dir.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -428,12 +428,13 @@ public class TestIndexWriterCommit extends LuceneTestCase {
|
|||
// commit to "first"
|
||||
Map<String,String> commitData = new HashMap<String,String>();
|
||||
commitData.put("tag", "first");
|
||||
w.commit(commitData);
|
||||
w.setCommitData(commitData);
|
||||
w.commit();
|
||||
|
||||
// commit to "second"
|
||||
w.addDocument(doc);
|
||||
commitData.put("tag", "second");
|
||||
w.commit(commitData);
|
||||
w.setCommitData(commitData);
|
||||
w.close();
|
||||
|
||||
// open "first" with IndexWriter
|
||||
|
@ -454,7 +455,7 @@ public class TestIndexWriterCommit extends LuceneTestCase {
|
|||
// commit IndexWriter to "third"
|
||||
w.addDocument(doc);
|
||||
commitData.put("tag", "third");
|
||||
w.commit(commitData);
|
||||
w.setCommitData(commitData);
|
||||
w.close();
|
||||
|
||||
// make sure "second" commit is still there
|
||||
|
@ -635,7 +636,7 @@ public class TestIndexWriterCommit extends LuceneTestCase {
|
|||
TestIndexWriter.addDoc(w);
|
||||
Map<String,String> data = new HashMap<String,String>();
|
||||
data.put("label", "test1");
|
||||
w.commit(data);
|
||||
w.setCommitData(data);
|
||||
w.close();
|
||||
|
||||
r = DirectoryReader.open(dir);
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.apache.lucene.analysis.MockAnalyzer;
|
|||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.MockDirectoryWrapper;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
||||
|
@ -72,7 +71,7 @@ public class TestTransactionRollback extends LuceneTestCase {
|
|||
new RollbackDeletionPolicy(id)).setIndexCommit(last));
|
||||
Map<String,String> data = new HashMap<String,String>();
|
||||
data.put("index", "Rolled back to 1-"+id);
|
||||
w.commit(data);
|
||||
w.setCommitData(data);
|
||||
w.close();
|
||||
}
|
||||
|
||||
|
@ -142,7 +141,8 @@ public class TestTransactionRollback extends LuceneTestCase {
|
|||
if (currentRecordId%10 == 0) {
|
||||
Map<String,String> data = new HashMap<String,String>();
|
||||
data.put("index", "records 1-"+currentRecordId);
|
||||
w.commit(data);
|
||||
w.setCommitData(data);
|
||||
w.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,8 @@ package org.apache.lucene.index;
|
|||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.lucene.index.TwoPhaseCommitTool.TwoPhaseCommitWrapper;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
||||
public class TestTwoPhaseCommitTool extends LuceneTestCase {
|
||||
|
@ -117,27 +115,6 @@ public class TestTwoPhaseCommitTool extends LuceneTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testWrapper() throws Exception {
|
||||
// tests that TwoPhaseCommitWrapper delegates prepare/commit w/ commitData
|
||||
TwoPhaseCommitImpl impl = new TwoPhaseCommitImpl(false, false, false);
|
||||
HashMap<String, String> commitData = new HashMap<String, String>();
|
||||
TwoPhaseCommitWrapper wrapper = new TwoPhaseCommitWrapper(impl, commitData);
|
||||
|
||||
wrapper.prepareCommit();
|
||||
assertSame(commitData, impl.prepareCommitData);
|
||||
|
||||
// wrapper should ignore passed commitData
|
||||
wrapper.prepareCommit(new HashMap<String, String>());
|
||||
assertSame(commitData, impl.prepareCommitData);
|
||||
|
||||
wrapper.commit();
|
||||
assertSame(commitData, impl.commitData);
|
||||
|
||||
// wrapper should ignore passed commitData
|
||||
wrapper.commit(new HashMap<String, String>());
|
||||
assertSame(commitData, impl.commitData);
|
||||
}
|
||||
|
||||
public void testNullTPCs() throws Exception {
|
||||
int numObjects = random().nextInt(4) + 3; // between [3, 6]
|
||||
TwoPhaseCommit[] tpcs = new TwoPhaseCommit[numObjects];
|
||||
|
|
|
@ -176,7 +176,7 @@ public abstract class TaxonomyReader implements Closeable {
|
|||
/**
|
||||
* Retrieve user committed data.
|
||||
*
|
||||
* @see TaxonomyWriter#commit(Map)
|
||||
* @see TaxonomyWriter#setCommitData(Map)
|
||||
*/
|
||||
public abstract Map<String, String> getCommitUserData() throws IOException;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.apache.lucene.facet.taxonomy;
|
|||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.lucene.index.TwoPhaseCommit;
|
||||
|
||||
|
@ -104,4 +105,20 @@ public interface TaxonomyWriter extends Closeable, TwoPhaseCommit {
|
|||
*/
|
||||
public int getSize();
|
||||
|
||||
/**
|
||||
* Sets the commit user data map. That method is considered a transaction and
|
||||
* will be {@link #commit() committed} even if no other changes were made to
|
||||
* the writer instance.
|
||||
* <p>
|
||||
* <b>NOTE:</b> the map is cloned internally, therefore altering the map's
|
||||
* contents after calling this method has no effect.
|
||||
*/
|
||||
public void setCommitData(Map<String,String> commitUserData);
|
||||
|
||||
/**
|
||||
* Returns the commit user data map that was set on
|
||||
* {@link #setCommitData(Map)}.
|
||||
*/
|
||||
public Map<String,String> getCommitData();
|
||||
|
||||
}
|
||||
|
|
|
@ -129,6 +129,8 @@ public class DirectoryTaxonomyWriter implements TaxonomyWriter {
|
|||
private volatile ParentArray parentArray;
|
||||
private volatile int nextID;
|
||||
|
||||
// private Map<String,String> commitData;
|
||||
|
||||
/** Reads the commit data from a Directory. */
|
||||
private static Map<String, String> readCommitData(Directory dir) throws IOException {
|
||||
SegmentInfos infos = new SegmentInfos();
|
||||
|
@ -353,7 +355,8 @@ public class DirectoryTaxonomyWriter implements TaxonomyWriter {
|
|||
@Override
|
||||
public synchronized void close() throws IOException {
|
||||
if (!isClosed) {
|
||||
indexWriter.commit(combinedCommitData(null));
|
||||
indexWriter.setCommitData(combinedCommitData(indexWriter.getCommitData()));
|
||||
indexWriter.commit();
|
||||
doClose();
|
||||
}
|
||||
}
|
||||
|
@ -660,39 +663,31 @@ public class DirectoryTaxonomyWriter implements TaxonomyWriter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling commit() ensures that all the categories written so far are
|
||||
* visible to a reader that is opened (or reopened) after that call.
|
||||
* When the index is closed(), commit() is also implicitly done.
|
||||
* See {@link TaxonomyWriter#commit()}
|
||||
*/
|
||||
@Override
|
||||
public synchronized void commit() throws IOException {
|
||||
ensureOpen();
|
||||
indexWriter.commit(combinedCommitData(null));
|
||||
indexWriter.setCommitData(combinedCommitData(indexWriter.getCommitData()));
|
||||
indexWriter.commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine original user data with that of the taxonomy creation time
|
||||
*/
|
||||
private Map<String,String> combinedCommitData(Map<String,String> userData) {
|
||||
/** Combine original user data with the taxonomy epoch. */
|
||||
private Map<String,String> combinedCommitData(Map<String,String> commitData) {
|
||||
Map<String,String> m = new HashMap<String, String>();
|
||||
if (userData != null) {
|
||||
m.putAll(userData);
|
||||
if (commitData != null) {
|
||||
m.putAll(commitData);
|
||||
}
|
||||
m.put(INDEX_EPOCH, Long.toString(indexEpoch));
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like commit(), but also store properties with the index. These properties
|
||||
* are retrievable by {@link DirectoryTaxonomyReader#getCommitUserData}.
|
||||
* See {@link TaxonomyWriter#commit(Map)}.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void commit(Map<String,String> commitUserData) throws IOException {
|
||||
ensureOpen();
|
||||
indexWriter.commit(combinedCommitData(commitUserData));
|
||||
public void setCommitData(Map<String,String> commitUserData) {
|
||||
indexWriter.setCommitData(combinedCommitData(commitUserData));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String,String> getCommitData() {
|
||||
return combinedCommitData(indexWriter.getCommitData());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -702,17 +697,8 @@ public class DirectoryTaxonomyWriter implements TaxonomyWriter {
|
|||
@Override
|
||||
public synchronized void prepareCommit() throws IOException {
|
||||
ensureOpen();
|
||||
indexWriter.prepareCommit(combinedCommitData(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Like above, and also prepares to store user data with the index.
|
||||
* See {@link IndexWriter#prepareCommit(Map)}
|
||||
*/
|
||||
@Override
|
||||
public synchronized void prepareCommit(Map<String,String> commitUserData) throws IOException {
|
||||
ensureOpen();
|
||||
indexWriter.prepareCommit(combinedCommitData(commitUserData));
|
||||
indexWriter.setCommitData(combinedCommitData(indexWriter.getCommitData()));
|
||||
indexWriter.prepareCommit();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -87,9 +87,9 @@ public class TestDirectoryTaxonomyWriter extends LuceneTestCase {
|
|||
DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(dir, OpenMode.CREATE_OR_APPEND, NO_OP_CACHE);
|
||||
taxoWriter.addCategory(new CategoryPath("a"));
|
||||
taxoWriter.addCategory(new CategoryPath("b"));
|
||||
Map <String, String> userCommitData = new HashMap<String, String>();
|
||||
Map<String, String> userCommitData = new HashMap<String, String>();
|
||||
userCommitData.put("testing", "1 2 3");
|
||||
taxoWriter.commit(userCommitData);
|
||||
taxoWriter.setCommitData(userCommitData);
|
||||
taxoWriter.close();
|
||||
DirectoryReader r = DirectoryReader.open(dir);
|
||||
assertEquals("2 categories plus root should have been committed to the underlying directory", 3, r.numDocs());
|
||||
|
@ -104,9 +104,14 @@ public class TestDirectoryTaxonomyWriter extends LuceneTestCase {
|
|||
// that the taxonomy index has been recreated.
|
||||
taxoWriter = new DirectoryTaxonomyWriter(dir, OpenMode.CREATE_OR_APPEND, NO_OP_CACHE);
|
||||
taxoWriter.addCategory(new CategoryPath("c")); // add a category so that commit will happen
|
||||
taxoWriter.commit(new HashMap<String, String>(){{
|
||||
taxoWriter.setCommitData(new HashMap<String, String>(){{
|
||||
put("just", "data");
|
||||
}});
|
||||
taxoWriter.commit();
|
||||
|
||||
// verify taxoWriter.getCommitData()
|
||||
assertNotNull(DirectoryTaxonomyWriter.INDEX_EPOCH
|
||||
+ " not found in taoxWriter.commitData", taxoWriter.getCommitData().get(DirectoryTaxonomyWriter.INDEX_EPOCH));
|
||||
taxoWriter.close();
|
||||
|
||||
r = DirectoryReader.open(dir);
|
||||
|
@ -163,9 +168,10 @@ public class TestDirectoryTaxonomyWriter extends LuceneTestCase {
|
|||
|
||||
private void touchTaxo(DirectoryTaxonomyWriter taxoWriter, CategoryPath cp) throws IOException {
|
||||
taxoWriter.addCategory(cp);
|
||||
taxoWriter.commit(new HashMap<String, String>(){{
|
||||
taxoWriter.setCommitData(new HashMap<String, String>(){{
|
||||
put("just", "data");
|
||||
}});
|
||||
taxoWriter.commit();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -449,8 +449,8 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
|
|||
final Map<String,String> commitData = new HashMap<String,String>();
|
||||
commitData.put(SolrIndexWriter.COMMIT_TIME_MSEC_KEY,
|
||||
String.valueOf(System.currentTimeMillis()));
|
||||
|
||||
iw.get().prepareCommit(commitData);
|
||||
iw.get().setCommitData(commitData);
|
||||
iw.get().prepareCommit();
|
||||
} finally {
|
||||
iw.decref();
|
||||
}
|
||||
|
@ -525,7 +525,8 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
|
|||
final Map<String,String> commitData = new HashMap<String,String>();
|
||||
commitData.put(SolrIndexWriter.COMMIT_TIME_MSEC_KEY,
|
||||
String.valueOf(System.currentTimeMillis()));
|
||||
writer.commit(commitData);
|
||||
writer.setCommitData(commitData);
|
||||
writer.commit();
|
||||
// SolrCore.verbose("writer.commit() end");
|
||||
numDocsPending.set(0);
|
||||
callPostCommitCallbacks();
|
||||
|
@ -707,7 +708,8 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
|
|||
// todo: refactor this shared code (or figure out why a real CommitUpdateCommand can't be used)
|
||||
final Map<String,String> commitData = new HashMap<String,String>();
|
||||
commitData.put(SolrIndexWriter.COMMIT_TIME_MSEC_KEY, String.valueOf(System.currentTimeMillis()));
|
||||
writer.commit(commitData);
|
||||
writer.setCommitData(commitData);
|
||||
writer.commit();
|
||||
|
||||
synchronized (solrCoreState.getUpdateLock()) {
|
||||
ulog.postCommit(cmd);
|
||||
|
|
Loading…
Reference in New Issue