blob: 8e0da3a440a5667c37c2b88f8586c0525adf3e56 [file] [log] [blame]
Index: lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java (revision 1384783)
+++ lucene/core/src/java/org/apache/lucene/store/NIOFSDirectory.java (working copy)
@@ -20,13 +20,12 @@
import java.io.File;
import java.io.EOFException;
import java.io.IOException;
+import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException; // javadoc @link
import java.nio.channels.FileChannel;
import java.util.concurrent.Future; // javadoc
-import org.apache.lucene.store.SimpleFSDirectory.SimpleFSIndexInput.Descriptor;
-
/**
* An {@link FSDirectory} implementation that uses java.nio's FileChannel's
* positional read, which allows multiple threads to read from the same file
@@ -85,7 +84,7 @@
final IOContext context) throws IOException {
ensureOpen();
final File path = new File(getDirectory(), name);
- final Descriptor descriptor = new Descriptor(path, "r");
+ final RandomAccessFile descriptor = new RandomAccessFile(path, "r");
return new Directory.IndexInputSlicer() {
@Override
@@ -104,7 +103,7 @@
/**
* Reads bytes with {@link FileChannel#read(ByteBuffer, long)}
*/
- protected static class NIOFSIndexInput extends SimpleFSDirectory.SimpleFSIndexInput {
+ protected static class NIOFSIndexInput extends FSIndexInput {
private ByteBuffer byteBuf; // wraps the buffer for NIO
@@ -115,7 +114,7 @@
channel = file.getChannel();
}
- public NIOFSIndexInput(String sliceDescription, File path, Descriptor file, FileChannel fc, long off, long length, int bufferSize, int chunkSize) {
+ public NIOFSIndexInput(String sliceDescription, File path, RandomAccessFile file, FileChannel fc, long off, long length, int bufferSize, int chunkSize) {
super("NIOFSIndexInput(" + sliceDescription + " in path=\"" + path + "\" slice=" + off + ":" + (off+length) + ")", file, off, length, bufferSize, chunkSize);
channel = fc;
isClone = true;
@@ -128,18 +127,6 @@
}
@Override
- public void close() throws IOException {
- if (!isClone && file.isOpen) {
- // Close the channel & file
- try {
- channel.close();
- } finally {
- file.close();
- }
- }
- }
-
- @Override
protected void readInternal(byte[] b, int offset, int len) throws IOException {
final ByteBuffer bb;
@@ -194,6 +181,9 @@
throw new IOException(ioe.getMessage() + ": " + this, ioe);
}
}
+
+ @Override
+ protected void seekInternal(long pos) throws IOException {}
}
}
Index: lucene/core/src/java/org/apache/lucene/store/SimpleFSDirectory.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/store/SimpleFSDirectory.java (revision 1384783)
+++ lucene/core/src/java/org/apache/lucene/store/SimpleFSDirectory.java (working copy)
@@ -22,8 +22,6 @@
import java.io.IOException;
import java.io.RandomAccessFile;
-import org.apache.lucene.store.SimpleFSDirectory.SimpleFSIndexInput.Descriptor;
-
/** A straightforward implementation of {@link FSDirectory}
* using java.io.RandomAccessFile. However, this class has
* poor concurrent performance (multiple threads will
@@ -64,7 +62,7 @@
final IOContext context) throws IOException {
ensureOpen();
final File file = new File(getDirectory(), name);
- final Descriptor descriptor = new Descriptor(file, "r");
+ final RandomAccessFile descriptor = new RandomAccessFile(file, "r");
return new IndexInputSlicer() {
@Override
@@ -84,56 +82,14 @@
* Reads bytes with {@link RandomAccessFile#seek(long)} followed by
* {@link RandomAccessFile#read(byte[], int, int)}.
*/
- protected static class SimpleFSIndexInput extends BufferedIndexInput {
+ protected static class SimpleFSIndexInput extends FSIndexInput {
- /**
- * Extension of RandomAccessFile that tracks if the file is
- * open.
- */
- protected static class Descriptor extends RandomAccessFile {
- // remember if the file is open, so that we don't try to close it
- // more than once
- protected volatile boolean isOpen;
- long position;
- final long length;
-
- public Descriptor(File file, String mode) throws IOException {
- super(file, mode);
- isOpen=true;
- length=length();
- }
-
- @Override
- public void close() throws IOException {
- if (isOpen) {
- isOpen=false;
- super.close();
- }
- }
- }
-
- protected final Descriptor file;
- boolean isClone;
- // LUCENE-1566 - maximum read length on a 32bit JVM to prevent incorrect OOM
- protected final int chunkSize;
- protected final long off;
- protected final long end;
-
public SimpleFSIndexInput(String resourceDesc, File path, IOContext context, int chunkSize) throws IOException {
- super(resourceDesc, context);
- this.file = new Descriptor(path, "r");
- this.chunkSize = chunkSize;
- this.off = 0L;
- this.end = file.length;
+ super(resourceDesc, path, context, chunkSize);
}
- public SimpleFSIndexInput(String resourceDesc, Descriptor file, long off, long length, int bufferSize, int chunkSize) {
- super(resourceDesc, bufferSize);
- this.file = file;
- this.chunkSize = chunkSize;
- this.off = off;
- this.end = off + length;
- this.isClone = true; // well, we are sorta?
+ public SimpleFSIndexInput(String resourceDesc, RandomAccessFile file, long off, long length, int bufferSize, int chunkSize) {
+ super(resourceDesc, file, off, length, bufferSize, chunkSize);
}
/** IndexInput methods */
@@ -142,10 +98,7 @@
throws IOException {
synchronized (file) {
long position = off + getFilePointer();
- if (position != file.position) {
- file.seek(position);
- file.position = position;
- }
+ file.seek(position);
int total = 0;
if (position + len > end) {
@@ -162,7 +115,6 @@
readLength = chunkSize;
}
final int i = file.read(b, offset + total, readLength);
- file.position += i;
total += i;
} while (total < len);
} catch (OutOfMemoryError e) {
@@ -181,32 +133,7 @@
}
@Override
- public void close() throws IOException {
- // only close the file if this is not a clone
- if (!isClone) file.close();
- }
-
- @Override
protected void seekInternal(long position) {
}
-
- @Override
- public long length() {
- return end - off;
- }
-
- @Override
- public SimpleFSIndexInput clone() {
- SimpleFSIndexInput clone = (SimpleFSIndexInput)super.clone();
- clone.isClone = true;
- return clone;
- }
-
- /** Method used for testing. Returns true if the underlying
- * file descriptor is valid.
- */
- boolean isFDValid() throws IOException {
- return file.getFD().valid();
- }
}
}
Index: lucene/core/src/java/org/apache/lucene/store/FSDirectory.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/store/FSDirectory.java (revision 1384783)
+++ lucene/core/src/java/org/apache/lucene/store/FSDirectory.java (working copy)
@@ -437,6 +437,65 @@
return chunkSize;
}
+ /** Base class for reading input from a RandomAccessFile */
+ protected abstract static class FSIndexInput extends BufferedIndexInput {
+ /** the underlying RandomAccessFile */
+ protected final RandomAccessFile file;
+ boolean isClone = false;
+ /** maximum read length on a 32bit JVM to prevent incorrect OOM, see LUCENE-1566 */
+ protected final int chunkSize;
+ /** start offset: non-zero in the slice case */
+ protected final long off;
+ /** end offset (start+length) */
+ protected final long end;
+
+ /** Create a new FSIndexInput, reading the entire file from <code>path</code> */
+ protected FSIndexInput(String resourceDesc, File path, IOContext context, int chunkSize) throws IOException {
+ super(resourceDesc, context);
+ this.file = new RandomAccessFile(path, "r");
+ this.chunkSize = chunkSize;
+ this.off = 0L;
+ this.end = file.length();
+ }
+
+ /** Create a new FSIndexInput, representing a slice of an existing open <code>file</code> */
+ protected FSIndexInput(String resourceDesc, RandomAccessFile file, long off, long length, int bufferSize, int chunkSize) {
+ super(resourceDesc, bufferSize);
+ this.file = file;
+ this.chunkSize = chunkSize;
+ this.off = off;
+ this.end = off + length;
+ this.isClone = true; // well, we are sorta?
+ }
+
+ @Override
+ public void close() throws IOException {
+ // only close the file if this is not a clone
+ if (!isClone) {
+ file.close();
+ }
+ }
+
+ @Override
+ public FSIndexInput clone() {
+ FSIndexInput clone = (FSIndexInput)super.clone();
+ clone.isClone = true;
+ return clone;
+ }
+
+ @Override
+ public final long length() {
+ return end - off;
+ }
+
+ /** Method used for testing. Returns true if the underlying
+ * file descriptor is valid.
+ */
+ boolean isFDValid() throws IOException {
+ return file.getFD().valid();
+ }
+ }
+
/**
* Writes output with {@link RandomAccessFile#write(byte[], int, int)}
*/