Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 900162) +++ CHANGES.txt (working copy) @@ -1,6 +1,11 @@ Lucene Change Log $Id$ +Bug fixes + + * LUCENE-2222: FixedIntBlockIndexInput incorrectly read one block of + 0s before the actual data. (Renaud Delbru via Mike McCandless) + ======================= Trunk (not yet released) ======================= Changes in backwards compatibility policy Index: src/test/org/apache/lucene/index/codecs/intblock/TestIntBlockCodec.java =================================================================== --- src/test/org/apache/lucene/index/codecs/intblock/TestIntBlockCodec.java (revision 0) +++ src/test/org/apache/lucene/index/codecs/intblock/TestIntBlockCodec.java (revision 0) @@ -0,0 +1,42 @@ +package org.apache.lucene.index.codecs.intblock; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.store.*; +import org.apache.lucene.index.codecs.sep.*; + +public class TestIntBlockCodec extends LuceneTestCase { + + public void testSimpleIntBlocks() throws Exception { + Directory dir = new MockRAMDirectory(); + + IntIndexOutput out = new SimpleIntBlockIndexOutput(dir, "test", 128); + for(int i=0;i<11777;i++) { + out.write(i); + } + out.close(); + + IntIndexInput in = new SimpleIntBlockIndexInput(dir, "test", 128); + IntIndexInput.Reader r = in.reader(); + + for(int i=0;i<11777;i++) { + assertEquals(i, r.next()); + } + in.close(); + + dir.close(); + } + + public void testEmptySimpleIntBlocks() throws Exception { + Directory dir = new MockRAMDirectory(); + + IntIndexOutput out = new SimpleIntBlockIndexOutput(dir, "test", 128); + // write no ints + out.close(); + + IntIndexInput in = new SimpleIntBlockIndexInput(dir, "test", 128); + IntIndexInput.Reader r = in.reader(); + // read no ints + in.close(); + dir.close(); + } +} Property changes on: src/test/org/apache/lucene/index/codecs/intblock/TestIntBlockCodec.java ___________________________________________________________________ Added: svn:eol-style + native Index: src/java/org/apache/lucene/index/codecs/intblock/FixedIntBlockIndexInput.java =================================================================== --- src/java/org/apache/lucene/index/codecs/intblock/FixedIntBlockIndexInput.java (revision 900162) +++ src/java/org/apache/lucene/index/codecs/intblock/FixedIntBlockIndexInput.java (working copy) @@ -30,23 +30,26 @@ * from an IndexInput. While this is a simple approach, a * more performant approach would directly create an impl * of IntIndexInput inside Directory. Wrapping a generic - * IndexInput will likely cost performance. */ + * IndexInput will likely cost performance. + * + * @lucene.experimental + */ public abstract class FixedIntBlockIndexInput extends IntIndexInput { private IndexInput in; protected int blockSize; - protected void init(IndexInput in) throws IOException { + protected void init(final IndexInput in) throws IOException { this.in = in; blockSize = in.readVInt(); } @Override public Reader reader() throws IOException { - int[] buffer = new int[blockSize]; - IndexInput clone = (IndexInput) in.clone(); + final int[] buffer = new int[blockSize]; + final IndexInput clone = (IndexInput) in.clone(); // nocommit -- awkward - return new Reader(clone, buffer, getBlockReader(clone, buffer)); + return new Reader(clone, buffer, this.getBlockReader(clone, buffer)); } @Override @@ -80,15 +83,17 @@ private final BulkReadResult result = new BulkReadResult(); - public Reader(IndexInput in, int[] pending, BlockReader blockReader) { + public Reader(final IndexInput in, final int[] pending, final BlockReader blockReader) + throws IOException { this.in = in; this.pending = pending; this.blockSize = pending.length; result.buffer = pending; this.blockReader = blockReader; + upto = blockSize; } - void seek(long fp, int upto) { + void seek(final long fp, final int upto) { pendingFP = fp; pendingUpto = upto; seekPending = true; @@ -109,7 +114,7 @@ @Override public int next() throws IOException { - maybeSeek(); + this.maybeSeek(); if (upto == blockSize) { lastBlockFP = in.getFilePointer(); blockReader.readBlock(); @@ -120,8 +125,8 @@ } @Override - public BulkReadResult read(int[] buffer, int count) throws IOException { - maybeSeek(); + public BulkReadResult read(final int[] buffer, final int count) throws IOException { + this.maybeSeek(); if (upto == blockSize) { blockReader.readBlock(); upto = 0; @@ -149,7 +154,7 @@ private int upto; @Override - public void read(IndexInput indexIn, boolean absolute) throws IOException { + public void read(final IndexInput indexIn, final boolean absolute) throws IOException { if (absolute) { fp = indexIn.readVLong(); upto = indexIn.readVInt(); @@ -168,17 +173,17 @@ } @Override - public void seek(IntIndexInput.Reader other) throws IOException { + public void seek(final IntIndexInput.Reader other) throws IOException { ((Reader) other).seek(fp, upto); } @Override - public void set(IntIndexInput.Index other) { - Index idx = (Index) other; + public void set(final IntIndexInput.Index other) { + final Index idx = (Index) other; fp = idx.fp; upto = idx.upto; } - + public class State extends IndexState { long fp; int upto; @@ -187,7 +192,7 @@ // nocommit handle with set and/or clone? @Override public IndexState captureState() { - State state = new State(); + final State state = new State(); state.fp = fp; state.upto = upto; return state; @@ -195,11 +200,11 @@ // nocommit handle with set and/or clone? @Override - public void setState(IndexState state) { - State iState = (State) state; + public void setState(final IndexState state) { + final State iState = (State) state; this.fp = iState.fp; this.upto = iState.upto; - + } } -} \ No newline at end of file +} Index: src/java/org/apache/lucene/index/codecs/intblock/FixedIntBlockIndexOutput.java =================================================================== --- src/java/org/apache/lucene/index/codecs/intblock/FixedIntBlockIndexOutput.java (revision 900162) +++ src/java/org/apache/lucene/index/codecs/intblock/FixedIntBlockIndexOutput.java (working copy) @@ -26,6 +26,14 @@ import org.apache.lucene.index.codecs.sep.IntIndexOutput; import org.apache.lucene.store.IndexOutput; +/** Abstract base class that writes fixed-size blocks of ints + * to an IndexOutput. While this is a simple approach, a + * more performant approach would directly create an impl + * of IntIndexOutput inside Directory. Wrapping a generic + * IndexInput will likely cost performance. + * + * @lucene.experimental + */ public abstract class FixedIntBlockIndexOutput extends IntIndexOutput { private IndexOutput out; @@ -102,11 +110,12 @@ @Override public void close() throws IOException { - // NOTE: entries in the block after current upto are - // invalid - // nocommit -- zero fill? try { - flushBlock(pending, out); + if (upto > 0) { + // NOTE: entries in the block after current upto are + // invalid + flushBlock(pending, out); + } } finally { out.close(); }