Permit unbuffered index input.

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@150517 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Doug Cutting 2004-09-16 21:13:37 +00:00
parent faebce61db
commit 99fdf6af1f
25 changed files with 450 additions and 338 deletions

View File

@ -48,14 +48,18 @@ $Id$
9. PhraseQuery and PhrasePrefixQuery now allow the explicit specification 9. PhraseQuery and PhrasePrefixQuery now allow the explicit specification
of relative positions. (Christoph Goller) of relative positions. (Christoph Goller)
10. QueryParser changes: Fix for ArrayIndexOutOfBoundsExceptions 10. QueryParser changes: Fix for ArrayIndexOutOfBoundsExceptions
(patch #9110); some unused method parameters removed; The ability (patch #9110); some unused method parameters removed; The ability
to specify a minimum similarity for FuzzyQuery has been added. to specify a minimum similarity for FuzzyQuery has been added.
(Christoph Goller) (Christoph Goller)
11. Added support for binary stored fields (patch #29370) 11. Added support for binary stored fields (patch #29370)
(Drew Farris and Bernhard Messer via Christoph) (Drew Farris and Bernhard Messer via Christoph)
12. Permit unbuffered Directory implementations (e.g., using mmap).
InputStream is replaced by the new classes IndexInput and
BufferedIndexInput. InputStream is now deprecated and FSDirectory
is now subclassable. (cutting)
1.4.1 1.4.1

View File

@ -17,7 +17,8 @@ package org.apache.lucene.index;
*/ */
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.BufferedIndexInput;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
import org.apache.lucene.store.Lock; import org.apache.lucene.store.Lock;
import java.util.HashMap; import java.util.HashMap;
@ -44,7 +45,7 @@ class CompoundFileReader extends Directory {
private Directory directory; private Directory directory;
private String fileName; private String fileName;
private InputStream stream; private IndexInput stream;
private HashMap entries = new HashMap(); private HashMap entries = new HashMap();
@ -57,7 +58,7 @@ class CompoundFileReader extends Directory {
boolean success = false; boolean success = false;
try { try {
stream = dir.openFile(name); stream = dir.openInput(name);
// read the directory and init files // read the directory and init files
int count = stream.readVInt(); int count = stream.readVInt();
@ -109,7 +110,7 @@ class CompoundFileReader extends Directory {
stream = null; stream = null;
} }
public synchronized InputStream openFile(String id) public synchronized IndexInput openInput(String id)
throws IOException throws IOException
{ {
if (stream == null) if (stream == null)
@ -119,7 +120,7 @@ class CompoundFileReader extends Directory {
if (entry == null) if (entry == null)
throw new IOException("No sub-file with id " + id + " found"); throw new IOException("No sub-file with id " + id + " found");
return new CSInputStream(stream, entry.offset, entry.length); return new CSIndexInput(stream, entry.offset, entry.length);
} }
/** Returns an array of strings, one for each file in the directory. */ /** Returns an array of strings, one for each file in the directory. */
@ -182,21 +183,22 @@ class CompoundFileReader extends Directory {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/** Implementation of an InputStream that reads from a portion of the /** Implementation of an IndexInput that reads from a portion of the
* compound file. The visibility is left as "package" *only* because * compound file. The visibility is left as "package" *only* because
* this helps with testing since JUnit test cases in a different class * this helps with testing since JUnit test cases in a different class
* can then access package fields of this class. * can then access package fields of this class.
*/ */
static final class CSInputStream extends InputStream { static final class CSIndexInput extends BufferedIndexInput {
InputStream base; IndexInput base;
long fileOffset; long fileOffset;
long length;
CSInputStream(final InputStream base, final long fileOffset, final long length) CSIndexInput(final IndexInput base, final long fileOffset, final long length)
{ {
this.base = base; this.base = base;
this.fileOffset = fileOffset; this.fileOffset = fileOffset;
this.length = length; // variable in the superclass this.length = length;
} }
/** Expert: implements buffer refill. Reads bytes from the current /** Expert: implements buffer refill. Reads bytes from the current
@ -226,5 +228,10 @@ class CompoundFileReader extends Directory {
/** Closes the stream to further operations. */ /** Closes the stream to further operations. */
public void close() {} public void close() {}
public long length() {
return length;
}
} }
} }

View File

@ -18,7 +18,7 @@ package org.apache.lucene.index;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -196,11 +196,11 @@ final class CompoundFileWriter {
private void copyFile(FileEntry source, OutputStream os, byte buffer[]) private void copyFile(FileEntry source, OutputStream os, byte buffer[])
throws IOException throws IOException
{ {
InputStream is = null; IndexInput is = null;
try { try {
long startPtr = os.getFilePointer(); long startPtr = os.getFilePointer();
is = directory.openFile(source.file); is = directory.openInput(source.file);
long length = is.length(); long length = is.length();
long remainder = length; long remainder = length;
int chunk = buffer.length; int chunk = buffer.length;

View File

@ -24,7 +24,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
/** Access to the Field Info file that describes document fields and whether or /** Access to the Field Info file that describes document fields and whether or
* not they are indexed. Each segment has a separate Field Info file. Objects * not they are indexed. Each segment has a separate Field Info file. Objects
@ -42,13 +42,13 @@ final class FieldInfos {
/** /**
* Construct a FieldInfos object using the directory and the name of the file * Construct a FieldInfos object using the directory and the name of the file
* InputStream * IndexInput
* @param d The directory to open the InputStream from * @param d The directory to open the IndexInput from
* @param name The name of the file to open the InputStream from in the Directory * @param name The name of the file to open the IndexInput from in the Directory
* @throws IOException * @throws IOException
*/ */
FieldInfos(Directory d, String name) throws IOException { FieldInfos(Directory d, String name) throws IOException {
InputStream input = d.openFile(name); IndexInput input = d.openInput(name);
try { try {
read(input); read(input);
} finally { } finally {
@ -189,7 +189,7 @@ final class FieldInfos {
} }
} }
private void read(InputStream input) throws IOException { private void read(IndexInput input) throws IOException {
int size = input.readVInt();//read in the size int size = input.readVInt();//read in the size
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
String name = input.readString().intern(); String name = input.readString().intern();

View File

@ -21,7 +21,7 @@ import java.io.IOException;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
/** /**
* Class responsible for access to stored document fields. * Class responsible for access to stored document fields.
@ -32,15 +32,15 @@ import org.apache.lucene.store.InputStream;
*/ */
final class FieldsReader { final class FieldsReader {
private FieldInfos fieldInfos; private FieldInfos fieldInfos;
private InputStream fieldsStream; private IndexInput fieldsStream;
private InputStream indexStream; private IndexInput indexStream;
private int size; private int size;
FieldsReader(Directory d, String segment, FieldInfos fn) throws IOException { FieldsReader(Directory d, String segment, FieldInfos fn) throws IOException {
fieldInfos = fn; fieldInfos = fn;
fieldsStream = d.openFile(segment + ".fdt"); fieldsStream = d.openInput(segment + ".fdt");
indexStream = d.openFile(segment + ".fdx"); indexStream = d.openInput(segment + ".fdx");
size = (int)(indexStream.length() / 8); size = (int)(indexStream.length() / 8);
} }

View File

@ -25,7 +25,7 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.Lock; import org.apache.lucene.store.Lock;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
import org.apache.lucene.search.Similarity; import org.apache.lucene.search.Similarity;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
@ -606,7 +606,7 @@ public class IndexWriter {
if (!directory.fileExists("deletable")) if (!directory.fileExists("deletable"))
return result; return result;
InputStream input = directory.openFile("deletable"); IndexInput input = directory.openInput("deletable");
try { try {
for (int i = input.readInt(); i > 0; i--) // read file names for (int i = input.readInt(); i > 0; i--) // read file names
result.addElement(input.readString()); result.addElement(input.readString());

View File

@ -19,7 +19,7 @@ package org.apache.lucene.index;
import java.util.Vector; import java.util.Vector;
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
final class SegmentInfos extends Vector { final class SegmentInfos extends Vector {
@ -37,7 +37,7 @@ final class SegmentInfos extends Vector {
public final void read(Directory directory) throws IOException { public final void read(Directory directory) throws IOException {
InputStream input = directory.openFile("segments"); IndexInput input = directory.openInput("segments");
try { try {
int format = input.readInt(); int format = input.readInt();
if(format < 0){ // file contains explicit format info if(format < 0){ // file contains explicit format info
@ -103,7 +103,7 @@ final class SegmentInfos extends Vector {
public static long readCurrentVersion(Directory directory) public static long readCurrentVersion(Directory directory)
throws IOException { throws IOException {
InputStream input = directory.openFile("segments"); IndexInput input = directory.openInput("segments");
int format = 0; int format = 0;
long version = 0; long version = 0;
try { try {

View File

@ -25,7 +25,7 @@ import java.util.Set;
import java.util.Vector; import java.util.Vector;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BitVector; import org.apache.lucene.util.BitVector;
@ -49,20 +49,20 @@ final class SegmentReader extends IndexReader {
private boolean normsDirty = false; private boolean normsDirty = false;
private boolean undeleteAll = false; private boolean undeleteAll = false;
InputStream freqStream; IndexInput freqStream;
InputStream proxStream; IndexInput proxStream;
// Compound File Reader when based on a compound file segment // Compound File Reader when based on a compound file segment
CompoundFileReader cfsReader = null; CompoundFileReader cfsReader = null;
private class Norm { private class Norm {
public Norm(InputStream in, int number) public Norm(IndexInput in, int number)
{ {
this.in = in; this.in = in;
this.number = number; this.number = number;
} }
private InputStream in; private IndexInput in;
private byte[] bytes; private byte[] bytes;
private boolean dirty; private boolean dirty;
private int number; private int number;
@ -123,8 +123,8 @@ final class SegmentReader extends IndexReader {
// make sure that all index files have been read or are kept open // make sure that all index files have been read or are kept open
// so that if an index update removes them we'll still have them // so that if an index update removes them we'll still have them
freqStream = cfsDir.openFile(segment + ".frq"); freqStream = cfsDir.openInput(segment + ".frq");
proxStream = cfsDir.openFile(segment + ".prx"); proxStream = cfsDir.openInput(segment + ".prx");
openNorms(cfsDir); openNorms(cfsDir);
if (fieldInfos.hasVectors()) { // open term vector files only as needed if (fieldInfos.hasVectors()) { // open term vector files only as needed
@ -363,7 +363,7 @@ final class SegmentReader extends IndexReader {
return; return;
} }
InputStream normStream = (InputStream) norm.in.clone(); IndexInput normStream = (IndexInput) norm.in.clone();
try { // read from disk try { // read from disk
normStream.seek(0); normStream.seek(0);
normStream.readBytes(bytes, offset, maxDoc()); normStream.readBytes(bytes, offset, maxDoc());
@ -383,7 +383,7 @@ final class SegmentReader extends IndexReader {
fileName = segment + ".f" + fi.number; fileName = segment + ".f" + fi.number;
d = cfsDir; d = cfsDir;
} }
norms.put(fi.name, new Norm(d.openFile(fileName), fi.number)); norms.put(fi.name, new Norm(d.openInput(fileName), fi.number));
} }
} }
} }

View File

@ -18,11 +18,11 @@ package org.apache.lucene.index;
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.util.BitVector; import org.apache.lucene.util.BitVector;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
class SegmentTermDocs implements TermDocs { class SegmentTermDocs implements TermDocs {
protected SegmentReader parent; protected SegmentReader parent;
private InputStream freqStream; private IndexInput freqStream;
private int count; private int count;
private int df; private int df;
private BitVector deletedDocs; private BitVector deletedDocs;
@ -32,7 +32,7 @@ class SegmentTermDocs implements TermDocs {
private int skipInterval; private int skipInterval;
private int numSkips; private int numSkips;
private int skipCount; private int skipCount;
private InputStream skipStream; private IndexInput skipStream;
private int skipDoc; private int skipDoc;
private long freqPointer; private long freqPointer;
private long proxPointer; private long proxPointer;
@ -41,7 +41,7 @@ class SegmentTermDocs implements TermDocs {
SegmentTermDocs(SegmentReader parent) { SegmentTermDocs(SegmentReader parent) {
this.parent = parent; this.parent = parent;
this.freqStream = (InputStream) parent.freqStream.clone(); this.freqStream = (IndexInput) parent.freqStream.clone();
this.deletedDocs = parent.deletedDocs; this.deletedDocs = parent.deletedDocs;
this.skipInterval = parent.tis.getSkipInterval(); this.skipInterval = parent.tis.getSkipInterval();
} }
@ -147,7 +147,7 @@ class SegmentTermDocs implements TermDocs {
if (df >= skipInterval) { // optimized case if (df >= skipInterval) { // optimized case
if (skipStream == null) if (skipStream == null)
skipStream = (InputStream) freqStream.clone(); // lazily clone skipStream = (IndexInput) freqStream.clone(); // lazily clone
if (!haveSkipped) { // lazily seek skip stream if (!haveSkipped) { // lazily seek skip stream
skipStream.seek(skipPointer); skipStream.seek(skipPointer);

View File

@ -17,10 +17,10 @@ package org.apache.lucene.index;
*/ */
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
final class SegmentTermEnum extends TermEnum implements Cloneable { final class SegmentTermEnum extends TermEnum implements Cloneable {
private InputStream input; private IndexInput input;
FieldInfos fieldInfos; FieldInfos fieldInfos;
long size; long size;
long position = -1; long position = -1;
@ -38,7 +38,7 @@ final class SegmentTermEnum extends TermEnum implements Cloneable {
private char[] buffer = {}; private char[] buffer = {};
SegmentTermEnum(InputStream i, FieldInfos fis, boolean isi) SegmentTermEnum(IndexInput i, FieldInfos fis, boolean isi)
throws IOException { throws IOException {
input = i; input = i;
fieldInfos = fis; fieldInfos = fis;
@ -87,7 +87,7 @@ final class SegmentTermEnum extends TermEnum implements Cloneable {
clone = (SegmentTermEnum) super.clone(); clone = (SegmentTermEnum) super.clone();
} catch (CloneNotSupportedException e) {} } catch (CloneNotSupportedException e) {}
clone.input = (InputStream) input.clone(); clone.input = (IndexInput) input.clone();
clone.termInfo = new TermInfo(termInfo); clone.termInfo = new TermInfo(termInfo);
if (term != null) clone.growBuffer(term.text.length()); if (term != null) clone.growBuffer(term.text.length());

View File

@ -18,17 +18,17 @@ package org.apache.lucene.index;
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
final class SegmentTermPositions final class SegmentTermPositions
extends SegmentTermDocs implements TermPositions { extends SegmentTermDocs implements TermPositions {
private InputStream proxStream; private IndexInput proxStream;
private int proxCount; private int proxCount;
private int position; private int position;
SegmentTermPositions(SegmentReader p) throws IOException { SegmentTermPositions(SegmentReader p) throws IOException {
super(p); super(p);
this.proxStream = (InputStream)parent.proxStream.clone(); this.proxStream = (IndexInput)parent.proxStream.clone();
} }
final void seek(TermInfo ti) throws IOException { final void seek(TermInfo ti) throws IOException {

View File

@ -39,12 +39,17 @@ final class TermInfosReader {
segment = seg; segment = seg;
fieldInfos = fis; fieldInfos = fis;
origEnum = new SegmentTermEnum(directory.openFile(segment + ".tis"), origEnum = new SegmentTermEnum(directory.openInput(segment + ".tis"),
fieldInfos, false); fieldInfos, false);
size = origEnum.size; size = origEnum.size;
readIndex(); readIndex();
} }
protected void finalize() {
// patch for pre-1.4.2 JVMs, whose ThreadLocals leak
enumerators.set(null);
}
public int getSkipInterval() { public int getSkipInterval() {
return origEnum.skipInterval; return origEnum.skipInterval;
} }
@ -74,7 +79,7 @@ final class TermInfosReader {
private final void readIndex() throws IOException { private final void readIndex() throws IOException {
SegmentTermEnum indexEnum = SegmentTermEnum indexEnum =
new SegmentTermEnum(directory.openFile(segment + ".tii"), new SegmentTermEnum(directory.openInput(segment + ".tii"),
fieldInfos, true); fieldInfos, true);
try { try {
int indexSize = (int)indexEnum.size; int indexSize = (int)indexEnum.size;

View File

@ -17,7 +17,7 @@ package org.apache.lucene.index;
*/ */
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import java.io.IOException; import java.io.IOException;
@ -29,19 +29,19 @@ import java.io.IOException;
class TermVectorsReader { class TermVectorsReader {
private FieldInfos fieldInfos; private FieldInfos fieldInfos;
private InputStream tvx; private IndexInput tvx;
private InputStream tvd; private IndexInput tvd;
private InputStream tvf; private IndexInput tvf;
private int size; private int size;
TermVectorsReader(Directory d, String segment, FieldInfos fieldInfos) TermVectorsReader(Directory d, String segment, FieldInfos fieldInfos)
throws IOException { throws IOException {
if (d.fileExists(segment + TermVectorsWriter.TVX_EXTENSION)) { if (d.fileExists(segment + TermVectorsWriter.TVX_EXTENSION)) {
tvx = d.openFile(segment + TermVectorsWriter.TVX_EXTENSION); tvx = d.openInput(segment + TermVectorsWriter.TVX_EXTENSION);
checkValidFormat(tvx); checkValidFormat(tvx);
tvd = d.openFile(segment + TermVectorsWriter.TVD_EXTENSION); tvd = d.openInput(segment + TermVectorsWriter.TVD_EXTENSION);
checkValidFormat(tvd); checkValidFormat(tvd);
tvf = d.openFile(segment + TermVectorsWriter.TVF_EXTENSION); tvf = d.openInput(segment + TermVectorsWriter.TVF_EXTENSION);
checkValidFormat(tvf); checkValidFormat(tvf);
size = (int) tvx.length() / 8; size = (int) tvx.length() / 8;
} }
@ -49,7 +49,7 @@ class TermVectorsReader {
this.fieldInfos = fieldInfos; this.fieldInfos = fieldInfos;
} }
private void checkValidFormat(InputStream in) throws IOException private void checkValidFormat(IndexInput in) throws IOException
{ {
int format = in.readInt(); int format = in.readInt();
if (format > TermVectorsWriter.FORMAT_VERSION) if (format > TermVectorsWriter.FORMAT_VERSION)

View File

@ -0,0 +1,109 @@
package org.apache.lucene.store;
/**
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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.
*/
import java.io.IOException;
/** Base implementation class for buffered {@link IndexInput}. */
public abstract class BufferedIndexInput extends IndexInput {
static final int BUFFER_SIZE = OutputStream.BUFFER_SIZE;
private byte[] buffer;
private long bufferStart = 0; // position in file of buffer
private int bufferLength = 0; // end of valid bytes
private int bufferPosition = 0; // next byte to read
public byte readByte() throws IOException {
if (bufferPosition >= bufferLength)
refill();
return buffer[bufferPosition++];
}
public void readBytes(byte[] b, int offset, int len)
throws IOException {
if (len < BUFFER_SIZE) {
for (int i = 0; i < len; i++) // read byte-by-byte
b[i + offset] = (byte)readByte();
} else { // read all-at-once
long start = getFilePointer();
seekInternal(start);
readInternal(b, offset, len);
bufferStart = start + len; // adjust stream variables
bufferPosition = 0;
bufferLength = 0; // trigger refill() on read
}
}
private void refill() throws IOException {
long start = bufferStart + bufferPosition;
long end = start + BUFFER_SIZE;
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[BUFFER_SIZE]; // allocate buffer lazily
readInternal(buffer, 0, bufferLength);
bufferStart = start;
bufferPosition = 0;
}
/** 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
*/
protected abstract void readInternal(byte[] b, int offset, int length)
throws IOException;
public long getFilePointer() { return bufferStart + bufferPosition; }
public void seek(long pos) throws IOException {
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);
}
}
/** Expert: implements seek. Sets current position in this file, where the
* next {@link #readInternal(byte[],int,int)} will occur.
* @see #readInternal(byte[],int,int)
*/
protected abstract void seekInternal(long pos) throws IOException;
public Object clone() {
BufferedIndexInput clone = (BufferedIndexInput)super.clone();
if (buffer != null) {
clone.buffer = new byte[BUFFER_SIZE];
System.arraycopy(buffer, 0, clone.buffer, 0, bufferLength);
}
return clone;
}
}

View File

@ -67,9 +67,18 @@ public abstract class Directory {
public abstract OutputStream createFile(String name) public abstract OutputStream createFile(String name)
throws IOException; throws IOException;
/** @deprecated use {@link openInput(String)}. */
public InputStream openFile(String name) throws IOException {
return (InputStream)openInput(name);
}
/** Returns a stream reading an existing file. */ /** Returns a stream reading an existing file. */
public abstract InputStream openFile(String name) public IndexInput openInput(String name)
throws IOException; throws IOException {
// default implementation for back compatibility
// this method should be abstract
return (IndexInput)openFile(name);
}
/** Construct a {@link Lock}. /** Construct a {@link Lock}.
* @param name the name of the lock file * @param name the name of the lock file

View File

@ -56,6 +56,19 @@ public class FSDirectory extends Directory {
System.getProperty("org.apache.lucene.lockdir", System.getProperty("org.apache.lucene.lockdir",
System.getProperty("java.io.tmpdir")); System.getProperty("java.io.tmpdir"));
/** The default class which implements filesystem-based directories. */
private static final Class IMPL;
static {
try {
String name =
System.getProperty("org.apache.lucene.FSDirectory.class",
FSDirectory.class.getName());
IMPL = Class.forName(name);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private static MessageDigest DIGESTER; private static MessageDigest DIGESTER;
static { static {
@ -99,7 +112,12 @@ public class FSDirectory extends Directory {
synchronized (DIRECTORIES) { synchronized (DIRECTORIES) {
dir = (FSDirectory)DIRECTORIES.get(file); dir = (FSDirectory)DIRECTORIES.get(file);
if (dir == null) { if (dir == null) {
dir = new FSDirectory(file, create); try {
dir = (FSDirectory)IMPL.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
dir.init(file, create);
DIRECTORIES.put(file, dir); DIRECTORIES.put(file, dir);
} else if (create) { } else if (create) {
dir.create(); dir.create();
@ -115,7 +133,9 @@ public class FSDirectory extends Directory {
private int refCount; private int refCount;
private File lockDir; private File lockDir;
private FSDirectory(File path, boolean create) throws IOException { protected FSDirectory() {}; // permit subclassing
private void init(File path, boolean create) throws IOException {
directory = path; directory = path;
if (LOCK_DIR == null) { if (LOCK_DIR == null) {
@ -360,7 +380,7 @@ public class FSDirectory extends Directory {
/** For debug output. */ /** For debug output. */
public String toString() { public String toString() {
return "FSDirectory@" + directory; return this.getClass().getName() + "@" + directory;
} }
} }

View File

@ -0,0 +1,156 @@
package org.apache.lucene.store;
/**
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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.
*/
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.
* @see Directory
*/
public abstract class IndexInput implements Cloneable {
private char[] chars; // used by readString()
/** Reads and returns a single byte.
* @see OutputStream#writeByte(byte)
*/
public abstract byte readByte() throws IOException;
/** Reads a specified number of bytes into an array at the specified offset.
* @param b the array to read bytes into
* @param offset the offset in the array to start storing bytes
* @param len the number of bytes to read
* @see OutputStream#writeBytes(byte[],int)
*/
public abstract void readBytes(byte[] b, int offset, int len)
throws IOException;
/** Reads four bytes and returns an int.
* @see OutputStream#writeInt(int)
*/
public int readInt() throws IOException {
return ((readByte() & 0xFF) << 24) | ((readByte() & 0xFF) << 16)
| ((readByte() & 0xFF) << 8) | (readByte() & 0xFF);
}
/** Reads an int stored in variable-length format. Reads between one and
* five bytes. Smaller values take fewer bytes. Negative numbers are not
* supported.
* @see OutputStream#writeVInt(int)
*/
public int readVInt() throws IOException {
byte b = readByte();
int i = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = readByte();
i |= (b & 0x7F) << shift;
}
return i;
}
/** Reads eight bytes and returns a long.
* @see OutputStream#writeLong(long)
*/
public long readLong() throws IOException {
return (((long)readInt()) << 32) | (readInt() & 0xFFFFFFFFL);
}
/** Reads a long stored in variable-length format. Reads between one and
* nine bytes. Smaller values take fewer bytes. Negative numbers are not
* supported. */
public long readVLong() throws IOException {
byte b = readByte();
long i = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = readByte();
i |= (b & 0x7FL) << shift;
}
return i;
}
/** Reads a string.
* @see OutputStream#writeString(String)
*/
public String readString() throws IOException {
int length = readVInt();
if (chars == null || length > chars.length)
chars = new char[length];
readChars(chars, 0, length);
return new String(chars, 0, length);
}
/** Reads UTF-8 encoded characters into an array.
* @param buffer the array to read characters into
* @param start the offset in the array to start storing characters
* @param length the number of characters to read
* @see OutputStream#writeChars(String,int,int)
*/
public void readChars(char[] buffer, int start, int length)
throws IOException {
final int end = start + length;
for (int i = start; i < end; i++) {
byte b = readByte();
if ((b & 0x80) == 0)
buffer[i] = (char)(b & 0x7F);
else if ((b & 0xE0) != 0xE0) {
buffer[i] = (char)(((b & 0x1F) << 6)
| (readByte() & 0x3F));
} else
buffer[i] = (char)(((b & 0x0F) << 12)
| ((readByte() & 0x3F) << 6)
| (readByte() & 0x3F));
}
}
/** Closes the stream to futher operations. */
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.
* @see #getFilePointer()
*/
public abstract void seek(long pos) throws IOException;
/** The number of bytes in the file. */
public abstract long length();
/** Returns a clone of this stream.
*
* <p>Clones of a stream access the same data, and are positioned at the same
* point as the stream they were cloned from.
*
* <p>Expert: Subclasses must ensure that clones may be positioned at
* different points in the input from each other and from the stream they
* were cloned from.
*/
public Object clone() {
IndexInput clone = null;
try {
clone = (IndexInput)super.clone();
} catch (CloneNotSupportedException e) {}
clone.chars = null;
return clone;
}
}

View File

@ -18,217 +18,13 @@ package org.apache.lucene.store;
import java.io.IOException; import java.io.IOException;
/** Abstract base class for input from a file in a {@link Directory}. A /** @deprecated Use {@link IndexInput} or {@link BufferedIndexInput} instead.*/
* random-access input stream. Used for all Lucene index input operations. public abstract class InputStream extends BufferedIndexInput {
* @see Directory
* @see OutputStream
*/
public abstract class InputStream implements Cloneable {
static final int BUFFER_SIZE = OutputStream.BUFFER_SIZE;
private byte[] buffer;
private char[] chars;
private long bufferStart = 0; // position in file of buffer
private int bufferLength = 0; // end of valid bytes
private int bufferPosition = 0; // next byte to read
protected long length; // set by subclasses protected long length; // set by subclasses
/** Reads and returns a single byte. public long length() {
* @see OutputStream#writeByte(byte)
*/
public final byte readByte() throws IOException {
if (bufferPosition >= bufferLength)
refill();
return buffer[bufferPosition++];
}
/** Reads a specified number of bytes into an array at the specified offset.
* @param b the array to read bytes into
* @param offset the offset in the array to start storing bytes
* @param len the number of bytes to read
* @see OutputStream#writeBytes(byte[],int)
*/
public final void readBytes(byte[] b, int offset, int len)
throws IOException {
if (len < BUFFER_SIZE) {
for (int i = 0; i < len; i++) // read byte-by-byte
b[i + offset] = (byte)readByte();
} else { // read all-at-once
long start = getFilePointer();
seekInternal(start);
readInternal(b, offset, len);
bufferStart = start + len; // adjust stream variables
bufferPosition = 0;
bufferLength = 0; // trigger refill() on read
}
}
/** Reads four bytes and returns an int.
* @see OutputStream#writeInt(int)
*/
public final int readInt() throws IOException {
return ((readByte() & 0xFF) << 24) | ((readByte() & 0xFF) << 16)
| ((readByte() & 0xFF) << 8) | (readByte() & 0xFF);
}
/** Reads an int stored in variable-length format. Reads between one and
* five bytes. Smaller values take fewer bytes. Negative numbers are not
* supported.
* @see OutputStream#writeVInt(int)
*/
public final int readVInt() throws IOException {
byte b = readByte();
int i = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = readByte();
i |= (b & 0x7F) << shift;
}
return i;
}
/** Reads eight bytes and returns a long.
* @see OutputStream#writeLong(long)
*/
public final long readLong() throws IOException {
return (((long)readInt()) << 32) | (readInt() & 0xFFFFFFFFL);
}
/** Reads a long stored in variable-length format. Reads between one and
* nine bytes. Smaller values take fewer bytes. Negative numbers are not
* supported. */
public final long readVLong() throws IOException {
byte b = readByte();
long i = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = readByte();
i |= (b & 0x7FL) << shift;
}
return i;
}
/** Reads a string.
* @see OutputStream#writeString(String)
*/
public final String readString() throws IOException {
int length = readVInt();
if (chars == null || length > chars.length)
chars = new char[length];
readChars(chars, 0, length);
return new String(chars, 0, length);
}
/** Reads UTF-8 encoded characters into an array.
* @param buffer the array to read characters into
* @param start the offset in the array to start storing characters
* @param length the number of characters to read
* @see OutputStream#writeChars(String,int,int)
*/
public final void readChars(char[] buffer, int start, int length)
throws IOException {
final int end = start + length;
for (int i = start; i < end; i++) {
byte b = readByte();
if ((b & 0x80) == 0)
buffer[i] = (char)(b & 0x7F);
else if ((b & 0xE0) != 0xE0) {
buffer[i] = (char)(((b & 0x1F) << 6)
| (readByte() & 0x3F));
} else
buffer[i] = (char)(((b & 0x0F) << 12)
| ((readByte() & 0x3F) << 6)
| (readByte() & 0x3F));
}
}
private void refill() throws IOException {
long start = bufferStart + bufferPosition;
long end = start + BUFFER_SIZE;
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[BUFFER_SIZE]; // allocate buffer lazily
readInternal(buffer, 0, bufferLength);
bufferStart = start;
bufferPosition = 0;
}
/** 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
*/
protected abstract void readInternal(byte[] b, int offset, int length)
throws IOException;
/** Closes the stream to futher operations. */
public abstract void close() throws IOException;
/** Returns the current position in this file, where the next read will
* occur.
* @see #seek(long)
*/
public final long getFilePointer() {
return bufferStart + bufferPosition;
}
/** Sets current position in this file, where the next read will occur.
* @see #getFilePointer()
*/
public final void seek(long pos) throws IOException {
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);
}
}
/** Expert: implements seek. Sets current position in this file, where the
* next {@link #readInternal(byte[],int,int)} will occur.
* @see #readInternal(byte[],int,int)
*/
protected abstract void seekInternal(long pos) throws IOException;
/** The number of bytes in the file. */
public final long length() {
return length; return length;
} }
/** Returns a clone of this stream.
*
* <p>Clones of a stream access the same data, and are positioned at the same
* point as the stream they were cloned from.
*
* <p>Expert: Subclasses must ensure that clones may be positioned at
* different points in the input from each other and from the stream they
* were cloned from.
*/
public Object clone() {
InputStream clone = null;
try {
clone = (InputStream)super.clone();
} catch (CloneNotSupportedException e) {}
if (buffer != null) {
clone.buffer = new byte[BUFFER_SIZE];
System.arraycopy(buffer, 0, clone.buffer, 0, bufferLength);
}
clone.chars = null;
return clone;
}
} }

View File

@ -19,7 +19,7 @@ package org.apache.lucene.util;
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
/** Optimized implementation of a vector of bits. This is more-or-less like /** Optimized implementation of a vector of bits. This is more-or-less like
@ -122,7 +122,7 @@ public final class BitVector {
<code>d</code>, as written by the {@link #write} method. <code>d</code>, as written by the {@link #write} method.
*/ */
public BitVector(Directory d, String name) throws IOException { public BitVector(Directory d, String name) throws IOException {
InputStream input = d.openFile(name); IndexInput input = d.openInput(name);
try { try {
size = input.readInt(); // read size size = input.readInt(); // read size
count = input.readInt(); // read count count = input.readInt(); // read count

View File

@ -17,7 +17,7 @@ and <a href="org/apache/lucene/util/PriorityQueue.html">PriorityQueue</a>.</li>
<b><a href="org/apache/lucene/store/package-summary.html">org.apache.lucene.store</a></b> <b><a href="org/apache/lucene/store/package-summary.html">org.apache.lucene.store</a></b>
defines an abstract class for storing persistent data, the <a href="org/apache/lucene/store/Directory.html">Directory</a>, defines an abstract class for storing persistent data, the <a href="org/apache/lucene/store/Directory.html">Directory</a>,
a collection of named files written by an <a href="org/apache/lucene/store/OutputStream.html">OutputStream</a> a collection of named files written by an <a href="org/apache/lucene/store/OutputStream.html">OutputStream</a>
and read by an <a href="org/apache/lucene/store/InputStream.html">InputStream</a>.&nbsp; and read by an <a href="org/apache/lucene/store/IndexInput.html">IndexInput</a>.&nbsp;
Two implementations are provided, <a href="org/apache/lucene/store/FSDirectory.html">FSDirectory</a>, Two implementations are provided, <a href="org/apache/lucene/store/FSDirectory.html">FSDirectory</a>,
which uses a file system directory to store files, and <a href="org/apache/lucene/store/RAMDirectory.html">RAMDirectory</a> which uses a file system directory to store files, and <a href="org/apache/lucene/store/RAMDirectory.html">RAMDirectory</a>
which implements files as memory-resident data structures.</li> which implements files as memory-resident data structures.</li>

View File

@ -17,7 +17,7 @@ package org.apache.lucene;
*/ */
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.store.RAMDirectory;
@ -84,7 +84,7 @@ class StoreTest {
byte b = (byte)(gen.nextInt() & 0x7F); byte b = (byte)(gen.nextInt() & 0x7F);
//System.out.println("reading " + name + " with " + length + " of " + b); //System.out.println("reading " + name + " with " + length + " of " + b);
InputStream file = store.openFile(name); IndexInput file = store.openInput(name);
if (file.length() != length) if (file.length() != length)
throw new Exception("length incorrect"); throw new Exception("length incorrect");

View File

@ -16,15 +16,16 @@ package org.apache.lucene.index;
* limitations under the License. * limitations under the License.
*/ */
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.BufferedIndexInput;
import java.io.IOException; import java.io.IOException;
public class MockInputStream extends InputStream { public class MockIndexInput extends BufferedIndexInput {
private byte[] buffer; private byte[] buffer;
private int pointer = 0; private int pointer = 0;
private long length;
public MockInputStream(byte[] bytes) { public MockIndexInput(byte[] bytes) {
buffer = bytes; buffer = bytes;
length = bytes.length; length = bytes.length;
} }
@ -53,4 +54,9 @@ public class MockInputStream extends InputStream {
protected void seekInternal(long pos) throws IOException { protected void seekInternal(long pos) throws IOException {
pointer = (int) pos; pointer = (int) pos;
} }
public long length() {
return length;
}
} }

View File

@ -24,7 +24,7 @@ import junit.framework.TestSuite;
import junit.textui.TestRunner; import junit.textui.TestRunner;
import org.apache.lucene.store.OutputStream; import org.apache.lucene.store.OutputStream;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store._TestHelper; import org.apache.lucene.store._TestHelper;
@ -94,8 +94,8 @@ public class TestCompoundFile extends TestCase
private void assertSameStreams(String msg, private void assertSameStreams(String msg,
InputStream expected, IndexInput expected,
InputStream test) IndexInput test)
throws IOException throws IOException
{ {
assertNotNull(msg + " null expected", expected); assertNotNull(msg + " null expected", expected);
@ -120,8 +120,8 @@ public class TestCompoundFile extends TestCase
private void assertSameStreams(String msg, private void assertSameStreams(String msg,
InputStream expected, IndexInput expected,
InputStream actual, IndexInput actual,
long seekTo) long seekTo)
throws IOException throws IOException
{ {
@ -136,8 +136,8 @@ public class TestCompoundFile extends TestCase
private void assertSameSeekBehavior(String msg, private void assertSameSeekBehavior(String msg,
InputStream expected, IndexInput expected,
InputStream actual) IndexInput actual)
throws IOException throws IOException
{ {
// seek to 0 // seek to 0
@ -199,8 +199,8 @@ public class TestCompoundFile extends TestCase
csw.close(); csw.close();
CompoundFileReader csr = new CompoundFileReader(dir, name + ".cfs"); CompoundFileReader csr = new CompoundFileReader(dir, name + ".cfs");
InputStream expected = dir.openFile(name); IndexInput expected = dir.openInput(name);
InputStream actual = csr.openFile(name); IndexInput actual = csr.openInput(name);
assertSameStreams(name, expected, actual); assertSameStreams(name, expected, actual);
assertSameSeekBehavior(name, expected, actual); assertSameSeekBehavior(name, expected, actual);
expected.close(); expected.close();
@ -223,15 +223,15 @@ public class TestCompoundFile extends TestCase
csw.close(); csw.close();
CompoundFileReader csr = new CompoundFileReader(dir, "d.csf"); CompoundFileReader csr = new CompoundFileReader(dir, "d.csf");
InputStream expected = dir.openFile("d1"); IndexInput expected = dir.openInput("d1");
InputStream actual = csr.openFile("d1"); IndexInput actual = csr.openInput("d1");
assertSameStreams("d1", expected, actual); assertSameStreams("d1", expected, actual);
assertSameSeekBehavior("d1", expected, actual); assertSameSeekBehavior("d1", expected, actual);
expected.close(); expected.close();
actual.close(); actual.close();
expected = dir.openFile("d2"); expected = dir.openInput("d2");
actual = csr.openFile("d2"); actual = csr.openInput("d2");
assertSameStreams("d2", expected, actual); assertSameStreams("d2", expected, actual);
assertSameSeekBehavior("d2", expected, actual); assertSameSeekBehavior("d2", expected, actual);
expected.close(); expected.close();
@ -279,8 +279,8 @@ public class TestCompoundFile extends TestCase
CompoundFileReader csr = new CompoundFileReader(dir, "test.cfs"); CompoundFileReader csr = new CompoundFileReader(dir, "test.cfs");
for (int i=0; i<data.length; i++) { for (int i=0; i<data.length; i++) {
InputStream check = dir.openFile(segment + data[i]); IndexInput check = dir.openInput(segment + data[i]);
InputStream test = csr.openFile(segment + data[i]); IndexInput test = csr.openInput(segment + data[i]);
assertSameStreams(data[i], check, test); assertSameStreams(data[i], check, test);
assertSameSeekBehavior(data[i], check, test); assertSameSeekBehavior(data[i], check, test);
test.close(); test.close();
@ -319,9 +319,9 @@ public class TestCompoundFile extends TestCase
} }
os.close(); os.close();
InputStream in = fsdir.openFile(file); IndexInput in = fsdir.openInput(file);
// This read primes the buffer in InputStream // This read primes the buffer in IndexInput
byte b = in.readByte(); byte b = in.readByte();
// Close the file // Close the file
@ -343,14 +343,14 @@ public class TestCompoundFile extends TestCase
} }
static boolean isCSInputStream(InputStream is) { static boolean isCSIndexInput(IndexInput is) {
return is instanceof CompoundFileReader.CSInputStream; return is instanceof CompoundFileReader.CSIndexInput;
} }
static boolean isCSInputStreamOpen(InputStream is) throws IOException { static boolean isCSIndexInputOpen(IndexInput is) throws IOException {
if (isCSInputStream(is)) { if (isCSIndexInput(is)) {
CompoundFileReader.CSInputStream cis = CompoundFileReader.CSIndexInput cis =
(CompoundFileReader.CSInputStream) is; (CompoundFileReader.CSIndexInput) is;
return _TestHelper.isFSInputStreamOpen(cis.base); return _TestHelper.isFSInputStreamOpen(cis.base);
} else { } else {
@ -364,14 +364,14 @@ public class TestCompoundFile extends TestCase
CompoundFileReader cr = new CompoundFileReader(dir, "f.comp"); CompoundFileReader cr = new CompoundFileReader(dir, "f.comp");
// basic clone // basic clone
InputStream expected = dir.openFile("f11"); IndexInput expected = dir.openInput("f11");
assertTrue(_TestHelper.isFSInputStreamOpen(expected)); assertTrue(_TestHelper.isFSInputStreamOpen(expected));
InputStream one = cr.openFile("f11"); IndexInput one = cr.openInput("f11");
assertTrue(isCSInputStreamOpen(one)); assertTrue(isCSIndexInputOpen(one));
InputStream two = (InputStream) one.clone(); IndexInput two = (IndexInput) one.clone();
assertTrue(isCSInputStreamOpen(two)); assertTrue(isCSIndexInputOpen(two));
assertSameStreams("basic clone one", expected, one); assertSameStreams("basic clone one", expected, one);
expected.seek(0); expected.seek(0);
@ -379,7 +379,7 @@ public class TestCompoundFile extends TestCase
// Now close the first stream // Now close the first stream
one.close(); one.close();
assertTrue("Only close when cr is closed", isCSInputStreamOpen(one)); assertTrue("Only close when cr is closed", isCSIndexInputOpen(one));
// The following should really fail since we couldn't expect to // The following should really fail since we couldn't expect to
// access a file once close has been called on it (regardless of // access a file once close has been called on it (regardless of
@ -391,8 +391,8 @@ public class TestCompoundFile extends TestCase
// Now close the compound reader // Now close the compound reader
cr.close(); cr.close();
assertFalse("Now closed one", isCSInputStreamOpen(one)); assertFalse("Now closed one", isCSIndexInputOpen(one));
assertFalse("Now closed two", isCSInputStreamOpen(two)); assertFalse("Now closed two", isCSIndexInputOpen(two));
// The following may also fail since the compound stream is closed // The following may also fail since the compound stream is closed
expected.seek(0); expected.seek(0);
@ -418,11 +418,11 @@ public class TestCompoundFile extends TestCase
CompoundFileReader cr = new CompoundFileReader(dir, "f.comp"); CompoundFileReader cr = new CompoundFileReader(dir, "f.comp");
// Open two files // Open two files
InputStream e1 = dir.openFile("f11"); IndexInput e1 = dir.openInput("f11");
InputStream e2 = dir.openFile("f3"); IndexInput e2 = dir.openInput("f3");
InputStream a1 = cr.openFile("f11"); IndexInput a1 = cr.openInput("f11");
InputStream a2 = dir.openFile("f3"); IndexInput a2 = dir.openInput("f3");
// Seek the first pair // Seek the first pair
e1.seek(100); e1.seek(100);
@ -497,11 +497,11 @@ public class TestCompoundFile extends TestCase
CompoundFileReader cr = new CompoundFileReader(dir, "f.comp"); CompoundFileReader cr = new CompoundFileReader(dir, "f.comp");
// Open two files // Open two files
InputStream e1 = cr.openFile("f11"); IndexInput e1 = cr.openInput("f11");
InputStream e2 = cr.openFile("f3"); IndexInput e2 = cr.openInput("f3");
InputStream a1 = (InputStream) e1.clone(); IndexInput a1 = (IndexInput) e1.clone();
InputStream a2 = (InputStream) e2.clone(); IndexInput a2 = (IndexInput) e2.clone();
// Seek the first pair // Seek the first pair
e1.seek(100); e1.seek(100);
@ -575,7 +575,7 @@ public class TestCompoundFile extends TestCase
// Open two files // Open two files
try { try {
InputStream e1 = cr.openFile("bogus"); IndexInput e1 = cr.openInput("bogus");
fail("File not found"); fail("File not found");
} catch (IOException e) { } catch (IOException e) {
@ -590,7 +590,7 @@ public class TestCompoundFile extends TestCase
public void testReadPastEOF() throws IOException { public void testReadPastEOF() throws IOException {
setUp_2(); setUp_2();
CompoundFileReader cr = new CompoundFileReader(dir, "f.comp"); CompoundFileReader cr = new CompoundFileReader(dir, "f.comp");
InputStream is = cr.openFile("f2"); IndexInput is = cr.openInput("f2");
is.seek(is.length() - 10); is.seek(is.length() - 10);
byte b[] = new byte[100]; byte b[] = new byte[100];
is.readBytes(b, 0, 10); is.readBytes(b, 0, 10);

View File

@ -17,17 +17,17 @@ package org.apache.lucene.index;
*/ */
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.lucene.store.InputStream; import org.apache.lucene.store.IndexInput;
import java.io.IOException; import java.io.IOException;
public class TestInputStream extends TestCase { public class TestIndexInput extends TestCase {
public void testRead() throws IOException { public void testRead() throws IOException {
InputStream is = new MockInputStream(new byte[] { (byte) 0x80, 0x01, IndexInput is = new MockIndexInput(new byte[] { (byte) 0x80, 0x01,
(byte) 0xFF, 0x7F, (byte) 0xFF, 0x7F,
(byte) 0x80, (byte) 0x80, 0x01, (byte) 0x80, (byte) 0x80, 0x01,
(byte) 0x81, (byte) 0x80, 0x01, (byte) 0x81, (byte) 0x80, 0x01,
0x06, 'L', 'u', 'c', 'e', 'n', 'e'}); 0x06, 'L', 'u', 'c', 'e', 'n', 'e'});
assertEquals(128,is.readVInt()); assertEquals(128,is.readVInt());
assertEquals(16383,is.readVInt()); assertEquals(16383,is.readVInt());
assertEquals(16384,is.readVInt()); assertEquals(16384,is.readVInt());

View File

@ -10,14 +10,14 @@ public class _TestHelper {
/** Returns true if the instance of the provided input stream is actually /** Returns true if the instance of the provided input stream is actually
* an FSInputStream. * an FSInputStream.
*/ */
public static boolean isFSInputStream(InputStream is) { public static boolean isFSInputStream(IndexInput is) {
return is instanceof FSInputStream; return is instanceof FSInputStream;
} }
/** Returns true if the provided input stream is an FSInputStream and /** Returns true if the provided input stream is an FSInputStream and
* is a clone, that is it does not own its underlying file descriptor. * is a clone, that is it does not own its underlying file descriptor.
*/ */
public static boolean isFSInputStreamClone(InputStream is) { public static boolean isFSInputStreamClone(IndexInput is) {
if (isFSInputStream(is)) { if (isFSInputStream(is)) {
return ((FSInputStream) is).isClone; return ((FSInputStream) is).isClone;
} else { } else {
@ -32,7 +32,7 @@ public class _TestHelper {
* FSInputStream that owns this descriptor is closed. However, the * FSInputStream that owns this descriptor is closed. However, the
* descriptor may possibly become invalid in other ways as well. * descriptor may possibly become invalid in other ways as well.
*/ */
public static boolean isFSInputStreamOpen(InputStream is) public static boolean isFSInputStreamOpen(IndexInput is)
throws IOException throws IOException
{ {
if (isFSInputStream(is)) { if (isFSInputStream(is)) {