Improve BufferedIndexInput.readBytes() performance: LUCENE-695

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@468172 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2006-10-26 22:25:44 +00:00
parent 1eb10aba44
commit 19bf841c27
2 changed files with 45 additions and 13 deletions

View File

@ -185,6 +185,10 @@ Optimizations
9. LUCENE-365: DisjunctionSumScorer performance increase of ~30%. Speeds up
queries with optional clauses. (Paul Elschot via Yonik Seeley)
10. LUCENE-695: Optimized BufferedIndexInput.readBytes() for medium size buffers,
which will speed up merging and retrieving binary and compressed fields.
(Nadav Har'El via Yonik Seeley)
Test Cases
1. Added TestTermScorer.java (Grant Ingersoll)

View File

@ -34,19 +34,47 @@ public abstract class BufferedIndexInput extends IndexInput {
return buffer[bufferPosition++];
}
public void readBytes(byte[] b, int offset, int len)
throws IOException {
if (len < BUFFER_SIZE) {
for (int i = 0; i < len; i++) // read byte-by-byte
b[i + offset] = (byte)readByte();
} else { // read all-at-once
long start = getFilePointer();
seekInternal(start);
readInternal(b, offset, len);
bufferStart = start + len; // adjust stream variables
bufferPosition = 0;
bufferLength = 0; // trigger refill() on read
public void readBytes(byte[] b, int offset, int len) throws IOException {
if(len <= (bufferLength-bufferPosition)){
// the buffer contains enough data to satistfy this request
if(len>0) // to allow b to be null if len is 0...
System.arraycopy(buffer, bufferPosition, b, offset, len);
bufferPosition+=len;
} else {
// the buffer does not have enough data. First serve all we've got.
int available = bufferLength - bufferPosition;
if(available > 0){
System.arraycopy(buffer, bufferPosition, b, offset, available);
offset += available;
len -= available;
bufferPosition += available;
}
// and now, read the remaining 'len' bytes:
if(len<BUFFER_SIZE){
// If the amount left to read is small enough, do it in the usual
// buffered way: fill the buffer and copy from it:
refill();
if(bufferLength<len){
// Throw an exception when refill() could not read len bytes:
System.arraycopy(buffer, 0, b, offset, bufferLength);
throw new IOException("read past EOF");
} else {
System.arraycopy(buffer, 0, b, offset, len);
bufferPosition=len;
}
} else {
// The amount left to read is larger than the buffer - there's no
// performance reason not to read it all at once. Note that unlike
// the previous code of this function, there is no need to do a seek
// here, because there's no need to reread what we had in the buffer.
long after = bufferStart+bufferPosition+len;
if(after > length())
throw new IOException("read past EOF");
readInternal(b, offset, len);
bufferStart = after;
bufferPosition = 0;
bufferLength = 0; // trigger refill() on read
}
}
}