@Test public void bufferLengthCanAlmostReachIntMaxValue() throws IOException { BlockGetter bigGetter = new BlockGetter() { @Override public void get(long firstBlock, long numBlocks, OutputStream destination) { } @Override public int expectedBlockLength() { return Integer.MAX_VALUE - 8; } }; BlockConsumingInputStream.ensureExpectedArraySizeDoesNotOverflow(bigGetter, 1); }
@VisibleForTesting static void ensureExpectedArraySizeDoesNotOverflow(BlockGetter blockGetter, int blocksInMemory) { int expectedBlockLength = blockGetter.expectedBlockLength(); int maxBlocksInMemory = StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD / expectedBlockLength; long expectedBufferSize = (long) expectedBlockLength * (long) blocksInMemory; Preconditions.checkArgument(blocksInMemory <= maxBlocksInMemory, "Promised to load too many blocks into memory. The underlying buffer is stored as a byte array, " + "so can only fit %s bytes. The supplied BlockGetter expected to produce " + "blocks of %s bytes, so %s of them (requested size %s) would cause the array to overflow.", StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD, expectedBlockLength, blocksInMemory, expectedBufferSize); }
BlockConsumingInputStream extends InputStream { @VisibleForTesting static void ensureExpectedArraySizeDoesNotOverflow(BlockGetter blockGetter, int blocksInMemory) { int expectedBlockLength = blockGetter.expectedBlockLength(); int maxBlocksInMemory = StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD / expectedBlockLength; long expectedBufferSize = (long) expectedBlockLength * (long) blocksInMemory; Preconditions.checkArgument(blocksInMemory <= maxBlocksInMemory, "Promised to load too many blocks into memory. The underlying buffer is stored as a byte array, " + "so can only fit %s bytes. The supplied BlockGetter expected to produce " + "blocks of %s bytes, so %s of them (requested size %s) would cause the array to overflow.", StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD, expectedBlockLength, blocksInMemory, expectedBufferSize); } }
BlockConsumingInputStream extends InputStream { @VisibleForTesting static void ensureExpectedArraySizeDoesNotOverflow(BlockGetter blockGetter, int blocksInMemory) { int expectedBlockLength = blockGetter.expectedBlockLength(); int maxBlocksInMemory = StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD / expectedBlockLength; long expectedBufferSize = (long) expectedBlockLength * (long) blocksInMemory; Preconditions.checkArgument(blocksInMemory <= maxBlocksInMemory, "Promised to load too many blocks into memory. The underlying buffer is stored as a byte array, " + "so can only fit %s bytes. The supplied BlockGetter expected to produce " + "blocks of %s bytes, so %s of them (requested size %s) would cause the array to overflow.", StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD, expectedBlockLength, blocksInMemory, expectedBufferSize); } private  BlockConsumingInputStream(BlockGetter blockGetter, long numBlocks, int blocksInMemory); }
BlockConsumingInputStream extends InputStream { @VisibleForTesting static void ensureExpectedArraySizeDoesNotOverflow(BlockGetter blockGetter, int blocksInMemory) { int expectedBlockLength = blockGetter.expectedBlockLength(); int maxBlocksInMemory = StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD / expectedBlockLength; long expectedBufferSize = (long) expectedBlockLength * (long) blocksInMemory; Preconditions.checkArgument(blocksInMemory <= maxBlocksInMemory, "Promised to load too many blocks into memory. The underlying buffer is stored as a byte array, " + "so can only fit %s bytes. The supplied BlockGetter expected to produce " + "blocks of %s bytes, so %s of them (requested size %s) would cause the array to overflow.", StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD, expectedBlockLength, blocksInMemory, expectedBufferSize); } private  BlockConsumingInputStream(BlockGetter blockGetter, long numBlocks, int blocksInMemory); static BlockConsumingInputStream create(
            BlockGetter blockGetter,
            long numBlocks,
            int blocksInMemory); @Override int read(); @Override int read(byte[] bytes, int off, int len); }
BlockConsumingInputStream extends InputStream { @VisibleForTesting static void ensureExpectedArraySizeDoesNotOverflow(BlockGetter blockGetter, int blocksInMemory) { int expectedBlockLength = blockGetter.expectedBlockLength(); int maxBlocksInMemory = StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD / expectedBlockLength; long expectedBufferSize = (long) expectedBlockLength * (long) blocksInMemory; Preconditions.checkArgument(blocksInMemory <= maxBlocksInMemory, "Promised to load too many blocks into memory. The underlying buffer is stored as a byte array, " + "so can only fit %s bytes. The supplied BlockGetter expected to produce " + "blocks of %s bytes, so %s of them (requested size %s) would cause the array to overflow.", StreamStoreDefinition.MAX_IN_MEMORY_THRESHOLD, expectedBlockLength, blocksInMemory, expectedBufferSize); } private  BlockConsumingInputStream(BlockGetter blockGetter, long numBlocks, int blocksInMemory); static BlockConsumingInputStream create(
            BlockGetter blockGetter,
            long numBlocks,
            int blocksInMemory); @Override int read(); @Override int read(byte[] bytes, int off, int len);  }