+++ /dev/null
-package org.apache.lucene.store;
-
-/**
- * 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.
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-/** A straightforward implementation of {@link FSDirectory}
- * using java.io.RandomAccessFile. However, this class has
- * poor concurrent performance (multiple threads will
- * bottleneck) as it synchronizes when multiple threads
- * read from the same file. It's usually better to use
- * {@link NIOFSDirectory} or {@link MMapDirectory} instead. */
-public class SimpleFSDirectory extends FSDirectory {
-
- /** Create a new SimpleFSDirectory for the named location.
- *
- * @param path the path of the directory
- * @param lockFactory the lock factory to use, or null for the default
- * ({@link NativeFSLockFactory});
- * @throws IOException
- */
- public SimpleFSDirectory(File path, LockFactory lockFactory) throws IOException {
- super(path, lockFactory);
- }
-
- /** Create a new SimpleFSDirectory for the named location and {@link NativeFSLockFactory}.
- *
- * @param path the path of the directory
- * @throws IOException
- */
- public SimpleFSDirectory(File path) throws IOException {
- super(path, null);
- }
-
- /** Creates an IndexInput for the file with the given name. */
- @Override
- public IndexInput openInput(String name, int bufferSize) throws IOException {
- ensureOpen();
- return new SimpleFSIndexInput(new File(directory, name), bufferSize, getReadChunkSize());
- }
-
- protected static class SimpleFSIndexInput extends BufferedIndexInput {
-
- 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;
-
- public SimpleFSIndexInput(File path, int bufferSize, int chunkSize) throws IOException {
- super(bufferSize);
- file = new Descriptor(path, "r");
- this.chunkSize = chunkSize;
- }
-
- /** IndexInput methods */
- @Override
- protected void readInternal(byte[] b, int offset, int len)
- throws IOException {
- synchronized (file) {
- long position = getFilePointer();
- if (position != file.position) {
- file.seek(position);
- file.position = position;
- }
- int total = 0;
-
- try {
- do {
- final int readLength;
- if (total + chunkSize > len) {
- readLength = len - total;
- } else {
- // LUCENE-1566 - work around JVM Bug by breaking very large reads into chunks
- readLength = chunkSize;
- }
- final int i = file.read(b, offset + total, readLength);
- if (i == -1) {
- throw new IOException("read past EOF");
- }
- file.position += i;
- total += i;
- } while (total < len);
- } catch (OutOfMemoryError e) {
- // propagate OOM up and add a hint for 32bit VM Users hitting the bug
- // with a large chunk size in the fast path.
- final OutOfMemoryError outOfMemoryError = new OutOfMemoryError(
- "OutOfMemoryError likely caused by the Sun VM Bug described in "
- + "https://issues.apache.org/jira/browse/LUCENE-1566; try calling FSDirectory.setReadChunkSize "
- + "with a value smaller than the current chunk size (" + chunkSize + ")");
- outOfMemoryError.initCause(e);
- throw outOfMemoryError;
- }
- }
- }
-
- @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 file.length;
- }
-
- @Override
- public Object 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();
- }
-
- @Override
- public void copyBytes(IndexOutput out, long numBytes) throws IOException {
- numBytes -= flushBuffer(out, numBytes);
- // If out is FSIndexOutput, the copy will be optimized
- out.copyBytes(this, numBytes);
- }
- }
-}