Index: lucene/core/src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (revision 1415054) +++ lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -2638,6 +2638,10 @@ synchronized(this) { maybeApplyDeletes(true); + if (commitUserData != null) { + setCommitData(commitUserData); + } + readerPool.commit(segmentInfos); // Must clone the segmentInfos while we still @@ -2688,10 +2692,23 @@ } } - 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: the map is cloned internally, therefore altering the map's + * contents after calling this method has no effect. + */ + public final void setCommitData(Map commitUserData) { + segmentInfos.setUserData(new HashMap(commitUserData)); + ++changeCount; + } + // Used only by commit and prepareCommit, below; lock // order is commitLock -> IW private final Object commitLock = new Object(); @@ -3906,7 +3923,7 @@ * 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 commitUserData) throws IOException { + private void startCommit(final SegmentInfos toSync) throws IOException { assert testPoint("startStartCommit"); assert pendingCommit == null; @@ -3939,10 +3956,6 @@ } assert filesExist(toSync); - - if (commitUserData != null) { - toSync.setUserData(commitUserData); - } } assert testPoint("midStartCommit"); Index: lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java (revision 1415054) +++ lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java (working copy) @@ -23,8 +23,10 @@ import java.io.StringReader; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.lucene.analysis.*; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; @@ -1932,4 +1934,25 @@ 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() {{ + put("key", "value"); + }}); + writer.commit(); + + DirectoryReader r = DirectoryReader.open(dir); + assertEquals("value", r.getIndexCommit().getUserData().get("key")); + + writer.close(); + r.close(); + dir.close(); + } + } Index: lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java =================================================================== --- lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java (revision 1415054) +++ lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java (working copy) @@ -129,6 +129,8 @@ private volatile ParentArray parentArray; private volatile int nextID; + private Map commitData; + /** Reads the commit data from a Directory. */ private static Map readCommitData(Directory dir) throws IOException { SegmentInfos infos = new SegmentInfos(); @@ -353,7 +355,7 @@ @Override public synchronized void close() throws IOException { if (!isClosed) { - indexWriter.commit(combinedCommitData(null)); + indexWriter.commit(combinedCommitData()); doClose(); } } @@ -668,17 +670,16 @@ */ @Override public synchronized void commit() throws IOException { - ensureOpen(); - indexWriter.commit(combinedCommitData(null)); + commit(null); } /** * Combine original user data with that of the taxonomy creation time */ - private Map combinedCommitData(Map userData) { + private Map combinedCommitData() { Map m = new HashMap(); - if (userData != null) { - m.putAll(userData); + if (commitData != null) { + m.putAll(commitData); } m.put(INDEX_EPOCH, Long.toString(indexEpoch)); return m; @@ -692,7 +693,8 @@ @Override public synchronized void commit(Map commitUserData) throws IOException { ensureOpen(); - indexWriter.commit(combinedCommitData(commitUserData)); + this.commitData = commitUserData; + indexWriter.commit(combinedCommitData()); } /** @@ -701,8 +703,7 @@ */ @Override public synchronized void prepareCommit() throws IOException { - ensureOpen(); - indexWriter.prepareCommit(combinedCommitData(null)); + prepareCommit(null); } /** @@ -712,7 +713,8 @@ @Override public synchronized void prepareCommit(Map commitUserData) throws IOException { ensureOpen(); - indexWriter.prepareCommit(combinedCommitData(commitUserData)); + this.commitData = commitUserData; + indexWriter.prepareCommit(combinedCommitData()); } @Override