org.apache.lucene.store.IndexInput.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.lucene.store.IndexInput.java

Source

/*
 * 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.lucene.store;

import java.io.Closeable;
import java.io.IOException;

/** 
 * Abstract base class for input from a file in a {@link Directory}.  A
 * random-access input stream.  Used for all Lucene index input operations.
 *
 * <p>{@code IndexInput} may only be used from one thread, because it is not
 * thread safe (it keeps internal state like file position). To allow
 * multithreaded use, every {@code IndexInput} instance must be cloned before
 * it is used in another thread. Subclasses must therefore implement {@link #clone()},
 * returning a new {@code IndexInput} which operates on the same underlying
 * resource, but positioned independently. 
 * 
 * <p><b>Warning:</b> Lucene never closes cloned
 * {@code IndexInput}s, it will only call {@link #close()} on the original object.
 * 
 * <p>If you access the cloned IndexInput after closing the original object,
 * any <code>readXXX</code> methods will throw {@link AlreadyClosedException}.
 *
 * @see Directory
 */
public abstract class IndexInput extends DataInput implements Cloneable, Closeable {

    private final String resourceDescription;

    /** resourceDescription should be a non-null, opaque string
     *  describing this resource; it's returned from
     *  {@link #toString}. */
    protected IndexInput(String resourceDescription) {
        if (resourceDescription == null) {
            throw new IllegalArgumentException("resourceDescription must not be null");
        }
        this.resourceDescription = resourceDescription;
    }

    /** Closes the stream to further operations. */
    @Override
    public abstract void close() throws IOException;

    /** Returns the current position in this file, where the next read will
     * occur.
     * @see #seek(long)
     */
    public abstract long getFilePointer();

    /** Sets current position in this file, where the next read will occur.  If this is
     *  beyond the end of the file then this will throw {@code EOFException} and then the
     *  stream is in an undetermined state.
     *
     * @see #getFilePointer()
     */
    public abstract void seek(long pos) throws IOException;

    /** The number of bytes in the file. */
    public abstract long length();

    @Override
    public String toString() {
        return resourceDescription;
    }

    /** {@inheritDoc}
     * 
     * <p><b>Warning:</b> Lucene never closes cloned
     * {@code IndexInput}s, it will only call {@link #close()} on the original object.
     * 
     * <p>If you access the cloned IndexInput after closing the original object,
     * any <code>readXXX</code> methods will throw {@link AlreadyClosedException}.
     *
     * <p>This method is NOT thread safe, so if the current {@code IndexInput}
     * is being used by one thread while {@code clone} is called by another,
     * disaster could strike.
     */
    @Override
    public IndexInput clone() {
        return (IndexInput) super.clone();
    }

    /**
     * Creates a slice of this index input, with the given description, offset, and length. 
     * The slice is sought to the beginning.
     */
    public abstract IndexInput slice(String sliceDescription, long offset, long length) throws IOException;

    /** Subclasses call this to get the String for resourceDescription of a slice of this {@code IndexInput}. */
    protected String getFullSliceDescription(String sliceDescription) {
        if (sliceDescription == null) {
            // Clones pass null sliceDescription:
            return toString();
        } else {
            return toString() + " [slice=" + sliceDescription + "]";
        }
    }

    /**
     * Creates a random-access slice of this index input, with the given offset and length. 
     * <p>
     * The default implementation calls {@link #slice}, and it doesn't support random access,
     * it implements absolute reads as seek+read.
     */
    public RandomAccessInput randomAccessSlice(long offset, long length) throws IOException {
        final IndexInput slice = slice("randomaccess", offset, length);
        if (slice instanceof RandomAccessInput) {
            // slice() already supports random access
            return (RandomAccessInput) slice;
        } else {
            // return default impl
            return new RandomAccessInput() {
                @Override
                public byte readByte(long pos) throws IOException {
                    slice.seek(pos);
                    return slice.readByte();
                }

                @Override
                public short readShort(long pos) throws IOException {
                    slice.seek(pos);
                    return slice.readShort();
                }

                @Override
                public int readInt(long pos) throws IOException {
                    slice.seek(pos);
                    return slice.readInt();
                }

                @Override
                public long readLong(long pos) throws IOException {
                    slice.seek(pos);
                    return slice.readLong();
                }

                @Override
                public String toString() {
                    return "RandomAccessInput(" + IndexInput.this.toString() + ")";
                }
            };
        }
    }
}