Index: lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (revision 1127872) +++ lucene/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (working copy) @@ -919,7 +919,7 @@ assertTrue(failure.failOnCommit && failure.failOnDeleteFile); w.rollback(); assertFalse(dir.fileExists("1.fnx")); - // FIXME: on windows, this often fails! assertEquals(0, dir.listAll().length); + assertEquals(0, dir.listAll().length); dir.close(); } } Index: lucene/src/java/org/apache/lucene/index/SegmentInfos.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentInfos.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/SegmentInfos.java (working copy) @@ -330,7 +330,7 @@ // We hit an exception above; try to close the file // but suppress any exception: try { - segnOutput.close(); + if (segnOutput != null) segnOutput.close(); } catch (Throwable t) { // Suppress so we keep throwing the original exception } Index: lucene/src/java/org/apache/lucene/index/SegmentMerger.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentMerger.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/SegmentMerger.java (working copy) @@ -546,14 +546,13 @@ } codec = segmentWriteState.segmentCodecs.codec(); final FieldsConsumer consumer = codec.fieldsConsumer(segmentWriteState); - - // NOTE: this is silly, yet, necessary -- we create a - // MultiBits as our skip docs only to have it broken - // apart when we step through the docs enums in - // MultiDocsEnum. - mergeState.multiDeletedDocs = new MultiBits(bits, bitsStarts); - try { + // NOTE: this is silly, yet, necessary -- we create a + // MultiBits as our skip docs only to have it broken + // apart when we step through the docs enums in + // MultiDocsEnum. + mergeState.multiDeletedDocs = new MultiBits(bits, bitsStarts); + consumer.merge(mergeState, new MultiFields(fields.toArray(Fields.EMPTY_ARRAY), slices.toArray(ReaderUtil.Slice.EMPTY_ARRAY))); Index: lucene/src/java/org/apache/lucene/index/PerFieldCodecWrapper.java =================================================================== --- lucene/src/java/org/apache/lucene/index/PerFieldCodecWrapper.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/PerFieldCodecWrapper.java (working copy) @@ -74,6 +74,8 @@ @Override public void close() throws IOException { + // TODO would be nice if we could use IOUtils.closeSafely - can do that + // only if we convert the list to an array Iterator it = consumers.iterator(); IOException err = null; while (it.hasNext()) { Index: lucene/src/java/org/apache/lucene/index/codecs/BlockTermsWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/BlockTermsWriter.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/BlockTermsWriter.java (working copy) @@ -31,6 +31,7 @@ import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.RamUsageEstimator; // TODO: currently we encode all terms between two indexed @@ -75,15 +76,20 @@ final String termsFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, TERMS_EXTENSION); this.termsIndexWriter = termsIndexWriter; out = state.directory.createOutput(termsFileName); - fieldInfos = state.fieldInfos; - writeHeader(out); - currentField = null; - this.postingsWriter = postingsWriter; - //segment = state.segmentName; - - //System.out.println("BTW.init seg=" + state.segmentName); - - postingsWriter.start(out); // have consumer write its format/header + boolean success = false; + try { + fieldInfos = state.fieldInfos; + writeHeader(out); + currentField = null; + this.postingsWriter = postingsWriter; + //segment = state.segmentName; + + //System.out.println("BTW.init seg=" + state.segmentName); + + postingsWriter.start(out); // have consumer write its format/header + } finally { + if (!success) IOUtils.closeSafelyNoException(out, postingsWriter, termsIndexWriter); + } } protected void writeHeader(IndexOutput out) throws IOException { @@ -143,7 +149,6 @@ } protected void writeTrailer(long dirStart) throws IOException { - // TODO Auto-generated method stub out.seek(CodecUtil.headerLength(CODEC_NAME)); out.writeLong(dirStart); } Index: lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosWriter.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosWriter.java (working copy) @@ -24,6 +24,7 @@ import org.apache.lucene.store.ChecksumIndexOutput; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IndexOutput; +import org.apache.lucene.util.IOUtils; /** * Default implementation of {@link SegmentInfosWriter}. @@ -56,15 +57,23 @@ public IndexOutput writeInfos(Directory dir, String segmentFileName, SegmentInfos infos) throws IOException { IndexOutput out = createOutput(dir, segmentFileName); - out.writeInt(FORMAT_CURRENT); // write FORMAT - out.writeLong(infos.version); - out.writeInt(infos.counter); // write counter - out.writeLong(infos.getGlobalFieldMapVersion()); - out.writeInt(infos.size()); // write infos - for (SegmentInfo si : infos) { - si.write(out); + boolean success = false; + try { + out.writeInt(FORMAT_CURRENT); // write FORMAT + out.writeLong(infos.version); + out.writeInt(infos.counter); // write counter + out.writeLong(infos.getGlobalFieldMapVersion()); + out.writeInt(infos.size()); // write infos + for (SegmentInfo si : infos) { + si.write(out); + } + out.writeStringStringMap(infos.getUserData()); + success = true; + } finally { + if (!success) { + IOUtils.closeSafelyNoException(out); + } } - out.writeStringStringMap(infos.getUserData()); return out; } Index: lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexReader.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexReader.java (working copy) @@ -24,6 +24,7 @@ import org.apache.lucene.index.SegmentInfo; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.PagedBytes; import org.apache.lucene.util.packed.PackedInts; @@ -108,6 +109,7 @@ } success = true; } finally { + if (!success) IOUtils.closeSafelyNoException(in); if (indexDivisor > 0) { in.close(); in = null; Index: lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexWriter.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexWriter.java (working copy) @@ -25,6 +25,7 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; import org.apache.lucene.util.ArrayUtil; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.packed.PackedInts; import java.util.List; @@ -58,9 +59,15 @@ final String indexFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, TERMS_INDEX_EXTENSION); termIndexInterval = state.termIndexInterval; out = state.directory.createOutput(indexFileName); - fieldInfos = state.fieldInfos; - writeHeader(out); - out.writeInt(termIndexInterval); + boolean success = false; + try { + fieldInfos = state.fieldInfos; + writeHeader(out); + out.writeInt(termIndexInterval); + success = true; + } finally { + if (!success) IOUtils.closeSafelyNoException(out); + } } protected void writeHeader(IndexOutput out) throws IOException { @@ -204,31 +211,40 @@ @Override public void close() throws IOException { - final long dirStart = out.getFilePointer(); - final int fieldCount = fields.size(); - - int nonNullFieldCount = 0; - for(int i=0;i 0) { - nonNullFieldCount++; + boolean success = false; + try { + final long dirStart = out.getFilePointer(); + final int fieldCount = fields.size(); + + int nonNullFieldCount = 0; + for(int i=0;i 0) { + nonNullFieldCount++; + } } - } - - out.writeVInt(nonNullFieldCount); - for(int i=0;i 0) { - out.writeVInt(field.fieldInfo.number); - out.writeVInt(field.numIndexTerms); - out.writeVLong(field.termsStart); - out.writeVLong(field.indexStart); - out.writeVLong(field.packedIndexStart); - out.writeVLong(field.packedOffsetsStart); + + out.writeVInt(nonNullFieldCount); + for(int i=0;i 0) { + out.writeVInt(field.fieldInfo.number); + out.writeVInt(field.numIndexTerms); + out.writeVLong(field.termsStart); + out.writeVLong(field.indexStart); + out.writeVLong(field.packedIndexStart); + out.writeVLong(field.packedOffsetsStart); + } } + writeTrailer(dirStart); + success = true; + } finally { + if (success) { + out.close(); + } else { + IOUtils.closeSafelyNoException(out); + } } - writeTrailer(dirStart); - out.close(); } protected void writeTrailer(long dirStart) throws IOException { Index: lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsWriterImpl.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsWriterImpl.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsWriterImpl.java (working copy) @@ -31,6 +31,7 @@ import org.apache.lucene.store.RAMOutputStream; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; +import org.apache.lucene.util.IOUtils; /** Writes frq to .frq, docs to .doc, pos to .pos, payloads * to .pyl, skip data to .skp @@ -49,18 +50,18 @@ final static int VERSION_START = 0; final static int VERSION_CURRENT = VERSION_START; - final IntIndexOutput freqOut; - final IntIndexOutput.Index freqIndex; + IntIndexOutput freqOut; + IntIndexOutput.Index freqIndex; - final IntIndexOutput posOut; - final IntIndexOutput.Index posIndex; + IntIndexOutput posOut; + IntIndexOutput.Index posIndex; - final IntIndexOutput docOut; - final IntIndexOutput.Index docIndex; + IntIndexOutput docOut; + IntIndexOutput.Index docIndex; - final IndexOutput payloadOut; + IndexOutput payloadOut; - final IndexOutput skipOut; + IndexOutput skipOut; IndexOutput termsOut; final SepSkipListWriter skipListWriter; @@ -107,44 +108,49 @@ } public SepPostingsWriterImpl(SegmentWriteState state, IntStreamFactory factory, int skipInterval) throws IOException { - super(); - this.skipInterval = skipInterval; - this.skipMinimum = skipInterval; /* set to the same for now */ - final String docFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, DOC_EXTENSION); - docOut = factory.createOutput(state.directory, docFileName); - docIndex = docOut.index(); + freqOut = null; + freqIndex = null; + posOut = null; + posIndex = null; + payloadOut = null; + boolean success = false; + try { + this.skipInterval = skipInterval; + this.skipMinimum = skipInterval; /* set to the same for now */ + final String docFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, DOC_EXTENSION); + docOut = factory.createOutput(state.directory, docFileName); + docIndex = docOut.index(); + + if (state.fieldInfos.hasProx()) { + final String frqFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, FREQ_EXTENSION); + freqOut = factory.createOutput(state.directory, frqFileName); + freqIndex = freqOut.index(); + + final String posFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, POS_EXTENSION); + posOut = factory.createOutput(state.directory, posFileName); + posIndex = posOut.index(); + + // TODO: -- only if at least one field stores payloads? + final String payloadFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, PAYLOAD_EXTENSION); + payloadOut = state.directory.createOutput(payloadFileName); + } + + final String skipFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, SKIP_EXTENSION); + skipOut = state.directory.createOutput(skipFileName); + + totalNumDocs = state.numDocs; + + skipListWriter = new SepSkipListWriter(skipInterval, + maxSkipLevels, + state.numDocs, + freqOut, docOut, + posOut, payloadOut); + + success = true; + } finally { + if (!success) IOUtils.closeSafelyNoException(docOut, skipOut, freqOut, posOut, payloadOut); - if (state.fieldInfos.hasProx()) { - final String frqFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, FREQ_EXTENSION); - freqOut = factory.createOutput(state.directory, frqFileName); - freqIndex = freqOut.index(); - - final String posFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, POS_EXTENSION); - posOut = factory.createOutput(state.directory, posFileName); - posIndex = posOut.index(); - - // TODO: -- only if at least one field stores payloads? - final String payloadFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, PAYLOAD_EXTENSION); - payloadOut = state.directory.createOutput(payloadFileName); - - } else { - freqOut = null; - freqIndex = null; - posOut = null; - posIndex = null; - payloadOut = null; } - - final String skipFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, SKIP_EXTENSION); - skipOut = state.directory.createOutput(skipFileName); - - totalNumDocs = state.numDocs; - - skipListWriter = new SepSkipListWriter(skipInterval, - maxSkipLevels, - state.numDocs, - freqOut, docOut, - posOut, payloadOut); } @Override @@ -306,25 +312,7 @@ @Override public void close() throws IOException { - try { - docOut.close(); - } finally { - try { - skipOut.close(); - } finally { - if (freqOut != null) { - try { - freqOut.close(); - } finally { - try { - posOut.close(); - } finally { - payloadOut.close(); - } - } - } - } - } + IOUtils.closeSafely(docOut, skipOut, freqOut, posOut, payloadOut); } public static void getExtensions(Set extensions) { Index: lucene/src/java/org/apache/lucene/index/codecs/TermsIndexWriterBase.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/TermsIndexWriterBase.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/TermsIndexWriterBase.java (working copy) @@ -19,10 +19,12 @@ import org.apache.lucene.index.FieldInfo; import org.apache.lucene.util.BytesRef; + +import java.io.Closeable; import java.io.IOException; /** @lucene.experimental */ -public abstract class TermsIndexWriterBase { +public abstract class TermsIndexWriterBase implements Closeable { public abstract class FieldWriter { public abstract boolean checkIndexTerm(BytesRef text, TermStats stats) throws IOException; @@ -31,6 +33,4 @@ } public abstract FieldWriter addField(FieldInfo fieldInfo, long termsFilePointer) throws IOException; - - public abstract void close() throws IOException; } Index: lucene/src/java/org/apache/lucene/index/codecs/VariableGapTermsIndexWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/VariableGapTermsIndexWriter.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/index/codecs/VariableGapTermsIndexWriter.java (working copy) @@ -28,6 +28,7 @@ import org.apache.lucene.store.IndexOutput; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.automaton.fst.Builder; import org.apache.lucene.util.automaton.fst.FST; import org.apache.lucene.util.automaton.fst.PositiveIntOutputs; @@ -159,9 +160,15 @@ public VariableGapTermsIndexWriter(SegmentWriteState state, IndexTermSelector policy) throws IOException { final String indexFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, TERMS_INDEX_EXTENSION); out = state.directory.createOutput(indexFileName); - fieldInfos = state.fieldInfos; - this.policy = policy; - writeHeader(out); + boolean success = false; + try { + fieldInfos = state.fieldInfos; + this.policy = policy; + writeHeader(out); + success = true; + } finally { + if (!success) IOUtils.closeSafelyNoException(out); + } } protected void writeHeader(IndexOutput out) throws IOException { Index: lucene/src/java/org/apache/lucene/util/IOUtils.java =================================================================== --- lucene/src/java/org/apache/lucene/util/IOUtils.java (revision 1127872) +++ lucene/src/java/org/apache/lucene/util/IOUtils.java (working copy) @@ -26,6 +26,19 @@ private IOUtils() {} // no instance /** + * Closes all given Closeables, suppressing all thrown exceptions. + * Some of the Closeables may be null, they are ignored. + */ + public static void closeSafelyNoException(Closeable... objects) { + for (Closeable object : objects) { + try { + if (object != null) object.close(); + } catch (Throwable t) { + } + } + } + + /** *

Closes all given Closeables, suppressing all thrown exceptions. Some of the Closeables * may be null, they are ignored. After everything is closed, method either throws priorException, * if one is supplied, or the first of suppressed exceptions, or completes normally.

Index: lucene/src/test-framework/org/apache/lucene/index/codecs/mocksep/MockSingleIntIndexOutput.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/index/codecs/mocksep/MockSingleIntIndexOutput.java (revision 1127872) +++ lucene/src/test-framework/org/apache/lucene/index/codecs/mocksep/MockSingleIntIndexOutput.java (working copy) @@ -20,6 +20,7 @@ import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.Directory; import org.apache.lucene.util.CodecUtil; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.index.codecs.sep.IntIndexOutput; import java.io.IOException; @@ -36,7 +37,15 @@ public MockSingleIntIndexOutput(Directory dir, String fileName) throws IOException { out = dir.createOutput(fileName); - CodecUtil.writeHeader(out, CODEC, VERSION_CURRENT); + boolean success = false; + try { + CodecUtil.writeHeader(out, CODEC, VERSION_CURRENT); + success = true; + } finally { + if (!success) { + IOUtils.closeSafelyNoException(out); + } + } } /** Write an int to the primary file */ Index: lucene/src/test-framework/org/apache/lucene/index/codecs/mockrandom/MockRandomCodec.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/index/codecs/mockrandom/MockRandomCodec.java (revision 1127872) +++ lucene/src/test-framework/org/apache/lucene/index/codecs/mockrandom/MockRandomCodec.java (working copy) @@ -136,8 +136,11 @@ final String seedFileName = IndexFileNames.segmentFileName(state.segmentName, state.codecId, SEED_EXT); final IndexOutput out = state.directory.createOutput(seedFileName); - out.writeLong(seed); - out.close(); + try { + out.writeLong(seed); + } finally { + out.close(); + } final Random random = new Random(seed); Index: lucene/src/test-framework/org/apache/lucene/store/MockDirectoryWrapper.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/store/MockDirectoryWrapper.java (revision 1127872) +++ lucene/src/test-framework/org/apache/lucene/store/MockDirectoryWrapper.java (working copy) @@ -68,24 +68,24 @@ boolean trackDiskUsage = false; private Set unSyncedFiles; private Set createdFiles; - Set openFilesForWrite = new HashSet(); + private Set openFilesForWrite = new HashSet(); volatile boolean crashed; private ThrottledIndexOutput throttledOutput; private Throttling throttling = Throttling.SOMETIMES; // use this for tracking files for crash. // additionally: provides debugging information in case you leave one open - Map openFileHandles = Collections.synchronizedMap(new IdentityHashMap()); + private Map openFileHandles = Collections.synchronizedMap(new IdentityHashMap()); // NOTE: we cannot initialize the Map here due to the // order in which our constructor actually does this // member initialization vs when it calls super. It seems // like super is called, then our members are initialized: - Map openFiles; + private Map openFiles; // Only tracked if noDeleteOpenFile is true: if an attempt // is made to delete an open file, we enroll it here. - Set openFilesDeleted; + private Set openFilesDeleted; private synchronized void init() { if (openFiles == null) { @@ -127,7 +127,7 @@ SOMETIMES, /** never throttle output */ NEVER - }; + } public void setThrottling(Throttling throttling) { this.throttling = throttling; @@ -362,9 +362,10 @@ ramdir.fileMap.put(name, file); } } + //System.out.println(Thread.currentThread().getName() + ": MDW: create " + name); IndexOutput io = new MockIndexOutputWrapper(this, delegate.createOutput(name), name); - openFileHandles.put(io, new RuntimeException("unclosed IndexOutput")); + addFileHandle(io, name, false); openFilesForWrite.add(name); // throttling REALLY slows down tests, so don't do it very often for SOMETIMES. @@ -379,6 +380,18 @@ } } + private void addFileHandle(Closeable c, String name, boolean input) { + Integer v = openFiles.get(name); + if (v != null) { + v = Integer.valueOf(v.intValue()+1); + openFiles.put(name, v); + } else { + openFiles.put(name, Integer.valueOf(1)); + } + + openFileHandles.put(c, new RuntimeException("unclosed Index" + (input ? "Input" : "Output") + ": " + name)); + } + @Override public synchronized IndexInput openInput(String name) throws IOException { maybeYield(); @@ -391,16 +404,8 @@ throw fillOpenTrace(new IOException("MockDirectoryWrapper: file \"" + name + "\" is still open for writing"), name, false); } - if (openFiles.containsKey(name)) { - Integer v = openFiles.get(name); - v = Integer.valueOf(v.intValue()+1); - openFiles.put(name, v); - } else { - openFiles.put(name, Integer.valueOf(1)); - } - IndexInput ii = new MockIndexInputWrapper(this, name, delegate.openInput(name)); - openFileHandles.put(ii, new RuntimeException("unclosed IndexInput")); + addFileHandle(ii, name, true); return ii; } @@ -465,6 +470,31 @@ delegate.close(); } + private synchronized void removeOpenFile(Closeable c, String name) { + Integer v = openFiles.get(name); + // Could be null when crash() was called + if (v != null) { + if (v.intValue() == 1) { + openFiles.remove(name); + openFilesDeleted.remove(name); + } else { + v = Integer.valueOf(v.intValue()-1); + openFiles.put(name, v); + } + } + + openFileHandles.remove(c); + } + + public synchronized void removeIndexOutput(IndexOutput out, String name) { + openFilesForWrite.remove(name); + removeOpenFile(out, name); + } + + public synchronized void removeIndexInput(IndexInput in, String name) { + removeOpenFile(in, name); + } + private CodecProvider codecProvider; // We pass this CodecProvider to checkIndex when dir is closed... Index: lucene/src/test-framework/org/apache/lucene/store/MockIndexInputWrapper.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/store/MockIndexInputWrapper.java (revision 1127872) +++ lucene/src/test-framework/org/apache/lucene/store/MockIndexInputWrapper.java (working copy) @@ -31,8 +31,7 @@ private IndexInput delegate; private boolean isClone; - /** Construct an empty output buffer. - * @throws IOException */ + /** Construct an empty output buffer. */ public MockIndexInputWrapper(MockDirectoryWrapper dir, String name, IndexInput delegate) { this.name = name; this.dir = dir; @@ -46,20 +45,7 @@ // remove the conditional check so we also track that // all clones get closed: if (!isClone) { - synchronized(dir) { - Integer v = dir.openFiles.get(name); - // Could be null when MockRAMDirectory.crash() was called - if (v != null) { - if (v.intValue() == 1) { - dir.openFiles.remove(name); - dir.openFilesDeleted.remove(name); - } else { - v = Integer.valueOf(v.intValue()-1); - dir.openFiles.put(name, v); - } - } - dir.openFileHandles.remove(this); - } + dir.removeIndexInput(this, name); } } Index: lucene/src/test-framework/org/apache/lucene/store/MockIndexOutputWrapper.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/store/MockIndexOutputWrapper.java (revision 1127872) +++ lucene/src/test-framework/org/apache/lucene/store/MockIndexOutputWrapper.java (working copy) @@ -57,10 +57,7 @@ dir.maxUsedSize = size; } } - synchronized(dir) { - dir.openFileHandles.remove(this); - dir.openFilesForWrite.remove(name); - } + dir.removeIndexOutput(this, name); } }