LUCENE-2852: fix false EOF corner case in RAMInputStream

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056428 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2011-01-07 18:02:35 +00:00
parent 602a4e906a
commit cabea43938
3 changed files with 29 additions and 11 deletions

View File

@ -83,6 +83,7 @@ class RAMInputStream extends IndexInput implements Cloneable {
}
private final void switchCurrentBuffer(boolean enforceEOF) throws IOException {
bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
if (currentBufferIndex >= file.numBuffers()) {
// end of file reached, no more buffers left
if (enforceEOF)
@ -95,7 +96,6 @@ class RAMInputStream extends IndexInput implements Cloneable {
} else {
currentBuffer = file.getBuffer(currentBufferIndex);
bufferPosition = 0;
bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
long buflen = length - bufferStart;
bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE : (int) buflen;
}

View File

@ -27,6 +27,7 @@ import org.apache.lucene.document.*;
import java.util.Random;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.io.IOException;
public class TestThreadSafe extends LuceneTestCase {
@ -34,16 +35,16 @@ public class TestThreadSafe extends LuceneTestCase {
IndexReader ir1;
String failure=null;
class Thr extends Thread {
final int iter;
final Random rand;
final AtomicBoolean failed;
// pass in random in case we want to make things reproducable
public Thr(int iter, Random rand) {
public Thr(int iter, Random rand, AtomicBoolean failed) {
this.iter = iter;
this.rand = rand;
this.failed = failed;
}
@Override
@ -61,8 +62,8 @@ public class TestThreadSafe extends LuceneTestCase {
}
} catch (Throwable th) {
failure=th.toString();
fail(failure);
failed.set(true);
throw new RuntimeException(th);
}
}
@ -124,16 +125,15 @@ public class TestThreadSafe extends LuceneTestCase {
void doTest(int iter, int nThreads) throws Exception {
Thr[] tarr = new Thr[nThreads];
AtomicBoolean failed = new AtomicBoolean();
for (int i=0; i<nThreads; i++) {
tarr[i] = new Thr(iter, new Random(random.nextLong()));
tarr[i] = new Thr(iter, new Random(random.nextLong()), failed);
tarr[i].start();
}
for (int i=0; i<nThreads; i++) {
tarr[i].join();
}
if (failure!=null) {
fail(failure);
}
assertFalse(failed.get());
}
public void testLazyLoadThreadSafety() throws Exception{

View File

@ -180,4 +180,22 @@ public class TestRAMDirectory extends LuceneTestCase {
}
dir.delete();
}
// LUCENE-2852
public void testSeekToEOFThenBack() throws Exception {
RAMDirectory dir = new RAMDirectory();
IndexOutput o = dir.createOutput("out");
byte[] bytes = new byte[3*RAMInputStream.BUFFER_SIZE];
o.writeBytes(bytes, 0, bytes.length);
o.close();
IndexInput i = dir.openInput("out");
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();
}
}