All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flink.runtime.state.gemini.engine.fs.GeminiBufferedInputStream Maven / Gradle / Ivy

There is a newer version: 1.5.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.flink.runtime.state.gemini.engine.fs;

import org.apache.flink.core.fs.FSDataInputStream;

import java.io.IOException;

/**
 * refer to {@link java.io.BufferedInputStream}.
 */
public class GeminiBufferedInputStream extends FSDataInputStream {

	private static final int DEFAULT_BUFFER_SIZE = 8192;

	/**
	 * The internal buffer array where the data is stored. When necessary,
	 * it may be replaced by another array of
	 * a different size.
	 */
	protected volatile byte[] buffer;

	/**
	 * The index one greater than the index of the last valid byte in
	 * the buffer.
	 * This value is always
	 * in the range 0 through buffer.length;
	 * elements buf[0]  through buffer[count-1]
	 * contain buffered input data obtained
	 * from the underlying  input stream.
	 */
	protected int count;

	/**
	 * The current position in the buffer. This is the index of the next
	 * character to be read from the buffer array.
	 *
	 * 

This value is always in the range 0 * through count. If it is less * than count, then buffer[pos] * is the next byte to be supplied as input; * if it is equal to count, then * the next read or skip * operation will require more bytes to be * read from the contained input stream. */ protected int pos; private final FSDataInputStream in; /** * Creates a GeminiBufferedInputStream * and saves its argument, the input stream * in, for later use. An internal * buffer array is created and stored in buf. * * @param in the underlying input stream. */ public GeminiBufferedInputStream(FSDataInputStream in) { this(in, DEFAULT_BUFFER_SIZE); } /** * Creates a GeminiBufferedInputStream * with the specified buffer size, * and saves its argument, the input stream * in, for later use. An internal * buffer array of length size * is created and stored in buf. * * @param in the underlying input stream. * @param size the buffer size. * @exception IllegalArgumentException if {@code size <= 0}. */ public GeminiBufferedInputStream(FSDataInputStream in, int size) { this.in = in; if (size <= 0) { throw new IllegalArgumentException("Buffer size <= 0"); } this.buffer = new byte[size]; } /** * Fills the buffer with more data. This method assumes that all data * has already been read in, hence pos > count. */ private void fill() throws IOException { count = 0; pos = 0; int n = in.read(buffer, pos, buffer.length); if (n > 0) { count = n + pos; } } @Override public int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) { return -1; } } return buffer[pos++] & 0xff; } /** * Read characters into a portion of an array, reading from the underlying * stream at most once if necessary. */ private int read1(byte[] b, int off, int len) throws IOException { int avail = count - pos; if (avail <= 0) { /* If the requested length is at least as large as the buffer, and if there is no mark/reset activity, do not bother to copy the bytes into the local buffer. In this way buffered streams will cascade harmlessly. */ if (len >= buffer.length) { return in.read(b, off, len); } fill(); avail = count - pos; if (avail <= 0) { return -1; } } int cnt = (avail < len) ? avail : len; System.arraycopy(buffer, pos, b, off, cnt); pos += cnt; return cnt; } /** * Reads bytes from this byte-input stream into the specified byte array, * starting at the given offset. * *

This method implements the general contract of the corresponding * {@link FSDataInputStream#read(byte[], int, int) read} method of * the {@link FSDataInputStream} class. As an additional * convenience, it attempts to read as many bytes as possible by repeatedly * invoking the read method of the underlying stream. This * iterated read continues until one of the following * conditions becomes true:

    * *
  • The specified number of bytes have been read, * *
  • The read method of the underlying stream returns * -1, indicating end-of-file, or * *
  • The available method of the underlying stream * returns zero, indicating that further input requests would block. * *
If the first read on the underlying stream returns * -1 to indicate end-of-file then this method returns * -1. Otherwise this method returns the number of bytes * actually read. * *

Subclasses of this class are encouraged, but not required, to * attempt to read as many bytes as possible in the same fashion. * * @param b destination buffer. * @param off offset at which to start storing bytes. * @param len maximum number of bytes to read. * @return the number of bytes read, or -1 if the end of * the stream has been reached. * @exception IOException if this input stream has been closed by * invoking its {@link #close()} method, * or an I/O error occurs. */ @Override public int read(byte[] b, int off, int len) throws IOException { if ((off | len | (off + len) | (b.length - (off + len))) < 0) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int n = 0; for ( ; ; ) { int nread = read1(b, off + n, len - n); if (nread <= 0) { return (n == 0) ? nread : n; } n += nread; if (n >= len || in.available() <= 0) { return n; } } } /** * See the general contract of the skip * method of FSDataInputStream. * * @exception IOException if the stream does not support seek, * or if this input stream has been closed by * invoking its {@link #close()} method, or an * I/O error occurs. */ @Override public long skip(long n) throws IOException { if (n <= 0) { return 0; } long avail = count - pos; if (avail <= 0) { return in.skip(n); } long skipped = (avail < n) ? avail : n; pos += skipped; return skipped; } @Override public int available() throws IOException { int n = count - pos; int avail = in.available(); return n > (Integer.MAX_VALUE - avail) ? Integer.MAX_VALUE : n + avail; } /** * Closes this input stream and releases any system resources * associated with the stream. * Once the stream has been closed, further read(), available(), reset(), * or skip() invocations will throw an IOException. * Closing a previously closed stream has no effect. * * @exception IOException if an I/O error occurs. */ @Override public void close() throws IOException { in.close(); buffer = null; } @Override public void seek(long desired) throws IOException { int avail = count - pos; if (avail <= 0) { in.seek(desired); return; } long upperPos = in.getPos(); long lowerPos = upperPos - count; if (desired > upperPos || desired < lowerPos) { pos = count; in.seek(desired); return; } pos = (int) (desired - lowerPos); } @Override public long getPos() throws IOException { long streamPos = in.getPos(); int n = count - pos; return streamPos - n; } public FSDataInputStream getWrappedInputStream() { return in; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy