Index: lucene/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java =================================================================== --- lucene/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java (revision 983911) +++ lucene/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java (working copy) @@ -18,7 +18,9 @@ */ import java.io.IOException; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import org.apache.lucene.document.Document; @@ -56,6 +58,38 @@ private final IndexWriter writer; /** + * Reads the snapshots information from the given {@link Directory}. This + * method does can be used if the snapshots information is needed, however you + * cannot instantiate the deletion policy (because e.g., some other process + * keeps a lock on the snapshots directory). + */ + public static Map readSnapshotsInfo(Directory dir) throws IOException { + IndexReader r = IndexReader.open(dir, true); + Map snapshots = new HashMap(); + try { + int numDocs = r.numDocs(); + // index is allowed to have exactly one document or 0. + if (numDocs == 1) { + Document doc = r.document(r.maxDoc() - 1); + Field sid = doc.getField(SNAPSHOTS_ID); + if (sid == null) { + throw new IllegalStateException("directory is not a valid snapshots store!"); + } + doc.removeField(SNAPSHOTS_ID); + for (Fieldable f : doc.getFields()) { + snapshots.put(f.name(), f.stringValue()); + } + } else if (numDocs != 0) { + throw new IllegalStateException( + "should be at most 1 document in the snapshots directory: " + numDocs); + } + } finally { + r.close(); + } + return snapshots; + } + + /** * {@link PersistentSnapshotDeletionPolicy} wraps another * {@link IndexDeletionPolicy} to enable flexible snapshotting. * @@ -91,26 +125,8 @@ // Initializes the snapshots information. This code should basically run // only if mode != CREATE, but if it is, it's no harm as we only open the // reader once and immediately close it. - IndexReader r = writer.getReader(); - try { - int numDocs = r.numDocs(); - // index is allowed to have exactly one document or 0. - if (numDocs == 1) { - Document doc = r.document(r.maxDoc() - 1); - Field sid = doc.getField(SNAPSHOTS_ID); - if (sid == null) { - throw new IllegalStateException("directory is not a valid snapshots store!"); - } - doc.removeField(SNAPSHOTS_ID); - for (Fieldable f : doc.getFields()) { - registerSnapshotInfo(f.name(), f.stringValue(), null); - } - } else if (numDocs != 0) { - throw new IllegalStateException( - "should be at most 1 document in the snapshots directory: " + numDocs); - } - } finally { - r.close(); + for (Entry e : readSnapshotsInfo(dir).entrySet()) { + registerSnapshotInfo(e.getKey(), e.getValue(), null); } } Index: lucene/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java (revision 983911) +++ lucene/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; +import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.store.MockRAMDirectory; import org.junit.Test; @@ -135,4 +136,30 @@ assertEquals("Should have no snapshots !", 0, psdp.getSnapshots().size()); } + @Test + public void testStaticRead() throws Exception { + // While PSDP is open, no one can read the snapshots information. This test + // checks that the static read method works. + int numSnapshots = 1; + Directory dir = new MockRAMDirectory(); + PersistentSnapshotDeletionPolicy psdp = (PersistentSnapshotDeletionPolicy) getDeletionPolicy(); + IndexWriter writer = new IndexWriter(dir, getConfig(psdp)); + prepareIndexAndSnapshots(psdp, writer, numSnapshots, "snapshot"); + writer.close(); + + try { + // This should fail, since the snapshots directory is locked - we didn't close it ! + new PersistentSnapshotDeletionPolicy( + new KeepOnlyLastCommitDeletionPolicy(), snapshotDir, OpenMode.APPEND, + TEST_VERSION_CURRENT); + fail("should not have reached here - the snapshots directory should be locked!"); + } catch (LockObtainFailedException e) { + // expected + } + + // Reading the snapshots info should succeed though + Map snapshots = PersistentSnapshotDeletionPolicy.readSnapshotsInfo(snapshotDir); + assertEquals("expected " + numSnapshots + " snapshots, got " + snapshots.size(), numSnapshots, snapshots.size()); + } + }