mirror of https://github.com/apache/lucene.git
LUCENE-1262: fix issue that causes BufferedIndexInput to return incorrect bytes after exception was hit during refill
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@647639 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
360051ec49
commit
a6ff3c93df
|
@ -90,6 +90,11 @@ Bug fixes
|
||||||
6. LUCENE-1228: IndexWriter.commit() was not updating the index version and as
|
6. LUCENE-1228: IndexWriter.commit() was not updating the index version and as
|
||||||
result IndexReader.reopen() failed to sense index changes. (Doron Cohen)
|
result IndexReader.reopen() failed to sense index changes. (Doron Cohen)
|
||||||
|
|
||||||
|
7. LUCENE-1262: Fixed bug in BufferedIndexReader.refill whereby on
|
||||||
|
hitting an exception in readInternal, the buffer is incorrectly
|
||||||
|
filled with stale bytes such that subsequent calls to readByte()
|
||||||
|
return incorrect results. (Trejkaz via Mike McCandless)
|
||||||
|
|
||||||
New features
|
New features
|
||||||
|
|
||||||
1. LUCENE-1137: Added Token.set/getFlags() accessors for passing more information about a Token through the analysis
|
1. LUCENE-1137: Added Token.set/getFlags() accessors for passing more information about a Token through the analysis
|
||||||
|
|
|
@ -141,16 +141,16 @@ public abstract class BufferedIndexInput extends IndexInput {
|
||||||
long end = start + bufferSize;
|
long end = start + bufferSize;
|
||||||
if (end > length()) // don't read past EOF
|
if (end > length()) // don't read past EOF
|
||||||
end = length();
|
end = length();
|
||||||
bufferLength = (int)(end - start);
|
int newLength = (int)(end - start);
|
||||||
if (bufferLength <= 0)
|
if (newLength <= 0)
|
||||||
throw new IOException("read past EOF");
|
throw new IOException("read past EOF");
|
||||||
|
|
||||||
if (buffer == null) {
|
if (buffer == null) {
|
||||||
buffer = new byte[bufferSize]; // allocate buffer lazily
|
buffer = new byte[bufferSize]; // allocate buffer lazily
|
||||||
seekInternal(bufferStart);
|
seekInternal(bufferStart);
|
||||||
}
|
}
|
||||||
readInternal(buffer, 0, bufferLength);
|
readInternal(buffer, 0, newLength);
|
||||||
|
bufferLength = newLength;
|
||||||
bufferStart = start;
|
bufferStart = start;
|
||||||
bufferPosition = 0;
|
bufferPosition = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,10 @@ import org.apache.lucene.util.LuceneTestCase;
|
||||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||||
import org.apache.lucene.document.*;
|
import org.apache.lucene.document.*;
|
||||||
import org.apache.lucene.store.FSDirectory;
|
import org.apache.lucene.store.FSDirectory;
|
||||||
|
import org.apache.lucene.store.IndexInput;
|
||||||
|
import org.apache.lucene.store.IndexOutput;
|
||||||
|
import org.apache.lucene.store.Directory;
|
||||||
|
import org.apache.lucene.store.BufferedIndexInput;
|
||||||
import org.apache.lucene.store.RAMDirectory;
|
import org.apache.lucene.store.RAMDirectory;
|
||||||
import org.apache.lucene.store.AlreadyClosedException;
|
import org.apache.lucene.store.AlreadyClosedException;
|
||||||
import org.apache.lucene.util._TestUtil;
|
import org.apache.lucene.util._TestUtil;
|
||||||
|
@ -298,4 +302,114 @@ public class TestFieldsReader extends LuceneTestCase {
|
||||||
assertEquals((byte) size , sizebytes[3]);
|
assertEquals((byte) size , sizebytes[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class FaultyFSDirectory extends Directory {
|
||||||
|
|
||||||
|
FSDirectory fsDir;
|
||||||
|
public FaultyFSDirectory(File dir) throws IOException {
|
||||||
|
fsDir = FSDirectory.getDirectory(dir);
|
||||||
|
lockFactory = fsDir.getLockFactory();
|
||||||
|
}
|
||||||
|
public IndexInput openInput(String name) throws IOException {
|
||||||
|
return new FaultyIndexInput(fsDir.openInput(name));
|
||||||
|
}
|
||||||
|
public String[] list() throws IOException {
|
||||||
|
return fsDir.list();
|
||||||
|
}
|
||||||
|
public boolean fileExists(String name) throws IOException {
|
||||||
|
return fsDir.fileExists(name);
|
||||||
|
}
|
||||||
|
public long fileModified(String name) throws IOException {
|
||||||
|
return fsDir.fileModified(name);
|
||||||
|
}
|
||||||
|
public void touchFile(String name) throws IOException {
|
||||||
|
fsDir.touchFile(name);
|
||||||
|
}
|
||||||
|
public void deleteFile(String name) throws IOException {
|
||||||
|
fsDir.deleteFile(name);
|
||||||
|
}
|
||||||
|
public void renameFile(String name, String newName) throws IOException {
|
||||||
|
fsDir.renameFile(name, newName);
|
||||||
|
}
|
||||||
|
public long fileLength(String name) throws IOException {
|
||||||
|
return fsDir.fileLength(name);
|
||||||
|
}
|
||||||
|
public IndexOutput createOutput(String name) throws IOException {
|
||||||
|
return fsDir.createOutput(name);
|
||||||
|
}
|
||||||
|
public void close() throws IOException {
|
||||||
|
fsDir.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FaultyIndexInput extends BufferedIndexInput {
|
||||||
|
IndexInput delegate;
|
||||||
|
static boolean doFail;
|
||||||
|
int count;
|
||||||
|
private FaultyIndexInput(IndexInput delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
private void simOutage() throws IOException {
|
||||||
|
if (doFail && count++ % 2 == 1) {
|
||||||
|
throw new IOException("Simulated network outage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void readInternal(byte[] b, int offset, int length) throws IOException {
|
||||||
|
simOutage();
|
||||||
|
delegate.readBytes(b, offset, length);
|
||||||
|
}
|
||||||
|
public void seekInternal(long pos) throws IOException {
|
||||||
|
//simOutage();
|
||||||
|
delegate.seek(pos);
|
||||||
|
}
|
||||||
|
public long length() {
|
||||||
|
return delegate.length();
|
||||||
|
}
|
||||||
|
public void close() throws IOException {
|
||||||
|
delegate.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LUCENE-1262
|
||||||
|
public void testExceptions() throws Throwable {
|
||||||
|
String tempDir = System.getProperty("java.io.tmpdir");
|
||||||
|
if (tempDir == null)
|
||||||
|
throw new IOException("java.io.tmpdir undefined, cannot run test");
|
||||||
|
File indexDir = new File(tempDir, "testfieldswriterexceptions");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Directory dir = new FaultyFSDirectory(indexDir);
|
||||||
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
||||||
|
for(int i=0;i<2;i++)
|
||||||
|
writer.addDocument(testDoc);
|
||||||
|
writer.optimize();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
IndexReader reader = IndexReader.open(dir);
|
||||||
|
|
||||||
|
FaultyIndexInput.doFail = true;
|
||||||
|
|
||||||
|
boolean exc = false;
|
||||||
|
|
||||||
|
for(int i=0;i<2;i++) {
|
||||||
|
try {
|
||||||
|
reader.document(i);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// expected
|
||||||
|
exc = true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
reader.document(i);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// expected
|
||||||
|
exc = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(exc);
|
||||||
|
reader.close();
|
||||||
|
dir.close();
|
||||||
|
} finally {
|
||||||
|
_TestUtil.rmDir(indexDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue