diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 41db2a06138..dce07644fab 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -142,6 +142,9 @@ API Changes The default implementation allocates an ew byte array and call StoredFieldVisitor#binaryField(FieldInfo, byte[]). (Ignacio Vera) +* GITHUB#12592: Add RandomAccessInput#length method to the RandomAccessInput interface. In addition deprecate + ByteBuffersDataInput#size in favour of this new method. (Ignacio Vera) + New Features --------------------- (No changes) diff --git a/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/store/EndiannessReverserIndexInput.java b/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/store/EndiannessReverserIndexInput.java index b0a2b3ad57e..5ec1402efc7 100644 --- a/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/store/EndiannessReverserIndexInput.java +++ b/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/store/EndiannessReverserIndexInput.java @@ -96,6 +96,11 @@ final class EndiannessReverserIndexInput extends FilterIndexInput { this.in = in; } + @Override + public long length() { + return in.length(); + } + @Override public byte readByte(long pos) throws IOException { return in.readByte(pos); diff --git a/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java b/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java index fdc11381548..1fac3fe9379 100644 --- a/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java +++ b/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataInput.java @@ -42,7 +42,7 @@ public final class ByteBuffersDataInput extends DataInput private final LongBuffer[] longBuffers; private final int blockBits; private final int blockMask; - private final long size; + private final long length; private final long offset; private long pos; @@ -71,19 +71,25 @@ public final class ByteBuffersDataInput extends DataInput this.blockMask = (1 << blockBits) - 1; } - long size = 0; + long length = 0; for (ByteBuffer block : blocks) { - size += block.remaining(); + length += block.remaining(); } - this.size = size; + this.length = length; // The initial "position" of this stream is shifted by the position of the first block. this.offset = blocks[0].position(); this.pos = offset; } + /** + * Returns the total number of bytes in this stream. + * + * @deprecated Use {@link #length()} instead. + */ + @Deprecated public long size() { - return size; + return length(); } @Override @@ -102,7 +108,7 @@ public final class ByteBuffersDataInput extends DataInput pos++; return v; } catch (IndexOutOfBoundsException e) { - if (pos >= size()) { + if (pos >= length()) { throw new EOFException(); } else { throw e; // Something is wrong. @@ -135,7 +141,7 @@ public final class ByteBuffersDataInput extends DataInput len -= chunk; } } catch (BufferUnderflowException | ArrayIndexOutOfBoundsException e) { - if (pos >= size()) { + if (pos >= length()) { throw new EOFException(); } else { throw e; // Something is wrong. @@ -162,7 +168,7 @@ public final class ByteBuffersDataInput extends DataInput off += chunk; } } catch (BufferUnderflowException | ArrayIndexOutOfBoundsException e) { - if (pos >= size()) { + if (pos >= length()) { throw new EOFException(); } else { throw e; // Something is wrong. @@ -206,6 +212,11 @@ public final class ByteBuffersDataInput extends DataInput } } + @Override + public long length() { + return length; + } + @Override public byte readByte(long pos) { pos += offset; @@ -287,7 +298,7 @@ public final class ByteBuffersDataInput extends DataInput off += chunk; } } catch (BufferUnderflowException | IndexOutOfBoundsException e) { - if (pos - offset + Float.BYTES > size()) { + if (pos - offset + Float.BYTES > length()) { throw new EOFException(); } else { throw e; // Something is wrong. @@ -319,7 +330,7 @@ public final class ByteBuffersDataInput extends DataInput off += chunk; } } catch (BufferUnderflowException | IndexOutOfBoundsException e) { - if (pos - offset + Long.BYTES > size()) { + if (pos - offset + Long.BYTES > length()) { throw new EOFException(); } else { throw e; // Something is wrong. @@ -359,8 +370,8 @@ public final class ByteBuffersDataInput extends DataInput public void seek(long position) throws EOFException { this.pos = position + offset; - if (position > size()) { - this.pos = size(); + if (position > length()) { + this.pos = length(); throw new EOFException(); } } @@ -375,7 +386,7 @@ public final class ByteBuffersDataInput extends DataInput } public ByteBuffersDataInput slice(long offset, long length) { - if (offset < 0 || length < 0 || offset + length > this.size) { + if (offset < 0 || length < 0 || offset + length > this.length) { throw new IllegalArgumentException( String.format( Locale.ROOT, @@ -393,7 +404,7 @@ public final class ByteBuffersDataInput extends DataInput return String.format( Locale.ROOT, "%,d bytes, block size: %,d, blocks: %,d, position: %,d%s", - size(), + length(), blockSize(), blocks.length, position(), diff --git a/lucene/core/src/java/org/apache/lucene/store/IndexInput.java b/lucene/core/src/java/org/apache/lucene/store/IndexInput.java index 3d3d90bd6ff..9e482b7e429 100644 --- a/lucene/core/src/java/org/apache/lucene/store/IndexInput.java +++ b/lucene/core/src/java/org/apache/lucene/store/IndexInput.java @@ -148,6 +148,12 @@ public abstract class IndexInput extends DataInput implements Closeable { } else { // return default impl return new RandomAccessInput() { + @Override + public long length() { + assert length == slice.length(); + return slice.length(); + } + @Override public byte readByte(long pos) throws IOException { slice.seek(pos); diff --git a/lucene/core/src/java/org/apache/lucene/store/RandomAccessInput.java b/lucene/core/src/java/org/apache/lucene/store/RandomAccessInput.java index 3c735065d33..3578b2b13b2 100644 --- a/lucene/core/src/java/org/apache/lucene/store/RandomAccessInput.java +++ b/lucene/core/src/java/org/apache/lucene/store/RandomAccessInput.java @@ -25,6 +25,9 @@ import org.apache.lucene.util.BitUtil; // javadocs */ public interface RandomAccessInput { + /** The number of bytes in the file. */ + public long length(); + /** * Reads a byte at the given position in the file * diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java index 42d8d9bea3e..cdb8b5d983d 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/store/BaseDirectoryTestCase.java @@ -955,6 +955,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { // slice IndexInput input = dir.openInput("longs", newIOContext(random())); RandomAccessInput slice = input.randomAccessSlice(0, input.length()); + assertEquals(input.length(), slice.length()); for (int i = 0; i < longs.length; i++) { assertEquals(longs[i], slice.readLong(i * 8L)); } @@ -963,6 +964,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { for (int i = 1; i < longs.length; i++) { long offset = i * 8L; RandomAccessInput subslice = input.randomAccessSlice(offset, input.length() - offset); + assertEquals(input.length() - offset, subslice.length()); for (int j = i; j < longs.length; j++) { assertEquals(longs[j], subslice.readLong((j - i) * 8L)); } @@ -980,6 +982,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { o.close(); IndexInput padded = dir.openInput(name, newIOContext(random())); RandomAccessInput whole = padded.randomAccessSlice(i, padded.length() - i); + assertEquals(padded.length() - i, whole.length()); for (int j = 0; j < longs.length; j++) { assertEquals(longs[j], whole.readLong(j * 8L)); } @@ -1004,6 +1007,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { // slice IndexInput input = dir.openInput("ints", newIOContext(random())); RandomAccessInput slice = input.randomAccessSlice(0, input.length()); + assertEquals(input.length(), slice.length()); for (int i = 0; i < ints.length; i++) { assertEquals(ints[i], slice.readInt(i * 4L)); } @@ -1012,6 +1016,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { for (int i = 1; i < ints.length; i++) { long offset = i * 4L; RandomAccessInput subslice = input.randomAccessSlice(offset, input.length() - offset); + assertEquals(input.length() - offset, subslice.length()); for (int j = i; j < ints.length; j++) { assertEquals(ints[j], subslice.readInt((j - i) * 4L)); } @@ -1029,6 +1034,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { o.close(); IndexInput padded = dir.openInput(name, newIOContext(random())); RandomAccessInput whole = padded.randomAccessSlice(i, padded.length() - i); + assertEquals(padded.length() - i, whole.length()); for (int j = 0; j < ints.length; j++) { assertEquals(ints[j], whole.readInt(j * 4L)); } @@ -1052,6 +1058,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { // slice IndexInput input = dir.openInput("shorts", newIOContext(random())); RandomAccessInput slice = input.randomAccessSlice(0, input.length()); + assertEquals(input.length(), slice.length()); for (int i = 0; i < shorts.length; i++) { assertEquals(shorts[i], slice.readShort(i * 2L)); } @@ -1060,6 +1067,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { for (int i = 1; i < shorts.length; i++) { long offset = i * 2L; RandomAccessInput subslice = input.randomAccessSlice(offset, input.length() - offset); + assertEquals(input.length() - offset, subslice.length()); for (int j = i; j < shorts.length; j++) { assertEquals(shorts[j], subslice.readShort((j - i) * 2L)); } @@ -1077,6 +1085,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { o.close(); IndexInput padded = dir.openInput(name, newIOContext(random())); RandomAccessInput whole = padded.randomAccessSlice(i, padded.length() - i); + assertEquals(padded.length() - i, whole.length()); for (int j = 0; j < shorts.length; j++) { assertEquals(shorts[j], whole.readShort(j * 2L)); } @@ -1100,6 +1109,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { // slice IndexInput input = dir.openInput("bytes", newIOContext(random())); RandomAccessInput slice = input.randomAccessSlice(0, input.length()); + assertEquals(input.length(), slice.length()); for (int i = 0; i < bytes.length; i++) { assertEquals(bytes[i], slice.readByte(i)); } @@ -1108,6 +1118,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { for (int i = 1; i < bytes.length; i++) { long offset = i; RandomAccessInput subslice = input.randomAccessSlice(offset, input.length() - offset); + assertEquals(input.length() - offset, subslice.length()); for (int j = i; j < bytes.length; j++) { assertEquals(bytes[j], subslice.readByte(j - i)); } @@ -1125,6 +1136,7 @@ public abstract class BaseDirectoryTestCase extends LuceneTestCase { o.close(); IndexInput padded = dir.openInput(name, newIOContext(random())); RandomAccessInput whole = padded.randomAccessSlice(i, padded.length() - i); + assertEquals(padded.length() - i, whole.length()); for (int j = 0; j < bytes.length; j++) { assertEquals(bytes[j], whole.readByte(j)); }