| Index: lucene/CHANGES.txt |
| =================================================================== |
| --- lucene/CHANGES.txt (revision 953441) |
| +++ lucene/CHANGES.txt (working copy) |
| @@ -481,6 +481,10 @@ |
| files when a mergedSegmentWarmer is set on IndexWriter. (Mike |
| McCandless) |
| |
| +* LUCENE-2496: Don't throw NPE if IndexWriter is opened with CREATE on |
| + a prior (corrupt) index missing its segments_N file. (Mike |
| + McCandless) |
| + |
| New features |
| |
| * LUCENE-2128: Parallelized fetching document frequencies during weight |
| Index: lucene/src/test/org/apache/lucene/index/TestIndexWriter.java |
| =================================================================== |
| --- lucene/src/test/org/apache/lucene/index/TestIndexWriter.java (revision 953441) |
| +++ lucene/src/test/org/apache/lucene/index/TestIndexWriter.java (working copy) |
| @@ -4954,5 +4954,32 @@ |
| writer.close(); |
| assertEquals("expected a no-op close after IW.rollback()", 0, dir.listAll().length); |
| } |
| - |
| + |
| + public void testNoSegmentFile() throws IOException { |
| + File tempDir = _TestUtil.getTempDir("noSegmentFile"); |
| + try { |
| + Directory dir = FSDirectory.open(tempDir); |
| + dir.setLockFactory(new NoLockFactory()); |
| + IndexWriter w = new IndexWriter(dir, new IndexWriterConfig( |
| + TEST_VERSION_CURRENT, new MockAnalyzer()) |
| + .setMaxBufferedDocs(2)); |
| + |
| + Document doc = new Document(); |
| + doc.add(new Field("c", "val", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS)); |
| + w.addDocument(doc); |
| + w.addDocument(doc); |
| + String[] files = dir.listAll(); |
| + for(String file : files) { |
| + System.out.println("file=" + file); |
| + } |
| + IndexWriter w2 = new IndexWriter(dir, new IndexWriterConfig( |
| + TEST_VERSION_CURRENT, new MockAnalyzer()) |
| + .setMaxBufferedDocs(2).setOpenMode(OpenMode.CREATE)); |
| + |
| + w2.close(); |
| + dir.close(); |
| + } finally { |
| + _TestUtil.rmDir(tempDir); |
| + } |
| + } |
| } |
| Index: lucene/src/java/org/apache/lucene/index/IndexFileDeleter.java |
| =================================================================== |
| --- lucene/src/java/org/apache/lucene/index/IndexFileDeleter.java (revision 953441) |
| +++ lucene/src/java/org/apache/lucene/index/IndexFileDeleter.java (working copy) |
| @@ -134,8 +134,10 @@ |
| this.docWriter = docWriter; |
| this.infoStream = infoStream; |
| |
| + final String currentSegmentsFile = segmentInfos.getCurrentSegmentFileName(); |
| + |
| if (infoStream != null) |
| - message("init: current segments file is \"" + segmentInfos.getCurrentSegmentFileName() + "\"; deletionPolicy=" + policy); |
| + message("init: current segments file is \"" + currentSegmentsFile + "\"; deletionPolicy=" + policy); |
| |
| this.policy = policy; |
| this.directory = directory; |
| @@ -146,7 +148,6 @@ |
| indexFilenameFilter = new IndexFileNameFilter(codecs); |
| |
| CommitPoint currentCommitPoint = null; |
| - boolean seenIndexFiles = false; |
| String[] files = null; |
| try { |
| files = directory.listAll(); |
| @@ -158,7 +159,6 @@ |
| for (String fileName : files) { |
| |
| if ((indexFilenameFilter.accept(null, fileName)) && !fileName.endsWith("write.lock") && !fileName.equals(IndexFileNames.SEGMENTS_GEN)) { |
| - seenIndexFiles = true; |
| |
| // Add this file to refCounts with initial count 0: |
| getRefCount(fileName); |
| @@ -201,10 +201,7 @@ |
| } |
| } |
| |
| - // If we haven't seen any Lucene files, then currentCommitPoint is expected |
| - // to be null, because it means it's a fresh Directory. Therefore it cannot |
| - // be any NFS cache issues - so just ignore. |
| - if (currentCommitPoint == null && seenIndexFiles) { |
| + if (currentCommitPoint == null && currentSegmentsFile != null) { |
| // We did not in fact see the segments_N file |
| // corresponding to the segmentInfos that was passed |
| // in. Yet, it must exist, because our caller holds |
| @@ -214,7 +211,7 @@ |
| // try now to explicitly open this commit point: |
| SegmentInfos sis = new SegmentInfos(); |
| try { |
| - sis.read(directory, segmentInfos.getCurrentSegmentFileName(), codecs); |
| + sis.read(directory, currentSegmentsFile, codecs); |
| } catch (IOException e) { |
| throw new CorruptIndexException("failed to locate current segments_N file"); |
| } |
| @@ -244,7 +241,7 @@ |
| |
| // Finally, give policy a chance to remove things on |
| // startup: |
| - if (seenIndexFiles) { |
| + if (currentSegmentsFile != null) { |
| policy.onInit(commits); |
| } |
| |