FileDocCategorySizeDatePackage
BufferedIndexInput.javaAPI DocApache Lucene 2.2.06562Sat Jun 16 22:20:36 BST 2007org.apache.lucene.store

BufferedIndexInput

public abstract class BufferedIndexInput extends IndexInput
Base implementation class for buffered {@link IndexInput}.

Fields Summary
public static final int
BUFFER_SIZE
Default buffer size
private int
bufferSize
private byte[]
buffer
private long
bufferStart
private int
bufferLength
private int
bufferPosition
Constructors Summary
public BufferedIndexInput()

public BufferedIndexInput(int bufferSize)
Inits BufferedIndexInput with a specific bufferSize

    checkBufferSize(bufferSize);
    this.bufferSize = bufferSize;
  
Methods Summary
private voidcheckBufferSize(int bufferSize)

    if (bufferSize <= 0)
      throw new IllegalArgumentException("bufferSize must be greater than 0 (got " + bufferSize + ")");
  
public java.lang.Objectclone()

    BufferedIndexInput clone = (BufferedIndexInput)super.clone();

    clone.buffer = null;
    clone.bufferLength = 0;
    clone.bufferPosition = 0;
    clone.bufferStart = getFilePointer();

    return clone;
  
public intgetBufferSize()
Returns buffer size. @see #setBufferSize

    return bufferSize;
  
public longgetFilePointer()

 return bufferStart + bufferPosition; 
public bytereadByte()

		  // next byte to read

       
    if (bufferPosition >= bufferLength)
      refill();
    return buffer[bufferPosition++];
  
public voidreadBytes(byte[] b, int offset, int len)

    if(len <= (bufferLength-bufferPosition)){
      // the buffer contains enough data to satistfy this request
      if(len>0) // to allow b to be null if len is 0...
        System.arraycopy(buffer, bufferPosition, b, offset, len);
      bufferPosition+=len;
    } else {
      // the buffer does not have enough data. First serve all we've got.
      int available = bufferLength - bufferPosition;
      if(available > 0){
        System.arraycopy(buffer, bufferPosition, b, offset, available);
        offset += available;
        len -= available;
        bufferPosition += available;
      }
      // and now, read the remaining 'len' bytes:
      if(len<bufferSize){
        // If the amount left to read is small enough, do it in the usual
        // buffered way: fill the buffer and copy from it:
        refill();
        if(bufferLength<len){
          // Throw an exception when refill() could not read len bytes:
          System.arraycopy(buffer, 0, b, offset, bufferLength);
          throw new IOException("read past EOF");
        } else {
          System.arraycopy(buffer, 0, b, offset, len);
          bufferPosition=len;
        }
      } else {
        // The amount left to read is larger than the buffer - there's no
        // performance reason not to read it all at once. Note that unlike
        // the previous code of this function, there is no need to do a seek
        // here, because there's no need to reread what we had in the buffer.
        long after = bufferStart+bufferPosition+len;
        if(after > length())
          throw new IOException("read past EOF");
        readInternal(b, offset, len);
        bufferStart = after;
        bufferPosition = 0;
        bufferLength = 0;                    // trigger refill() on read
      }
    }
  
protected abstract voidreadInternal(byte[] b, int offset, int length)
Expert: implements buffer refill. Reads bytes from the current position in the input.

param
b the array to read bytes into
param
offset the offset in the array to start storing bytes
param
length the number of bytes to read

private voidrefill()

    long start = bufferStart + bufferPosition;
    long end = start + bufferSize;
    if (end > length())				  // don't read past EOF
      end = length();
    bufferLength = (int)(end - start);
    if (bufferLength <= 0)
      throw new IOException("read past EOF");

    if (buffer == null) {
      buffer = new byte[bufferSize];		  // allocate buffer lazily
      seekInternal(bufferStart);
    }
    readInternal(buffer, 0, bufferLength);

    bufferStart = start;
    bufferPosition = 0;
  
public voidseek(long pos)

    if (pos >= bufferStart && pos < (bufferStart + bufferLength))
      bufferPosition = (int)(pos - bufferStart);  // seek within buffer
    else {
      bufferStart = pos;
      bufferPosition = 0;
      bufferLength = 0;				  // trigger refill() on read()
      seekInternal(pos);
    }
  
protected abstract voidseekInternal(long pos)
Expert: implements seek. Sets current position in this file, where the next {@link #readInternal(byte[],int,int)} will occur.

see
#readInternal(byte[],int,int)

public voidsetBufferSize(int newSize)
Change the buffer size used by this IndexInput

    assert buffer == null || bufferSize == buffer.length;
    if (newSize != bufferSize) {
      checkBufferSize(newSize);
      bufferSize = newSize;
      if (buffer != null) {
        // Resize the existing buffer and carefully save as
        // many bytes as possible starting from the current
        // bufferPosition
        byte[] newBuffer = new byte[newSize];
        final int leftInBuffer = bufferLength-bufferPosition;
        final int numToCopy;
        if (leftInBuffer > newSize)
          numToCopy = newSize;
        else
          numToCopy = leftInBuffer;
        System.arraycopy(buffer, bufferPosition, newBuffer, 0, numToCopy);
        bufferStart += bufferPosition;
        bufferPosition = 0;
        bufferLength = numToCopy;
        buffer = newBuffer;
      }
    }