blob: 2caa60da05e130b3c8ebdf899dccb2337840eb2e [file] [log] [blame]
Index: lucene/misc/src/test/org/apache/lucene/store/TestNativeUnixDirectory.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/store/TestNativeUnixDirectory.java (revision 0)
+++ lucene/misc/src/test/org/apache/lucene/store/TestNativeUnixDirectory.java (working copy)
@@ -0,0 +1,36 @@
+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 org.apache.lucene.util.Constants;
+import org.apache.lucene.util.TestUtil;
+import org.junit.Assume;
+
+public class TestNativeUnixDirectory extends BaseDirectoryTestCase {
+
+ @Override
+ protected Directory getDirectory(File path) throws IOException {
+ // NativeUnixDirectory only works on Unix:
+ Assume.assumeTrue(Constants.WINDOWS == false);
+
+ return new NativeUnixDirectory(FSDirectory.open(path), TestUtil.nextInt(random(), 1, 1000)*512, random().nextInt(10000), true);
+ }
+}
Property changes on: lucene/misc/src/test/org/apache/lucene/store/TestNativeUnixDirectory.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/misc/src/java/org/apache/lucene/store/NativeUnixDirectory.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/store/NativeUnixDirectory.java (revision 1583585)
+++ lucene/misc/src/java/org/apache/lucene/store/NativeUnixDirectory.java (working copy)
@@ -19,15 +19,17 @@
import java.io.EOFException;
import java.io.File;
-import java.io.IOException;
+import java.io.FileDescriptor;
import java.io.FileInputStream;
-import java.io.FileDescriptor;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.util.zip.CRC32;
import org.apache.lucene.store.Directory; // javadoc
import org.apache.lucene.store.IOContext.Context;
+import org.apache.lucene.util.IOUtils;
// TODO
// - newer Linux kernel versions (after 2.6.29) have
@@ -36,6 +38,15 @@
// cache; we should explore using that instead of direct
// IO when context is merge
+// NOTE: to run tests using this Dir:
+// edit the ctor taking File to make the minBytesDirect
+// smaller, because very few (no?) tests will actually do
+// merges > 10 MB so O_DIRECT won't be used
+// cd lucene/misc
+// ant build-native-unix jar
+//
+// ant test -lib /path/to/lucene/build/misc/lucene-misc-5.0-SNAPSHOT.jar -Dtests.directory=NativeUnixDirectory
+
/**
* A {@link Directory} implementation for all Unixes that uses
* DIRECT I/O to bypass OS level IO caching during
@@ -67,7 +78,7 @@
*
* @lucene.experimental
*/
-public class NativeUnixDirectory extends FSDirectory {
+public class NativeUnixDirectory extends FilterDirectory {
// TODO: this is OS dependent, but likely 512 is the LCD
private final static long ALIGN = 512;
@@ -86,46 +97,54 @@
private final int mergeBufferSize;
private final long minBytesDirect;
private final Directory delegate;
+ private final boolean doCloseDelegate;
- /** Create a new NIOFSDirectory for the named location.
+ /** Create a new NativeUnixDirectory for the named location.
*
- * @param path the path of the directory
+ * @param delegate the wrapped directory, used for flushes
+ * or small merges
* @param mergeBufferSize Size of buffer to use for
* merging. See {@link #DEFAULT_MERGE_BUFFER_SIZE}.
* @param minBytesDirect Merges, or files to be opened for
* reading, smaller than this will
* not use direct IO. See {@link
* #DEFAULT_MIN_BYTES_DIRECT}
- * @param delegate fallback Directory for non-merges
* @throws IOException If there is a low-level I/O error
*/
- public NativeUnixDirectory(File path, int mergeBufferSize, long minBytesDirect, Directory delegate) throws IOException {
- super(path, delegate.getLockFactory());
- if ((mergeBufferSize & ALIGN) != 0) {
+ public NativeUnixDirectory(FSDirectory delegate, int mergeBufferSize, long minBytesDirect, boolean doCloseDelegate) throws IOException {
+ super(delegate);
+ if ((mergeBufferSize & (ALIGN-1)) != 0) {
throw new IllegalArgumentException("mergeBufferSize must be 0 mod " + ALIGN + " (got: " + mergeBufferSize + ")");
}
this.mergeBufferSize = mergeBufferSize;
this.minBytesDirect = minBytesDirect;
this.delegate = delegate;
+ this.doCloseDelegate = doCloseDelegate;
}
- /** Create a new NIOFSDirectory for the named location.
+ /** Create a new NativeUnixDirectory for the named location.
*
- * @param path the path of the directory
- * @param delegate fallback Directory for non-merges
+ * @param delegate the wrapped directory, used for flushes
+ * or small merges
* @throws IOException If there is a low-level I/O error
*/
- public NativeUnixDirectory(File path, Directory delegate) throws IOException {
- this(path, DEFAULT_MERGE_BUFFER_SIZE, DEFAULT_MIN_BYTES_DIRECT, delegate);
+ public NativeUnixDirectory(FSDirectory delegate, boolean doCloseDelegate) throws IOException {
+ this(delegate, DEFAULT_MERGE_BUFFER_SIZE, DEFAULT_MIN_BYTES_DIRECT, doCloseDelegate);
}
+ /** Create a new NativeUnixDirectory wrapping {@link
+ * FSDirectory#open}. */
+ public NativeUnixDirectory(File path) throws IOException {
+ this(FSDirectory.open(path), DEFAULT_MERGE_BUFFER_SIZE, DEFAULT_MIN_BYTES_DIRECT, true);
+ }
+
@Override
public IndexInput openInput(String name, IOContext context) throws IOException {
ensureOpen();
- if (context.context != Context.MERGE || context.mergeInfo.estimatedMergeBytes < minBytesDirect || fileLength(name) < minBytesDirect) {
+ if (context.context != Context.MERGE || fileLength(name) < minBytesDirect) {
return delegate.openInput(name, context);
} else {
- return new NativeUnixIndexInput(new File(getDirectory(), name), mergeBufferSize);
+ return new NativeUnixIndexInput(new File(((FSDirectory) in).getDirectory(), name), mergeBufferSize);
}
}
@@ -135,16 +154,21 @@
if (context.context != Context.MERGE || context.mergeInfo.estimatedMergeBytes < minBytesDirect) {
return delegate.createOutput(name, context);
} else {
- ensureCanWrite(name);
- return new NativeUnixIndexOutput(new File(getDirectory(), name), mergeBufferSize);
+ ((FSDirectory) in).ensureCanWrite(name);
+ return new NativeUnixIndexOutput(new File(((FSDirectory) in).getDirectory(), name), mergeBufferSize);
}
}
+ // NOTE: we can't just subclass BufferedIndexOutput
+ // becaues it sometimes flushes partial buffers not at the
+ // end of the file (e.g. in writeBytes):
+
private final static class NativeUnixIndexOutput extends IndexOutput {
private final ByteBuffer buffer;
private final FileOutputStream fos;
private final FileChannel channel;
private final int bufferSize;
+ private final CRC32 crc = new CRC32();
//private final File path;
@@ -155,11 +179,17 @@
public NativeUnixIndexOutput(File path, int bufferSize) throws IOException {
//this.path = path;
+ // TODO: we can reflect into
+ // sun.nio.fs.UnixNativeDispatcher's open method
+ // instead of our own:
final FileDescriptor fd = NativePosixUtil.open_direct(path.toString(), false);
fos = new FileOutputStream(fd);
- //fos = new FileOutputStream(path);
+ //System.out.println("FD=" + fd + " path=" + path);
channel = fos.getChannel();
- buffer = ByteBuffer.allocateDirect(bufferSize);
+ // TODO: we can use Unsafe to get page size alignment,
+ // and then alloc a buffer and do our own custom align
+ // within that?
+ buffer = NativePosixUtil.newAlignedDirectByteBuffer(ALIGN, bufferSize);
this.bufferSize = bufferSize;
isOpen = true;
}
@@ -168,6 +198,7 @@
public void writeByte(byte b) throws IOException {
assert bufferPos == buffer.position(): "bufferPos=" + bufferPos + " vs buffer.position()=" + buffer.position();
buffer.put(b);
+ crc.update(b);
if (++bufferPos == bufferSize) {
dump();
}
@@ -175,6 +206,7 @@
@Override
public void writeBytes(byte[] src, int offset, int len) throws IOException {
+ crc.update(src, offset, len);
int toWrite = len;
while(true) {
final int left = bufferSize - bufferPos;
@@ -243,7 +275,7 @@
@Override
public long getChecksum() throws IOException {
- throw new UnsupportedOperationException("this directory currently does not work at all!");
+ return crc.getValue();
}
@Override
@@ -254,6 +286,9 @@
dump();
} finally {
try {
+ // Sets the fileLength to the true length; this
+ // is necessary because we rounded up to the
+ // next multiple of bufferSize when writing:
//System.out.println("direct close set len=" + fileLength + " vs " + channel.size() + " path=" + path);
channel.truncate(fileLength);
//System.out.println(" now: " + channel.size());
@@ -283,11 +318,17 @@
public NativeUnixIndexInput(File path, int bufferSize) throws IOException {
super("NativeUnixIndexInput(path=\"" + path.getPath() + "\")");
+ // TODO: we can reflect into
+ // sun.nio.fs.UnixNativeDispatcher's open method
+ // instead of our own:
final FileDescriptor fd = NativePosixUtil.open_direct(path.toString(), true);
fis = new FileInputStream(fd);
channel = fis.getChannel();
this.bufferSize = bufferSize;
- buffer = ByteBuffer.allocateDirect(bufferSize);
+ // TODO: we can use Unsafe to get page size alignment,
+ // and then alloc a buffer and do our own custom align
+ // within that?
+ buffer = NativePosixUtil.newAlignedDirectByteBuffer(ALIGN, bufferSize);
isOpen = true;
isClone = false;
filePos = -bufferSize;
@@ -301,7 +342,7 @@
this.fis = null;
channel = other.channel;
this.bufferSize = other.bufferSize;
- buffer = ByteBuffer.allocateDirect(bufferSize);
+ buffer = NativePosixUtil.newAlignedDirectByteBuffer(ALIGN, bufferSize);
filePos = -bufferSize;
bufferPos = bufferSize;
isOpen = true;
@@ -417,4 +458,15 @@
}
}
}
+
+ @Override
+ public void close() throws IOException {
+ try {
+ super.close();
+ } finally {
+ if (doCloseDelegate) {
+ delegate.close();
+ }
+ }
+ }
}
Index: lucene/misc/src/java/org/apache/lucene/store/NativePosixUtil.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/store/NativePosixUtil.java (revision 1583585)
+++ lucene/misc/src/java/org/apache/lucene/store/NativePosixUtil.java (working copy)
@@ -41,6 +41,7 @@
public static native int posix_madvise(ByteBuffer buf, int advise) throws IOException;
public static native int madvise(ByteBuffer buf, int advise) throws IOException;
public static native FileDescriptor open_direct(String filename, boolean read) throws IOException;
+ public static native ByteBuffer newAlignedDirectByteBuffer(long alignment, long size) throws IOException;
public static native long pread(FileDescriptor fd, long pos, ByteBuffer byteBuf) throws IOException;
public static void advise(FileDescriptor fd, long offset, long len, int advise) throws IOException {
Index: lucene/misc/src/java/org/apache/lucene/store/NativePosixUtil.cpp
===================================================================
--- lucene/misc/src/java/org/apache/lucene/store/NativePosixUtil.cpp (revision 1583585)
+++ lucene/misc/src/java/org/apache/lucene/store/NativePosixUtil.cpp (working copy)
@@ -30,6 +30,7 @@
#include <string.h> // strerror
#include <errno.h> // errno
#include <unistd.h> // pread
+#include <stdlib.h> // posix_malign
#include <sys/mman.h> // posix_madvise, madvise
#include <sys/types.h> // constants for open
#include <sys/stat.h> // constants for open
@@ -112,15 +113,11 @@
{
jfieldID field_fd;
jmethodID const_fdesc;
- jclass class_fdesc, class_ioex;
+ jclass class_fdesc;
jobject ret;
int fd;
char *fname;
- class_ioex = env->FindClass("java/io/IOException");
- if (class_ioex == NULL) {
- return NULL;
- }
class_fdesc = env->FindClass("java/io/FileDescriptor");
if (class_fdesc == NULL) {
return NULL;
@@ -136,7 +133,7 @@
} else {
fd = open(fname, O_RDWR | O_CREAT | DIRECT_FLAG, 0666);
#ifdef OSX
- fcntl(fd, F_NOCACHE, 1);
+ fcntl(fd, F_NOCACHE, 1);
#endif
}
@@ -145,8 +142,18 @@
env->ReleaseStringUTFChars(filename, fname);
if (fd < 0) {
- // open returned an error. Throw an IOException with the error string
- env->ThrowNew(class_ioex, strerror(errno));
+ if (errno == ENOENT) {
+ jclass class_fnfeex = env->FindClass("java/io/FileNotFoundException");
+ if (class_fnfeex != NULL) {
+ env->ThrowNew(class_fnfeex, strerror(errno));
+ }
+ } else {
+ // open returned an error. Throw an IOException with the error string
+ jclass class_ioex = env->FindClass("java/io/IOException");
+ if (class_ioex != NULL) {
+ env->ThrowNew(class_ioex, strerror(errno));
+ }
+ }
return NULL;
}
@@ -168,6 +175,20 @@
return ret;
}
+extern "C"
+JNIEXPORT jobject JNICALL Java_org_apache_lucene_store_NativePosixUtil_newAlignedDirectByteBuffer(JNIEnv *env, jclass _ignore, jlong alignment, jlong size) {
+ void *p;
+ int result = posix_memalign(&p, (size_t) alignment, (size_t) size);
+ if (result != 0) {
+ jclass class_ioex = env->FindClass("java/io/IOException");
+ if (class_ioex != NULL) {
+ env->ThrowNew(class_ioex, strerror(result));
+ }
+ return NULL;
+ }
+ return env->NewDirectByteBuffer(p, size);
+}
+
/*
* Class: org_apache_lucene_store_NativePosixUtil
* Method: pread
Index: lucene/misc/build.xml
===================================================================
--- lucene/misc/build.xml (revision 1583585)
+++ lucene/misc/build.xml (working copy)
@@ -41,7 +41,11 @@
<taskdef resource="cpptasks.tasks" classpathref="cpptasks.classpath"/>
</target>
- <target name="build-native-unix" depends="install-cpptasks">
+ <condition property="isUnix">
+ <os family="unix"/>
+ </condition>
+
+ <target name="build-native-unix" depends="install-cpptasks" if="isUnix">
<mkdir dir="${common.build.dir}/native"/>
<cc outtype="shared" name="c++" subsystem="console" outfile="${common.build.dir}/native/NativePosixUtil" >
@@ -58,4 +62,5 @@
</cc>
</target>
+ <target name="init" depends="build-native-unix,module-build.init"/>
</project>
Index: lucene/test-framework/src/java/org/apache/lucene/store/BaseDirectoryTestCase.java
===================================================================
--- lucene/test-framework/src/java/org/apache/lucene/store/BaseDirectoryTestCase.java (revision 0)
+++ lucene/test-framework/src/java/org/apache/lucene/store/BaseDirectoryTestCase.java (working copy)
@@ -0,0 +1,400 @@
+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.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.NoSuchFileException;
+import java.util.Arrays;
+
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexNotFoundException;
+import org.apache.lucene.store.SimpleFSDirectory.SimpleFSIndexInput;
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.TestUtil;
+
+/** Base class for per-Directory tests. */
+
+public abstract class BaseDirectoryTestCase extends LuceneTestCase {
+
+ /** Subclass returns the Directory to be tested; if it's
+ * an FS-based directory it should point to the specified
+ * path, else it can ignore it. */
+ protected abstract Directory getDirectory(File path) throws IOException;
+
+ /** Make sure directory throws AlreadyClosedException if
+ * you try to createOutput after closing. */
+ public void testDetectClose() throws Throwable {
+ Directory dir = getDirectory(TestUtil.getTempDir("testDetectClose"));
+ dir.close();
+ try {
+ dir.createOutput("test", newIOContext(random()));
+ fail("did not hit expected exception");
+ } catch (AlreadyClosedException ace) {
+ // expected
+ }
+ }
+
+ // test is occasionally very slow, i dont know why
+ // try this seed: 7D7E036AD12927F5:93333EF9E6DE44DE
+ @Nightly
+ public void testThreadSafety() throws Exception {
+ final BaseDirectoryWrapper dir = newDirectory(getDirectory(TestUtil.getTempDir("testThreadSafety")));
+ dir.setCheckIndexOnClose(false); // we arent making an index
+ if (dir instanceof MockDirectoryWrapper) {
+ ((MockDirectoryWrapper)dir).setThrottling(MockDirectoryWrapper.Throttling.NEVER); // makes this test really slow
+ }
+
+ if (VERBOSE) {
+ System.out.println(dir);
+ }
+
+ class TheThread extends Thread {
+ private String name;
+
+ public TheThread(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public void run() {
+ for (int i = 0; i < 3000; i++) {
+ String fileName = this.name + i;
+ try {
+ //System.out.println("create:" + fileName);
+ IndexOutput output = dir.createOutput(fileName, newIOContext(random()));
+ output.close();
+ assertTrue(slowFileExists(dir, fileName));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ };
+
+ class TheThread2 extends Thread {
+ private String name;
+
+ public TheThread2(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public void run() {
+ for (int i = 0; i < 10000; i++) {
+ try {
+ String[] files = dir.listAll();
+ for (String file : files) {
+ //System.out.println("file:" + file);
+ try {
+ IndexInput input = dir.openInput(file, newIOContext(random()));
+ input.close();
+ } catch (FileNotFoundException | NoSuchFileException e) {
+ // ignore
+ } catch (IOException e) {
+ if (e.getMessage().contains("still open for writing")) {
+ // ignore
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ if (random().nextBoolean()) {
+ break;
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ };
+
+ TheThread theThread = new TheThread("t1");
+ TheThread2 theThread2 = new TheThread2("t2");
+ theThread.start();
+ theThread2.start();
+
+ theThread.join();
+ theThread2.join();
+
+ dir.close();
+ }
+
+ /** LUCENE-1464: just creating a Directory should not
+ * mkdir the underling directory in the filesystem. */
+ public void testDontCreate() throws Throwable {
+ File path = new File(TEMP_DIR, "doesnotexist");
+ try {
+ assertTrue(!path.exists());
+ Directory dir = getDirectory(path);
+ assertTrue(!path.exists());
+ dir.close();
+ } finally {
+ TestUtil.rmDir(path);
+ }
+ }
+
+ /** LUCENE-1468: once we create an output, we should see
+ * it in the dir listing and be able to open it with
+ * openInput. */
+ public void testDirectoryFilter() throws IOException {
+ String name = "file";
+ Directory dir = getDirectory(TestUtil.getTempDir("testDirectoryFilter"));
+ try {
+ dir.createOutput(name, newIOContext(random())).close();
+ assertTrue(slowFileExists(dir, name));
+ assertTrue(Arrays.asList(dir.listAll()).contains(name));
+ } finally {
+ dir.close();
+ }
+ }
+
+ // LUCENE-2852
+ public void testSeekToEOFThenBack() throws Exception {
+ Directory dir = getDirectory(TestUtil.getTempDir("testSeekToEOFThenBack"));
+
+ IndexOutput o = dir.createOutput("out", newIOContext(random()));
+ byte[] bytes = new byte[3*RAMInputStream.BUFFER_SIZE];
+ o.writeBytes(bytes, 0, bytes.length);
+ o.close();
+
+ IndexInput i = dir.openInput("out", newIOContext(random()));
+ i.seek(2*RAMInputStream.BUFFER_SIZE-1);
+ i.seek(3*RAMInputStream.BUFFER_SIZE);
+ i.seek(RAMInputStream.BUFFER_SIZE);
+ i.readBytes(bytes, 0, 2*RAMInputStream.BUFFER_SIZE);
+ i.close();
+ dir.close();
+ }
+
+ // LUCENE-1196
+ public void testIllegalEOF() throws Exception {
+ Directory dir = getDirectory(TestUtil.getTempDir("testIllegalEOF"));
+ IndexOutput o = dir.createOutput("out", newIOContext(random()));
+ byte[] b = new byte[1024];
+ o.writeBytes(b, 0, 1024);
+ o.close();
+ IndexInput i = dir.openInput("out", newIOContext(random()));
+ i.seek(1024);
+ i.close();
+ dir.close();
+ }
+
+ public void testDeleteFile() throws Exception {
+ Directory dir = getDirectory(TestUtil.getTempDir("testDeleteFile"));
+ dir.createOutput("foo.txt", IOContext.DEFAULT).close();
+ dir.deleteFile("foo.txt");
+ assertEquals(0, dir.listAll().length);
+ dir.close();
+ }
+
+ // LUCENE-3382 -- make sure we get exception if the directory really does not exist.
+ public void testNoDir() throws Throwable {
+ File tempDir = TestUtil.getTempDir("doesnotexist");
+ TestUtil.rmDir(tempDir);
+ Directory dir = getDirectory(tempDir);
+ try {
+ DirectoryReader.open(dir);
+ fail("did not hit expected exception");
+ } catch (NoSuchDirectoryException | IndexNotFoundException nsde) {
+ // expected
+ }
+ dir.close();
+ }
+
+ // LUCENE-3382 test that delegate compound files correctly.
+ public void testCompoundFileAppendTwice() throws IOException {
+ Directory newDir = getDirectory(TestUtil.getTempDir("testCompoundFileAppendTwice"));
+ CompoundFileDirectory csw = new CompoundFileDirectory(newDir, "d.cfs", newIOContext(random()), true);
+ createSequenceFile(newDir, "d1", (byte) 0, 15);
+ IndexOutput out = csw.createOutput("d.xyz", newIOContext(random()));
+ out.writeInt(0);
+ out.close();
+ assertEquals(1, csw.listAll().length);
+ assertEquals("d.xyz", csw.listAll()[0]);
+
+ csw.close();
+
+ CompoundFileDirectory cfr = new CompoundFileDirectory(newDir, "d.cfs", newIOContext(random()), false);
+ assertEquals(1, cfr.listAll().length);
+ assertEquals("d.xyz", cfr.listAll()[0]);
+ cfr.close();
+ newDir.close();
+ }
+
+
+ /** Creates a file of the specified size with sequential data. The first
+ * byte is written as the start byte provided. All subsequent bytes are
+ * computed as start + offset where offset is the number of the byte.
+ */
+ private void createSequenceFile(Directory dir, String name, byte start, int size) throws IOException {
+ IndexOutput os = dir.createOutput(name, newIOContext(random()));
+ for (int i=0; i < size; i++) {
+ os.writeByte(start);
+ start ++;
+ }
+ os.close();
+ }
+
+ public void testCopyBytes() throws Exception {
+ testCopyBytes(getDirectory(TestUtil.getTempDir("testCopyBytes")));
+ }
+
+ private static byte value(int idx) {
+ return (byte) ((idx % 256) * (1 + (idx / 256)));
+ }
+
+ public static void testCopyBytes(Directory dir) throws Exception {
+
+ // make random file
+ IndexOutput out = dir.createOutput("test", newIOContext(random()));
+ byte[] bytes = new byte[TestUtil.nextInt(random(), 1, 77777)];
+ final int size = TestUtil.nextInt(random(), 1, 1777777);
+ int upto = 0;
+ int byteUpto = 0;
+ while (upto < size) {
+ bytes[byteUpto++] = value(upto);
+ upto++;
+ if (byteUpto == bytes.length) {
+ out.writeBytes(bytes, 0, bytes.length);
+ byteUpto = 0;
+ }
+ }
+
+ out.writeBytes(bytes, 0, byteUpto);
+ assertEquals(size, out.getFilePointer());
+ out.close();
+ assertEquals(size, dir.fileLength("test"));
+
+ // copy from test -> test2
+ final IndexInput in = dir.openInput("test", newIOContext(random()));
+
+ out = dir.createOutput("test2", newIOContext(random()));
+
+ upto = 0;
+ while (upto < size) {
+ if (random().nextBoolean()) {
+ out.writeByte(in.readByte());
+ upto++;
+ } else {
+ final int chunk = Math.min(
+ TestUtil.nextInt(random(), 1, bytes.length), size - upto);
+ out.copyBytes(in, chunk);
+ upto += chunk;
+ }
+ }
+ assertEquals(size, upto);
+ out.close();
+ in.close();
+
+ // verify
+ IndexInput in2 = dir.openInput("test2", newIOContext(random()));
+ upto = 0;
+ while (upto < size) {
+ if (random().nextBoolean()) {
+ final byte v = in2.readByte();
+ assertEquals(value(upto), v);
+ upto++;
+ } else {
+ final int limit = Math.min(
+ TestUtil.nextInt(random(), 1, bytes.length), size - upto);
+ in2.readBytes(bytes, 0, limit);
+ for (int byteIdx = 0; byteIdx < limit; byteIdx++) {
+ assertEquals(value(upto), bytes[byteIdx]);
+ upto++;
+ }
+ }
+ }
+ in2.close();
+
+ dir.deleteFile("test");
+ dir.deleteFile("test2");
+
+ dir.close();
+ }
+
+ // LUCENE-3541
+ public void testCopyBytesWithThreads() throws Exception {
+ testCopyBytesWithThreads(getDirectory(TestUtil.getTempDir("testCopyBytesWithThreads")));
+ }
+
+ public static void testCopyBytesWithThreads(Directory d) throws Exception {
+ int datalen = TestUtil.nextInt(random(), 101, 10000);
+ byte data[] = new byte[datalen];
+ random().nextBytes(data);
+
+ IndexOutput output = d.createOutput("data", IOContext.DEFAULT);
+ output.writeBytes(data, 0, datalen);
+ output.close();
+
+ IndexInput input = d.openInput("data", IOContext.DEFAULT);
+ IndexOutput outputHeader = d.createOutput("header", IOContext.DEFAULT);
+ // copy our 100-byte header
+ outputHeader.copyBytes(input, 100);
+ outputHeader.close();
+
+ // now make N copies of the remaining bytes
+ CopyThread copies[] = new CopyThread[10];
+ for (int i = 0; i < copies.length; i++) {
+ copies[i] = new CopyThread(input.clone(), d.createOutput("copy" + i, IOContext.DEFAULT));
+ }
+
+ for (int i = 0; i < copies.length; i++) {
+ copies[i].start();
+ }
+
+ for (int i = 0; i < copies.length; i++) {
+ copies[i].join();
+ }
+
+ for (int i = 0; i < copies.length; i++) {
+ IndexInput copiedData = d.openInput("copy" + i, IOContext.DEFAULT);
+ byte[] dataCopy = new byte[datalen];
+ System.arraycopy(data, 0, dataCopy, 0, 100); // copy the header for easy testing
+ copiedData.readBytes(dataCopy, 100, datalen-100);
+ assertArrayEquals(data, dataCopy);
+ copiedData.close();
+ }
+ input.close();
+ d.close();
+
+ }
+
+ static class CopyThread extends Thread {
+ final IndexInput src;
+ final IndexOutput dst;
+
+ CopyThread(IndexInput src, IndexOutput dst) {
+ this.src = src;
+ this.dst = dst;
+ }
+
+ @Override
+ public void run() {
+ try {
+ dst.copyBytes(src, src.length()-100);
+ dst.close();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+}
+
Property changes on: lucene/test-framework/src/java/org/apache/lucene/store/BaseDirectoryTestCase.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
===================================================================
--- lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java (revision 1583585)
+++ lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java (working copy)
@@ -1170,6 +1170,21 @@
return newFSDirectoryImpl(clazz.asSubclass(FSDirectory.class), dir);
}
+ // See if it has a File ctor even though it's not an
+ // FSDir subclass:
+ Constructor<? extends Directory> fileCtor = null;
+ try {
+ fileCtor = clazz.getConstructor(File.class);
+ } catch (NoSuchMethodException nsme) {
+ // Ignore
+ }
+
+ if (fileCtor != null) {
+ final File dir = TestUtil.getTempDir("index");
+ dir.mkdirs(); // ensure it's created so we 'have' it.
+ return fileCtor.newInstance(dir);
+ }
+
// try empty ctor
return clazz.newInstance();
} catch (Exception e) {
@@ -1340,7 +1355,7 @@
}
if (ex != null) {
if (VERBOSE) {
- System.out.println("NOTE: newSearcher using ExecutorService with " + threads + " threads");
+ System.out.println("NOTE: newSearcher using ExecutorService with " + threads + " threads");
}
r.addReaderClosedListener(new ReaderClosedListener() {
@Override
Index: lucene/module-build.xml
===================================================================
--- lucene/module-build.xml (revision 1583585)
+++ lucene/module-build.xml (working copy)
@@ -30,7 +30,7 @@
<!-- if you extend the classpath refid in one contrib's build.xml (add JARs), use this as basis: -->
<path id="base.classpath">
- <pathelement location="${common.dir}/build/core/classes/java"/>
+ <pathelement location="${common.dir}/build/core/classes/java"/>
</path>
<!-- default classpath refid, can be overridden by contrib's build.xml (use the above base.classpath as basis): -->
Index: lucene/core/src/test/org/apache/lucene/store/TestNIOFSDirectory.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestNIOFSDirectory.java (working copy)
+++ lucene/core/src/test/org/apache/lucene/store/TestNIOFSDirectory.java (working copy)
@@ -27,265 +27,11 @@
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
-public class TestDirectory extends LuceneTestCase {
- public void testDetectClose() throws Throwable {
- Directory[] dirs = new Directory[] {
- new RAMDirectory(),
- new SimpleFSDirectory(TEMP_DIR),
- new NIOFSDirectory(TEMP_DIR)
- };
+public class TestNIOFSDirectory extends BaseDirectoryTestCase {
- for (Directory dir : dirs) {
- dir.close();
- try {
- dir.createOutput("test", newIOContext(random()));
- fail("did not hit expected exception");
- } catch (AlreadyClosedException ace) {
- }
- }
+ @Override
+ protected Directory getDirectory(File path) throws IOException {
+ return new NIOFSDirectory(path);
}
-
- // test is occasionally very slow, i dont know why
- // try this seed: 7D7E036AD12927F5:93333EF9E6DE44DE
- @Nightly
- public void testThreadSafety() throws Exception {
- final BaseDirectoryWrapper dir = newDirectory();
- dir.setCheckIndexOnClose(false); // we arent making an index
- if (dir instanceof MockDirectoryWrapper) {
- ((MockDirectoryWrapper)dir).setThrottling(Throttling.NEVER); // makes this test really slow
- }
-
- if (VERBOSE) {
- System.out.println(dir);
- }
-
- class TheThread extends Thread {
- private String name;
-
- public TheThread(String name) {
- this.name = name;
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 3000; i++) {
- String fileName = this.name + i;
- try {
- //System.out.println("create:" + fileName);
- IndexOutput output = dir.createOutput(fileName, newIOContext(random()));
- output.close();
- assertTrue(slowFileExists(dir, fileName));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
-
- class TheThread2 extends Thread {
- private String name;
-
- public TheThread2(String name) {
- this.name = name;
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- try {
- String[] files = dir.listAll();
- for (String file : files) {
- //System.out.println("file:" + file);
- try {
- IndexInput input = dir.openInput(file, newIOContext(random()));
- input.close();
- } catch (FileNotFoundException | NoSuchFileException e) {
- // ignore
- } catch (IOException e) {
- if (e.getMessage().contains("still open for writing")) {
- // ignore
- } else {
- throw new RuntimeException(e);
- }
- }
- if (random().nextBoolean()) {
- break;
- }
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
-
- TheThread theThread = new TheThread("t1");
- TheThread2 theThread2 = new TheThread2("t2");
- theThread.start();
- theThread2.start();
-
- theThread.join();
- theThread2.join();
-
- dir.close();
- }
-
-
- // Test that different instances of FSDirectory can coexist on the same
- // path, can read, write, and lock files.
- public void testDirectInstantiation() throws Exception {
- final File path = TestUtil.getTempDir("testDirectInstantiation");
-
- final byte[] largeBuffer = new byte[random().nextInt(256*1024)], largeReadBuffer = new byte[largeBuffer.length];
- for (int i = 0; i < largeBuffer.length; i++) {
- largeBuffer[i] = (byte) i; // automatically loops with modulo
- }
-
- final FSDirectory[] dirs = new FSDirectory[] {
- new SimpleFSDirectory(path, null),
- new NIOFSDirectory(path, null),
- new MMapDirectory(path, null)
- };
-
- for (int i=0; i<dirs.length; i++) {
- FSDirectory dir = dirs[i];
- dir.ensureOpen();
- String fname = "foo." + i;
- String lockname = "foo" + i + ".lck";
- IndexOutput out = dir.createOutput(fname, newIOContext(random()));
- out.writeByte((byte)i);
- out.writeBytes(largeBuffer, largeBuffer.length);
- out.close();
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- d2.ensureOpen();
- assertTrue(slowFileExists(d2, fname));
- assertEquals(1 + largeBuffer.length, d2.fileLength(fname));
-
- // don't do read tests if unmapping is not supported!
- if (d2 instanceof MMapDirectory && !((MMapDirectory) d2).getUseUnmap())
- continue;
-
- IndexInput input = d2.openInput(fname, newIOContext(random()));
- assertEquals((byte)i, input.readByte());
- // read array with buffering enabled
- Arrays.fill(largeReadBuffer, (byte)0);
- input.readBytes(largeReadBuffer, 0, largeReadBuffer.length, true);
- assertArrayEquals(largeBuffer, largeReadBuffer);
- // read again without using buffer
- input.seek(1L);
- Arrays.fill(largeReadBuffer, (byte)0);
- input.readBytes(largeReadBuffer, 0, largeReadBuffer.length, false);
- assertArrayEquals(largeBuffer, largeReadBuffer);
- input.close();
- }
-
- // delete with a different dir
- dirs[(i+1)%dirs.length].deleteFile(fname);
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- assertFalse(slowFileExists(d2, fname));
- }
-
- Lock lock = dir.makeLock(lockname);
- assertTrue(lock.obtain());
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- Lock lock2 = d2.makeLock(lockname);
- try {
- assertFalse(lock2.obtain(1));
- } catch (LockObtainFailedException e) {
- // OK
- }
- }
-
- lock.close();
-
- // now lock with different dir
- lock = dirs[(i+1)%dirs.length].makeLock(lockname);
- assertTrue(lock.obtain());
- lock.close();
- }
-
- for (int i=0; i<dirs.length; i++) {
- FSDirectory dir = dirs[i];
- dir.ensureOpen();
- dir.close();
- assertFalse(dir.isOpen);
- }
-
- TestUtil.rmDir(path);
- }
-
- // LUCENE-1464
- public void testDontCreate() throws Throwable {
- File path = new File(TEMP_DIR, "doesnotexist");
- try {
- assertTrue(!path.exists());
- Directory dir = new SimpleFSDirectory(path, null);
- assertTrue(!path.exists());
- dir.close();
- } finally {
- TestUtil.rmDir(path);
- }
- }
-
- // LUCENE-1468
- public void testRAMDirectoryFilter() throws IOException {
- checkDirectoryFilter(new RAMDirectory());
- }
-
- // LUCENE-1468
- public void testFSDirectoryFilter() throws IOException {
- checkDirectoryFilter(newFSDirectory(TestUtil.getTempDir("test")));
- }
-
- // LUCENE-1468
- private void checkDirectoryFilter(Directory dir) throws IOException {
- String name = "file";
- try {
- dir.createOutput(name, newIOContext(random())).close();
- assertTrue(slowFileExists(dir, name));
- assertTrue(Arrays.asList(dir.listAll()).contains(name));
- } finally {
- dir.close();
- }
- }
-
- // LUCENE-1468
- public void testCopySubdir() throws Throwable {
- File path = TestUtil.getTempDir("testsubdir");
- try {
- path.mkdirs();
- new File(path, "subdir").mkdirs();
- Directory fsDir = new SimpleFSDirectory(path, null);
- assertEquals(0, new RAMDirectory(fsDir, newIOContext(random())).listAll().length);
- } finally {
- TestUtil.rmDir(path);
- }
- }
-
- // LUCENE-1468
- public void testNotDirectory() throws Throwable {
- File path = TestUtil.getTempDir("testnotdir");
- Directory fsDir = new SimpleFSDirectory(path, null);
- try {
- IndexOutput out = fsDir.createOutput("afile", newIOContext(random()));
- out.close();
- assertTrue(slowFileExists(fsDir, "afile"));
- try {
- new SimpleFSDirectory(new File(path, "afile"), null);
- fail("did not hit expected exception");
- } catch (NoSuchDirectoryException nsde) {
- // Expected
- }
- } finally {
- fsDir.close();
- TestUtil.rmDir(path);
- }
- }
}
Index: lucene/core/src/test/org/apache/lucene/store/TestMMapDirectory.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestMMapDirectory.java (working copy)
+++ lucene/core/src/test/org/apache/lucene/store/TestMMapDirectory.java (working copy)
@@ -27,265 +27,11 @@
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
-public class TestDirectory extends LuceneTestCase {
- public void testDetectClose() throws Throwable {
- Directory[] dirs = new Directory[] {
- new RAMDirectory(),
- new SimpleFSDirectory(TEMP_DIR),
- new NIOFSDirectory(TEMP_DIR)
- };
+public class TestMMapDirectory extends BaseDirectoryTestCase {
- for (Directory dir : dirs) {
- dir.close();
- try {
- dir.createOutput("test", newIOContext(random()));
- fail("did not hit expected exception");
- } catch (AlreadyClosedException ace) {
- }
- }
+ @Override
+ protected Directory getDirectory(File path) throws IOException {
+ return new MMapDirectory(path);
}
-
- // test is occasionally very slow, i dont know why
- // try this seed: 7D7E036AD12927F5:93333EF9E6DE44DE
- @Nightly
- public void testThreadSafety() throws Exception {
- final BaseDirectoryWrapper dir = newDirectory();
- dir.setCheckIndexOnClose(false); // we arent making an index
- if (dir instanceof MockDirectoryWrapper) {
- ((MockDirectoryWrapper)dir).setThrottling(Throttling.NEVER); // makes this test really slow
- }
-
- if (VERBOSE) {
- System.out.println(dir);
- }
-
- class TheThread extends Thread {
- private String name;
-
- public TheThread(String name) {
- this.name = name;
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 3000; i++) {
- String fileName = this.name + i;
- try {
- //System.out.println("create:" + fileName);
- IndexOutput output = dir.createOutput(fileName, newIOContext(random()));
- output.close();
- assertTrue(slowFileExists(dir, fileName));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
-
- class TheThread2 extends Thread {
- private String name;
-
- public TheThread2(String name) {
- this.name = name;
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- try {
- String[] files = dir.listAll();
- for (String file : files) {
- //System.out.println("file:" + file);
- try {
- IndexInput input = dir.openInput(file, newIOContext(random()));
- input.close();
- } catch (FileNotFoundException | NoSuchFileException e) {
- // ignore
- } catch (IOException e) {
- if (e.getMessage().contains("still open for writing")) {
- // ignore
- } else {
- throw new RuntimeException(e);
- }
- }
- if (random().nextBoolean()) {
- break;
- }
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
-
- TheThread theThread = new TheThread("t1");
- TheThread2 theThread2 = new TheThread2("t2");
- theThread.start();
- theThread2.start();
-
- theThread.join();
- theThread2.join();
-
- dir.close();
- }
-
-
- // Test that different instances of FSDirectory can coexist on the same
- // path, can read, write, and lock files.
- public void testDirectInstantiation() throws Exception {
- final File path = TestUtil.getTempDir("testDirectInstantiation");
-
- final byte[] largeBuffer = new byte[random().nextInt(256*1024)], largeReadBuffer = new byte[largeBuffer.length];
- for (int i = 0; i < largeBuffer.length; i++) {
- largeBuffer[i] = (byte) i; // automatically loops with modulo
- }
-
- final FSDirectory[] dirs = new FSDirectory[] {
- new SimpleFSDirectory(path, null),
- new NIOFSDirectory(path, null),
- new MMapDirectory(path, null)
- };
-
- for (int i=0; i<dirs.length; i++) {
- FSDirectory dir = dirs[i];
- dir.ensureOpen();
- String fname = "foo." + i;
- String lockname = "foo" + i + ".lck";
- IndexOutput out = dir.createOutput(fname, newIOContext(random()));
- out.writeByte((byte)i);
- out.writeBytes(largeBuffer, largeBuffer.length);
- out.close();
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- d2.ensureOpen();
- assertTrue(slowFileExists(d2, fname));
- assertEquals(1 + largeBuffer.length, d2.fileLength(fname));
-
- // don't do read tests if unmapping is not supported!
- if (d2 instanceof MMapDirectory && !((MMapDirectory) d2).getUseUnmap())
- continue;
-
- IndexInput input = d2.openInput(fname, newIOContext(random()));
- assertEquals((byte)i, input.readByte());
- // read array with buffering enabled
- Arrays.fill(largeReadBuffer, (byte)0);
- input.readBytes(largeReadBuffer, 0, largeReadBuffer.length, true);
- assertArrayEquals(largeBuffer, largeReadBuffer);
- // read again without using buffer
- input.seek(1L);
- Arrays.fill(largeReadBuffer, (byte)0);
- input.readBytes(largeReadBuffer, 0, largeReadBuffer.length, false);
- assertArrayEquals(largeBuffer, largeReadBuffer);
- input.close();
- }
-
- // delete with a different dir
- dirs[(i+1)%dirs.length].deleteFile(fname);
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- assertFalse(slowFileExists(d2, fname));
- }
-
- Lock lock = dir.makeLock(lockname);
- assertTrue(lock.obtain());
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- Lock lock2 = d2.makeLock(lockname);
- try {
- assertFalse(lock2.obtain(1));
- } catch (LockObtainFailedException e) {
- // OK
- }
- }
-
- lock.close();
-
- // now lock with different dir
- lock = dirs[(i+1)%dirs.length].makeLock(lockname);
- assertTrue(lock.obtain());
- lock.close();
- }
-
- for (int i=0; i<dirs.length; i++) {
- FSDirectory dir = dirs[i];
- dir.ensureOpen();
- dir.close();
- assertFalse(dir.isOpen);
- }
-
- TestUtil.rmDir(path);
- }
-
- // LUCENE-1464
- public void testDontCreate() throws Throwable {
- File path = new File(TEMP_DIR, "doesnotexist");
- try {
- assertTrue(!path.exists());
- Directory dir = new SimpleFSDirectory(path, null);
- assertTrue(!path.exists());
- dir.close();
- } finally {
- TestUtil.rmDir(path);
- }
- }
-
- // LUCENE-1468
- public void testRAMDirectoryFilter() throws IOException {
- checkDirectoryFilter(new RAMDirectory());
- }
-
- // LUCENE-1468
- public void testFSDirectoryFilter() throws IOException {
- checkDirectoryFilter(newFSDirectory(TestUtil.getTempDir("test")));
- }
-
- // LUCENE-1468
- private void checkDirectoryFilter(Directory dir) throws IOException {
- String name = "file";
- try {
- dir.createOutput(name, newIOContext(random())).close();
- assertTrue(slowFileExists(dir, name));
- assertTrue(Arrays.asList(dir.listAll()).contains(name));
- } finally {
- dir.close();
- }
- }
-
- // LUCENE-1468
- public void testCopySubdir() throws Throwable {
- File path = TestUtil.getTempDir("testsubdir");
- try {
- path.mkdirs();
- new File(path, "subdir").mkdirs();
- Directory fsDir = new SimpleFSDirectory(path, null);
- assertEquals(0, new RAMDirectory(fsDir, newIOContext(random())).listAll().length);
- } finally {
- TestUtil.rmDir(path);
- }
- }
-
- // LUCENE-1468
- public void testNotDirectory() throws Throwable {
- File path = TestUtil.getTempDir("testnotdir");
- Directory fsDir = new SimpleFSDirectory(path, null);
- try {
- IndexOutput out = fsDir.createOutput("afile", newIOContext(random()));
- out.close();
- assertTrue(slowFileExists(fsDir, "afile"));
- try {
- new SimpleFSDirectory(new File(path, "afile"), null);
- fail("did not hit expected exception");
- } catch (NoSuchDirectoryException nsde) {
- // Expected
- }
- } finally {
- fsDir.close();
- TestUtil.rmDir(path);
- }
- }
}
Index: lucene/core/src/test/org/apache/lucene/store/TestRateLimitedDirectoryWrapper.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestRateLimitedDirectoryWrapper.java (revision 0)
+++ lucene/core/src/test/org/apache/lucene/store/TestRateLimitedDirectoryWrapper.java (working copy)
@@ -0,0 +1,31 @@
+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;
+
+public class TestRateLimitedDirectoryWrapper extends BaseDirectoryTestCase {
+
+ @Override
+ protected Directory getDirectory(File path) {
+ RateLimitedDirectoryWrapper dir = new RateLimitedDirectoryWrapper(newFSDirectory(path));
+ RateLimiter limiter = new RateLimiter.SimpleRateLimiter(.1 + 3*random().nextDouble());
+ dir.setRateLimiter(limiter, IOContext.Context.MERGE);
+ return dir;
+ }
+}
Property changes on: lucene/core/src/test/org/apache/lucene/store/TestRateLimitedDirectoryWrapper.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/core/src/test/org/apache/lucene/store/TestDirectory.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestDirectory.java (working copy)
+++ lucene/core/src/test/org/apache/lucene/store/TestDirectory.java (working copy)
@@ -27,265 +27,15 @@
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
-public class TestDirectory extends LuceneTestCase {
- public void testDetectClose() throws Throwable {
- Directory[] dirs = new Directory[] {
- new RAMDirectory(),
- new SimpleFSDirectory(TEMP_DIR),
- new NIOFSDirectory(TEMP_DIR)
- };
+public class TestDirectory extends BaseDirectoryTestCase {
- for (Directory dir : dirs) {
- dir.close();
- try {
- dir.createOutput("test", newIOContext(random()));
- fail("did not hit expected exception");
- } catch (AlreadyClosedException ace) {
- }
+ @Override
+ protected Directory getDirectory(File path) throws IOException {
+ if (random().nextBoolean()) {
+ return newDirectory();
+ } else {
+ return newFSDirectory(path);
}
}
-
- // test is occasionally very slow, i dont know why
- // try this seed: 7D7E036AD12927F5:93333EF9E6DE44DE
- @Nightly
- public void testThreadSafety() throws Exception {
- final BaseDirectoryWrapper dir = newDirectory();
- dir.setCheckIndexOnClose(false); // we arent making an index
- if (dir instanceof MockDirectoryWrapper) {
- ((MockDirectoryWrapper)dir).setThrottling(Throttling.NEVER); // makes this test really slow
- }
-
- if (VERBOSE) {
- System.out.println(dir);
- }
-
- class TheThread extends Thread {
- private String name;
-
- public TheThread(String name) {
- this.name = name;
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 3000; i++) {
- String fileName = this.name + i;
- try {
- //System.out.println("create:" + fileName);
- IndexOutput output = dir.createOutput(fileName, newIOContext(random()));
- output.close();
- assertTrue(slowFileExists(dir, fileName));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
-
- class TheThread2 extends Thread {
- private String name;
-
- public TheThread2(String name) {
- this.name = name;
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- try {
- String[] files = dir.listAll();
- for (String file : files) {
- //System.out.println("file:" + file);
- try {
- IndexInput input = dir.openInput(file, newIOContext(random()));
- input.close();
- } catch (FileNotFoundException | NoSuchFileException e) {
- // ignore
- } catch (IOException e) {
- if (e.getMessage().contains("still open for writing")) {
- // ignore
- } else {
- throw new RuntimeException(e);
- }
- }
- if (random().nextBoolean()) {
- break;
- }
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
-
- TheThread theThread = new TheThread("t1");
- TheThread2 theThread2 = new TheThread2("t2");
- theThread.start();
- theThread2.start();
-
- theThread.join();
- theThread2.join();
-
- dir.close();
- }
-
-
- // Test that different instances of FSDirectory can coexist on the same
- // path, can read, write, and lock files.
- public void testDirectInstantiation() throws Exception {
- final File path = TestUtil.getTempDir("testDirectInstantiation");
-
- final byte[] largeBuffer = new byte[random().nextInt(256*1024)], largeReadBuffer = new byte[largeBuffer.length];
- for (int i = 0; i < largeBuffer.length; i++) {
- largeBuffer[i] = (byte) i; // automatically loops with modulo
- }
-
- final FSDirectory[] dirs = new FSDirectory[] {
- new SimpleFSDirectory(path, null),
- new NIOFSDirectory(path, null),
- new MMapDirectory(path, null)
- };
-
- for (int i=0; i<dirs.length; i++) {
- FSDirectory dir = dirs[i];
- dir.ensureOpen();
- String fname = "foo." + i;
- String lockname = "foo" + i + ".lck";
- IndexOutput out = dir.createOutput(fname, newIOContext(random()));
- out.writeByte((byte)i);
- out.writeBytes(largeBuffer, largeBuffer.length);
- out.close();
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- d2.ensureOpen();
- assertTrue(slowFileExists(d2, fname));
- assertEquals(1 + largeBuffer.length, d2.fileLength(fname));
-
- // don't do read tests if unmapping is not supported!
- if (d2 instanceof MMapDirectory && !((MMapDirectory) d2).getUseUnmap())
- continue;
-
- IndexInput input = d2.openInput(fname, newIOContext(random()));
- assertEquals((byte)i, input.readByte());
- // read array with buffering enabled
- Arrays.fill(largeReadBuffer, (byte)0);
- input.readBytes(largeReadBuffer, 0, largeReadBuffer.length, true);
- assertArrayEquals(largeBuffer, largeReadBuffer);
- // read again without using buffer
- input.seek(1L);
- Arrays.fill(largeReadBuffer, (byte)0);
- input.readBytes(largeReadBuffer, 0, largeReadBuffer.length, false);
- assertArrayEquals(largeBuffer, largeReadBuffer);
- input.close();
- }
-
- // delete with a different dir
- dirs[(i+1)%dirs.length].deleteFile(fname);
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- assertFalse(slowFileExists(d2, fname));
- }
-
- Lock lock = dir.makeLock(lockname);
- assertTrue(lock.obtain());
-
- for (int j=0; j<dirs.length; j++) {
- FSDirectory d2 = dirs[j];
- Lock lock2 = d2.makeLock(lockname);
- try {
- assertFalse(lock2.obtain(1));
- } catch (LockObtainFailedException e) {
- // OK
- }
- }
-
- lock.close();
-
- // now lock with different dir
- lock = dirs[(i+1)%dirs.length].makeLock(lockname);
- assertTrue(lock.obtain());
- lock.close();
- }
-
- for (int i=0; i<dirs.length; i++) {
- FSDirectory dir = dirs[i];
- dir.ensureOpen();
- dir.close();
- assertFalse(dir.isOpen);
- }
-
- TestUtil.rmDir(path);
- }
-
- // LUCENE-1464
- public void testDontCreate() throws Throwable {
- File path = new File(TEMP_DIR, "doesnotexist");
- try {
- assertTrue(!path.exists());
- Directory dir = new SimpleFSDirectory(path, null);
- assertTrue(!path.exists());
- dir.close();
- } finally {
- TestUtil.rmDir(path);
- }
- }
-
- // LUCENE-1468
- public void testRAMDirectoryFilter() throws IOException {
- checkDirectoryFilter(new RAMDirectory());
- }
-
- // LUCENE-1468
- public void testFSDirectoryFilter() throws IOException {
- checkDirectoryFilter(newFSDirectory(TestUtil.getTempDir("test")));
- }
-
- // LUCENE-1468
- private void checkDirectoryFilter(Directory dir) throws IOException {
- String name = "file";
- try {
- dir.createOutput(name, newIOContext(random())).close();
- assertTrue(slowFileExists(dir, name));
- assertTrue(Arrays.asList(dir.listAll()).contains(name));
- } finally {
- dir.close();
- }
- }
-
- // LUCENE-1468
- public void testCopySubdir() throws Throwable {
- File path = TestUtil.getTempDir("testsubdir");
- try {
- path.mkdirs();
- new File(path, "subdir").mkdirs();
- Directory fsDir = new SimpleFSDirectory(path, null);
- assertEquals(0, new RAMDirectory(fsDir, newIOContext(random())).listAll().length);
- } finally {
- TestUtil.rmDir(path);
- }
- }
-
- // LUCENE-1468
- public void testNotDirectory() throws Throwable {
- File path = TestUtil.getTempDir("testnotdir");
- Directory fsDir = new SimpleFSDirectory(path, null);
- try {
- IndexOutput out = fsDir.createOutput("afile", newIOContext(random()));
- out.close();
- assertTrue(slowFileExists(fsDir, "afile"));
- try {
- new SimpleFSDirectory(new File(path, "afile"), null);
- fail("did not hit expected exception");
- } catch (NoSuchDirectoryException nsde) {
- // Expected
- }
- } finally {
- fsDir.close();
- TestUtil.rmDir(path);
- }
- }
}
Index: lucene/core/src/test/org/apache/lucene/store/TestRAMDirectory.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestRAMDirectory.java (revision 1583585)
+++ lucene/core/src/test/org/apache/lucene/store/TestRAMDirectory.java (working copy)
@@ -20,39 +20,40 @@
import java.io.File;
import java.io.IOException;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
-import org.apache.lucene.util.TestUtil;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.StoredDocument;
-import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.util.English;
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.TestUtil;
+import org.apache.lucene.util.TestUtil;
/**
* JUnit testcase to test RAMDirectory. RAMDirectory itself is used in many testcases,
* but not one of them uses an different constructor other than the default constructor.
*/
-public class TestRAMDirectory extends LuceneTestCase {
+public class TestRAMDirectory extends BaseDirectoryTestCase {
- private File indexDir = null;
+ @Override
+ protected Directory getDirectory(File path) {
+ return new RAMDirectory();
+ }
// add enough document so that the index will be larger than RAMDirectory.READ_BUFFER_SIZE
private final int docsToAdd = 500;
-
- // setup the index
- @Override
- public void setUp() throws Exception {
- super.setUp();
- indexDir = TestUtil.getTempDir("RAMDirIndex");
+
+ private File buildIndex() throws IOException {
+ File path = TestUtil.getTempDir("buildIndex");
- Directory dir = newFSDirectory(indexDir);
+ Directory dir = newFSDirectory(path);
IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(
TEST_VERSION_CURRENT, new MockAnalyzer(random())).setOpenMode(OpenMode.CREATE));
// add some documents
@@ -65,9 +66,27 @@
assertEquals(docsToAdd, writer.maxDoc());
writer.close();
dir.close();
+
+ return path;
}
+ // LUCENE-1468
+ public void testCopySubdir() throws Throwable {
+ File path = TestUtil.getTempDir("testsubdir");
+ Directory fsDir = null;
+ try {
+ path.mkdirs();
+ new File(path, "subdir").mkdirs();
+ fsDir = newFSDirectory(path);
+ assertEquals(0, new RAMDirectory(fsDir, newIOContext(random())).listAll().length);
+ } finally {
+ TestUtil.rmDir(path);
+ IOUtils.close(fsDir);
+ }
+ }
+
public void testRAMDirectory () throws IOException {
+ File indexDir = buildIndex();
Directory dir = newFSDirectory(indexDir);
MockDirectoryWrapper ramDir = new MockDirectoryWrapper(random(), new RAMDirectory(dir, newIOContext(random())));
@@ -99,6 +118,8 @@
private final int docsPerThread = 40;
public void testRAMDirectorySize() throws IOException, InterruptedException {
+
+ File indexDir = buildIndex();
Directory dir = newFSDirectory(indexDir);
final MockDirectoryWrapper ramDir = new MockDirectoryWrapper(random(), new RAMDirectory(dir, newIOContext(random())));
@@ -138,52 +159,4 @@
writer.close();
}
-
- @Override
- public void tearDown() throws Exception {
- // cleanup
- if (indexDir != null && indexDir.exists()) {
- rmDir (indexDir);
- }
- super.tearDown();
- }
-
- // LUCENE-1196
- public void testIllegalEOF() throws Exception {
- RAMDirectory dir = new RAMDirectory();
- IndexOutput o = dir.createOutput("out", newIOContext(random()));
- byte[] b = new byte[1024];
- o.writeBytes(b, 0, 1024);
- o.close();
- IndexInput i = dir.openInput("out", newIOContext(random()));
- i.seek(1024);
- i.close();
- dir.close();
- }
-
- private void rmDir(File dir) {
- File[] files = dir.listFiles();
- for (int i = 0; i < files.length; i++) {
- files[i].delete();
- }
- dir.delete();
- }
-
- // LUCENE-2852
- public void testSeekToEOFThenBack() throws Exception {
- RAMDirectory dir = new RAMDirectory();
-
- IndexOutput o = dir.createOutput("out", newIOContext(random()));
- byte[] bytes = new byte[3*RAMInputStream.BUFFER_SIZE];
- o.writeBytes(bytes, 0, bytes.length);
- o.close();
-
- IndexInput i = dir.openInput("out", newIOContext(random()));
- i.seek(2*RAMInputStream.BUFFER_SIZE-1);
- i.seek(3*RAMInputStream.BUFFER_SIZE);
- i.seek(RAMInputStream.BUFFER_SIZE);
- i.readBytes(bytes, 0, 2*RAMInputStream.BUFFER_SIZE);
- i.close();
- dir.close();
- }
}
Index: lucene/core/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java (revision 1583585)
+++ lucene/core/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java (working copy)
@@ -39,8 +39,15 @@
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
-public class TestNRTCachingDirectory extends LuceneTestCase {
+public class TestNRTCachingDirectory extends BaseDirectoryTestCase {
+ @Override
+ protected Directory getDirectory(File path) {
+ return new NRTCachingDirectory(newFSDirectory(path),
+ .1 + 2.0*random().nextDouble(),
+ .1 + 5.0*random().nextDouble());
+ }
+
public void testNRTAndCommit() throws Exception {
Directory dir = newDirectory();
NRTCachingDirectory cachedDir = new NRTCachingDirectory(dir, 2.0, 25.0);
@@ -112,72 +119,4 @@
IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, analyzer);
IndexWriter writer = new IndexWriter(cachedFSDir, conf);
}
-
- public void testDeleteFile() throws Exception {
- Directory dir = new NRTCachingDirectory(newDirectory(), 2.0, 25.0);
- dir.createOutput("foo.txt", IOContext.DEFAULT).close();
- dir.deleteFile("foo.txt");
- assertEquals(0, dir.listAll().length);
- dir.close();
- }
-
- // LUCENE-3382 -- make sure we get exception if the directory really does not exist.
- public void testNoDir() throws Throwable {
- File tempDir = TestUtil.getTempDir("doesnotexist");
- TestUtil.rmDir(tempDir);
- Directory dir = new NRTCachingDirectory(newFSDirectory(tempDir), 2.0, 25.0);
- try {
- DirectoryReader.open(dir);
- fail("did not hit expected exception");
- } catch (NoSuchDirectoryException nsde) {
- // expected
- }
- dir.close();
- }
-
- // LUCENE-3382 test that we can add a file, and then when we call list() we get it back
- public void testDirectoryFilter() throws IOException {
- Directory dir = new NRTCachingDirectory(newFSDirectory(TestUtil.getTempDir("foo")), 2.0, 25.0);
- String name = "file";
- try {
- dir.createOutput(name, newIOContext(random())).close();
- assertTrue(slowFileExists(dir, name));
- assertTrue(Arrays.asList(dir.listAll()).contains(name));
- } finally {
- dir.close();
- }
- }
-
- // LUCENE-3382 test that delegate compound files correctly.
- public void testCompoundFileAppendTwice() throws IOException {
- Directory newDir = new NRTCachingDirectory(newDirectory(), 2.0, 25.0);
- CompoundFileDirectory csw = new CompoundFileDirectory(newDir, "d.cfs", newIOContext(random()), true);
- createSequenceFile(newDir, "d1", (byte) 0, 15);
- IndexOutput out = csw.createOutput("d.xyz", newIOContext(random()));
- out.writeInt(0);
- out.close();
- assertEquals(1, csw.listAll().length);
- assertEquals("d.xyz", csw.listAll()[0]);
-
- csw.close();
-
- CompoundFileDirectory cfr = new CompoundFileDirectory(newDir, "d.cfs", newIOContext(random()), false);
- assertEquals(1, cfr.listAll().length);
- assertEquals("d.xyz", cfr.listAll()[0]);
- cfr.close();
- newDir.close();
- }
-
- /** Creates a file of the specified size with sequential data. The first
- * byte is written as the start byte provided. All subsequent bytes are
- * computed as start + offset where offset is the number of the byte.
- */
- private void createSequenceFile(Directory dir, String name, byte start, int size) throws IOException {
- IndexOutput os = dir.createOutput(name, newIOContext(random()));
- for (int i=0; i < size; i++) {
- os.writeByte(start);
- start ++;
- }
- os.close();
- }
}
Index: lucene/core/src/test/org/apache/lucene/store/TestMultiMMap.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestMultiMMap.java (revision 1583585)
+++ lucene/core/src/test/org/apache/lucene/store/TestMultiMMap.java (working copy)
@@ -18,6 +18,7 @@
*/
import java.io.File;
+import java.io.IOException;
import java.util.Random;
import org.apache.lucene.analysis.MockAnalyzer;
@@ -37,8 +38,13 @@
* values, it's necessary to access a file >
* Integer.MAX_VALUE in size using multiple byte buffers.
*/
-public class TestMultiMMap extends LuceneTestCase {
+public class TestMultiMMap extends BaseDirectoryTestCase {
File workDir;
+
+ @Override
+ protected Directory getDirectory(File path) throws IOException {
+ return new MMapDirectory(path, null, 1<<TestUtil.nextInt(random(), 10, 28));
+ }
@Override
public void setUp() throws Exception {
Index: lucene/core/src/test/org/apache/lucene/store/TestSimpleFSDirectory.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestSimpleFSDirectory.java (working copy)
+++ lucene/core/src/test/org/apache/lucene/store/TestSimpleFSDirectory.java (working copy)
@@ -27,110 +27,13 @@
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
-public class TestDirectory extends LuceneTestCase {
- public void testDetectClose() throws Throwable {
- Directory[] dirs = new Directory[] {
- new RAMDirectory(),
- new SimpleFSDirectory(TEMP_DIR),
- new NIOFSDirectory(TEMP_DIR)
- };
+public class TestSimpleFSDirectory extends BaseDirectoryTestCase {
- for (Directory dir : dirs) {
- dir.close();
- try {
- dir.createOutput("test", newIOContext(random()));
- fail("did not hit expected exception");
- } catch (AlreadyClosedException ace) {
- }
- }
+ @Override
+ protected Directory getDirectory(File path) throws IOException {
+ return new SimpleFSDirectory(path);
}
-
- // test is occasionally very slow, i dont know why
- // try this seed: 7D7E036AD12927F5:93333EF9E6DE44DE
- @Nightly
- public void testThreadSafety() throws Exception {
- final BaseDirectoryWrapper dir = newDirectory();
- dir.setCheckIndexOnClose(false); // we arent making an index
- if (dir instanceof MockDirectoryWrapper) {
- ((MockDirectoryWrapper)dir).setThrottling(Throttling.NEVER); // makes this test really slow
- }
-
- if (VERBOSE) {
- System.out.println(dir);
- }
- class TheThread extends Thread {
- private String name;
-
- public TheThread(String name) {
- this.name = name;
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 3000; i++) {
- String fileName = this.name + i;
- try {
- //System.out.println("create:" + fileName);
- IndexOutput output = dir.createOutput(fileName, newIOContext(random()));
- output.close();
- assertTrue(slowFileExists(dir, fileName));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
-
- class TheThread2 extends Thread {
- private String name;
-
- public TheThread2(String name) {
- this.name = name;
- }
-
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- try {
- String[] files = dir.listAll();
- for (String file : files) {
- //System.out.println("file:" + file);
- try {
- IndexInput input = dir.openInput(file, newIOContext(random()));
- input.close();
- } catch (FileNotFoundException | NoSuchFileException e) {
- // ignore
- } catch (IOException e) {
- if (e.getMessage().contains("still open for writing")) {
- // ignore
- } else {
- throw new RuntimeException(e);
- }
- }
- if (random().nextBoolean()) {
- break;
- }
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
-
- TheThread theThread = new TheThread("t1");
- TheThread2 theThread2 = new TheThread2("t2");
- theThread.start();
- theThread2.start();
-
- theThread.join();
- theThread2.join();
-
- dir.close();
- }
-
-
// Test that different instances of FSDirectory can coexist on the same
// path, can read, write, and lock files.
public void testDirectInstantiation() throws Exception {
@@ -220,55 +123,7 @@
TestUtil.rmDir(path);
}
- // LUCENE-1464
- public void testDontCreate() throws Throwable {
- File path = new File(TEMP_DIR, "doesnotexist");
- try {
- assertTrue(!path.exists());
- Directory dir = new SimpleFSDirectory(path, null);
- assertTrue(!path.exists());
- dir.close();
- } finally {
- TestUtil.rmDir(path);
- }
- }
-
// LUCENE-1468
- public void testRAMDirectoryFilter() throws IOException {
- checkDirectoryFilter(new RAMDirectory());
- }
-
- // LUCENE-1468
- public void testFSDirectoryFilter() throws IOException {
- checkDirectoryFilter(newFSDirectory(TestUtil.getTempDir("test")));
- }
-
- // LUCENE-1468
- private void checkDirectoryFilter(Directory dir) throws IOException {
- String name = "file";
- try {
- dir.createOutput(name, newIOContext(random())).close();
- assertTrue(slowFileExists(dir, name));
- assertTrue(Arrays.asList(dir.listAll()).contains(name));
- } finally {
- dir.close();
- }
- }
-
- // LUCENE-1468
- public void testCopySubdir() throws Throwable {
- File path = TestUtil.getTempDir("testsubdir");
- try {
- path.mkdirs();
- new File(path, "subdir").mkdirs();
- Directory fsDir = new SimpleFSDirectory(path, null);
- assertEquals(0, new RAMDirectory(fsDir, newIOContext(random())).listAll().length);
- } finally {
- TestUtil.rmDir(path);
- }
- }
-
- // LUCENE-1468
public void testNotDirectory() throws Throwable {
File path = TestUtil.getTempDir("testnotdir");
Directory fsDir = new SimpleFSDirectory(path, null);
Index: lucene/core/src/test/org/apache/lucene/store/TestCopyBytes.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestCopyBytes.java (revision 1583585)
+++ lucene/core/src/test/org/apache/lucene/store/TestCopyBytes.java (working copy)
@@ -1,173 +0,0 @@
-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.IOException;
-
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
-
-import org.junit.Test;
-
-public class TestCopyBytes extends LuceneTestCase {
-
- private byte value(int idx) {
- return (byte) ((idx % 256) * (1 + (idx / 256)));
- }
-
- @Test
- public void testCopyBytes() throws Exception {
- int num = atLeast(10);
- for (int iter = 0; iter < num; iter++) {
- Directory dir = newDirectory();
- if (VERBOSE) {
- System.out.println("TEST: iter=" + iter + " dir=" + dir);
- }
-
- // make random file
- IndexOutput out = dir.createOutput("test", newIOContext(random()));
- byte[] bytes = new byte[TestUtil.nextInt(random(), 1, 77777)];
- final int size = TestUtil.nextInt(random(), 1, 1777777);
- int upto = 0;
- int byteUpto = 0;
- while (upto < size) {
- bytes[byteUpto++] = value(upto);
- upto++;
- if (byteUpto == bytes.length) {
- out.writeBytes(bytes, 0, bytes.length);
- byteUpto = 0;
- }
- }
-
- out.writeBytes(bytes, 0, byteUpto);
- assertEquals(size, out.getFilePointer());
- out.close();
- assertEquals(size, dir.fileLength("test"));
-
- // copy from test -> test2
- final IndexInput in = dir.openInput("test", newIOContext(random()));
-
- out = dir.createOutput("test2", newIOContext(random()));
-
- upto = 0;
- while (upto < size) {
- if (random().nextBoolean()) {
- out.writeByte(in.readByte());
- upto++;
- } else {
- final int chunk = Math.min(
- TestUtil.nextInt(random(), 1, bytes.length), size - upto);
- out.copyBytes(in, chunk);
- upto += chunk;
- }
- }
- assertEquals(size, upto);
- out.close();
- in.close();
-
- // verify
- IndexInput in2 = dir.openInput("test2", newIOContext(random()));
- upto = 0;
- while (upto < size) {
- if (random().nextBoolean()) {
- final byte v = in2.readByte();
- assertEquals(value(upto), v);
- upto++;
- } else {
- final int limit = Math.min(
- TestUtil.nextInt(random(), 1, bytes.length), size - upto);
- in2.readBytes(bytes, 0, limit);
- for (int byteIdx = 0; byteIdx < limit; byteIdx++) {
- assertEquals(value(upto), bytes[byteIdx]);
- upto++;
- }
- }
- }
- in2.close();
-
- dir.deleteFile("test");
- dir.deleteFile("test2");
-
- dir.close();
- }
- }
-
- // LUCENE-3541
- public void testCopyBytesWithThreads() throws Exception {
- int datalen = TestUtil.nextInt(random(), 101, 10000);
- byte data[] = new byte[datalen];
- random().nextBytes(data);
-
- Directory d = newDirectory();
- IndexOutput output = d.createOutput("data", IOContext.DEFAULT);
- output.writeBytes(data, 0, datalen);
- output.close();
-
- IndexInput input = d.openInput("data", IOContext.DEFAULT);
- IndexOutput outputHeader = d.createOutput("header", IOContext.DEFAULT);
- // copy our 100-byte header
- outputHeader.copyBytes(input, 100);
- outputHeader.close();
-
- // now make N copies of the remaining bytes
- CopyThread copies[] = new CopyThread[10];
- for (int i = 0; i < copies.length; i++) {
- copies[i] = new CopyThread(input.clone(), d.createOutput("copy" + i, IOContext.DEFAULT));
- }
-
- for (int i = 0; i < copies.length; i++) {
- copies[i].start();
- }
-
- for (int i = 0; i < copies.length; i++) {
- copies[i].join();
- }
-
- for (int i = 0; i < copies.length; i++) {
- IndexInput copiedData = d.openInput("copy" + i, IOContext.DEFAULT);
- byte[] dataCopy = new byte[datalen];
- System.arraycopy(data, 0, dataCopy, 0, 100); // copy the header for easy testing
- copiedData.readBytes(dataCopy, 100, datalen-100);
- assertArrayEquals(data, dataCopy);
- copiedData.close();
- }
- input.close();
- d.close();
-
- }
-
- static class CopyThread extends Thread {
- final IndexInput src;
- final IndexOutput dst;
-
- CopyThread(IndexInput src, IndexOutput dst) {
- this.src = src;
- this.dst = dst;
- }
-
- @Override
- public void run() {
- try {
- dst.copyBytes(src, src.length()-100);
- dst.close();
- } catch (IOException ex) {
- throw new RuntimeException(ex);
- }
- }
- }
-}
Index: lucene/core/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java (revision 1583585)
+++ lucene/core/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java (working copy)
@@ -35,7 +35,8 @@
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
-public class TestFileSwitchDirectory extends LuceneTestCase {
+public class TestFileSwitchDirectory extends BaseDirectoryTestCase {
+
/**
* Test if writing doc stores to disk and everything else to ram works.
*/
@@ -115,51 +116,28 @@
}
dir.close();
}
-
- // LUCENE-3380 test that we can add a file, and then when we call list() we get it back
- public void testDirectoryFilter() throws IOException {
- Directory dir = newFSSwitchDirectory(Collections.<String>emptySet());
- String name = "file";
- try {
- dir.createOutput(name, newIOContext(random())).close();
- assertTrue(slowFileExists(dir, name));
- assertTrue(Arrays.asList(dir.listAll()).contains(name));
- } finally {
- dir.close();
+
+ @Override
+ protected Directory getDirectory(File path) throws IOException {
+ Set<String> extensions = new HashSet<String>();
+ if (random().nextBoolean()) {
+ extensions.add("cfs");
}
+ if (random().nextBoolean()) {
+ extensions.add("prx");
+ }
+ if (random().nextBoolean()) {
+ extensions.add("frq");
+ }
+ if (random().nextBoolean()) {
+ extensions.add("tip");
+ }
+ if (random().nextBoolean()) {
+ extensions.add("tim");
+ }
+ if (random().nextBoolean()) {
+ extensions.add("del");
+ }
+ return newFSSwitchDirectory(extensions);
}
-
- // LUCENE-3380 test that delegate compound files correctly.
- public void testCompoundFileAppendTwice() throws IOException {
- Directory newDir = newFSSwitchDirectory(Collections.singleton("cfs"));
- CompoundFileDirectory csw = new CompoundFileDirectory(newDir, "d.cfs", newIOContext(random()), true);
- createSequenceFile(newDir, "d1", (byte) 0, 15);
- IndexOutput out = csw.createOutput("d.xyz", newIOContext(random()));
- out.writeInt(0);
- out.close();
- assertEquals(1, csw.listAll().length);
- assertEquals("d.xyz", csw.listAll()[0]);
-
- csw.close();
-
- CompoundFileDirectory cfr = new CompoundFileDirectory(newDir, "d.cfs", newIOContext(random()), false);
- assertEquals(1, cfr.listAll().length);
- assertEquals("d.xyz", cfr.listAll()[0]);
- cfr.close();
- newDir.close();
- }
-
- /** Creates a file of the specified size with sequential data. The first
- * byte is written as the start byte provided. All subsequent bytes are
- * computed as start + offset where offset is the number of the byte.
- */
- private void createSequenceFile(Directory dir, String name, byte start, int size) throws IOException {
- IndexOutput os = dir.createOutput(name, newIOContext(random()));
- for (int i=0; i < size; i++) {
- os.writeByte(start);
- start ++;
- }
- os.close();
- }
-
}
Index: lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java (revision 1583585)
+++ lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java (working copy)
@@ -276,4 +276,9 @@
return buffers;
}
+
+ @Override
+ public String toString() {
+ return super.toString() + " chunkSize=" + getMaxChunkSize();
+ }
}
Index: lucene/core/src/java/org/apache/lucene/store/IndexOutput.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/store/IndexOutput.java (revision 1583585)
+++ lucene/core/src/java/org/apache/lucene/store/IndexOutput.java (working copy)
@@ -31,6 +31,7 @@
*/
public abstract class IndexOutput extends DataOutput implements Closeable {
+ // TODO: can we remove this?
/** Forces any buffered output to be written. */
public abstract void flush() throws IOException;
@@ -46,9 +47,12 @@
/** Returns the current checksum of bytes written so far */
public abstract long getChecksum() throws IOException;
+ // TODO: can we remove this? It's always the same as
+ // .getFilePointer?
/** The number of bytes in the file. */
public abstract long length() throws IOException;
+ // TODO: remove this
/** Set the file length. By default, this method does
* nothing (it's optional for a Directory to implement
* it). But, certain Directory implementations (for
Index: lucene/common-build.xml
===================================================================
--- lucene/common-build.xml (revision 1583585)
+++ lucene/common-build.xml (working copy)
@@ -915,6 +915,10 @@
<enable package="org.apache.solr"/>
</assertions>
+ <!-- TODO: generalize this for non-unix -->
+ <!-- Add any native extensions to LD_LIBRARY_PATH: -->
+ <env key="LD_LIBRARY_PATH" value="/l/fixnativeunix/lucene/build/native/"></env>
+
<!-- JVM arguments and system properties. -->
<jvmarg line="${args}"/>
<jvmarg line="${tests.heapdump.args}"/>