You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rj...@apache.org on 2013/10/16 08:53:31 UTC
svn commit: r1532655 - in /lucene/dev/branches/branch_4x: ./ lucene/
lucene/CHANGES.txt lucene/core/
lucene/core/src/java/org/apache/lucene/util/packed/DirectPackedReader.java
Author: rjernst
Date: Wed Oct 16 06:53:31 2013
New Revision: 1532655
URL: http://svn.apache.org/r1532655
Log:
LUCENE-5266: Improved DirectPackedReader performance
Modified:
lucene/dev/branches/branch_4x/ (props changed)
lucene/dev/branches/branch_4x/lucene/ (props changed)
lucene/dev/branches/branch_4x/lucene/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_4x/lucene/core/ (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/util/packed/DirectPackedReader.java
Modified: lucene/dev/branches/branch_4x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/CHANGES.txt?rev=1532655&r1=1532654&r2=1532655&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/lucene/CHANGES.txt Wed Oct 16 06:53:31 2013
@@ -117,6 +117,8 @@ Optimizations
* LUCENE-5236: EliasFanoDocIdSet now has an index and uses broadword bit
selection to speed-up advance(). (Paul Elschot via Adrien Grand)
+* LUCENE-5266: Improved number of read calls and branches in DirectPackedReader. (Ryan Ernst)
+
Documentation
* LUCENE-5211: Better javadocs and error checking of 'format' option in
Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/util/packed/DirectPackedReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/util/packed/DirectPackedReader.java?rev=1532655&r1=1532654&r2=1532655&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/util/packed/DirectPackedReader.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/util/packed/DirectPackedReader.java Wed Oct 16 06:53:31 2013
@@ -25,12 +25,18 @@ import java.io.IOException;
class DirectPackedReader extends PackedInts.ReaderImpl {
private final IndexInput in;
private final long startPointer;
+ private final long valueMask;
public DirectPackedReader(int bitsPerValue, int valueCount, IndexInput in) {
super(valueCount, bitsPerValue);
this.in = in;
startPointer = in.getFilePointer();
+ if (bitsPerValue == 64) {
+ valueMask = -1L;
+ } else {
+ valueMask = (1L << bitsPerValue) - 1;
+ }
}
@Override
@@ -40,29 +46,49 @@ class DirectPackedReader extends PackedI
try {
in.seek(startPointer + elementPos);
- final byte b0 = in.readByte();
final int bitPos = (int) (majorBitPos & 7);
- if (bitPos + bitsPerValue <= 8) {
- // special case: all bits are in the first byte
- return (b0 & ((1L << (8 - bitPos)) - 1)) >>> (8 - bitPos - bitsPerValue);
- }
-
- // take bits from the first byte
- int remainingBits = bitsPerValue - 8 + bitPos;
- long result = (b0 & ((1L << (8 - bitPos)) - 1)) << remainingBits;
-
- // add bits from inner bytes
- while (remainingBits >= 8) {
- remainingBits -= 8;
- result |= (in.readByte() & 0xFFL) << remainingBits;
- }
-
- // take bits from the last byte
- if (remainingBits > 0) {
- result |= (in.readByte() & 0xFFL) >>> (8 - remainingBits);
+ // round up bits to a multiple of 8 to find total bytes needed to read
+ final int roundedBits = ((bitPos + bitsPerValue + 7) & ~7);
+ // the number of extra bits read at the end to shift out
+ int shiftRightBits = roundedBits - bitPos - bitsPerValue;
+
+ long rawValue;
+ switch (roundedBits >>> 3) {
+ case 1:
+ rawValue = in.readByte();
+ break;
+ case 2:
+ rawValue = in.readShort();
+ break;
+ case 3:
+ rawValue = ((long)in.readShort() << 8) | (in.readByte() & 0xFFL);
+ break;
+ case 4:
+ rawValue = in.readInt();
+ break;
+ case 5:
+ rawValue = ((long)in.readInt() << 8) | (in.readByte() & 0xFFL);
+ break;
+ case 6:
+ rawValue = ((long)in.readInt() << 16) | (in.readShort() & 0xFFFFL);
+ break;
+ case 7:
+ rawValue = ((long)in.readInt() << 24) | ((in.readShort() & 0xFFFFL) << 8) | (in.readByte() & 0xFFL);
+ break;
+ case 8:
+ rawValue = in.readLong();
+ break;
+ case 9:
+ // We must be very careful not to shift out relevant bits. So we account for right shift
+ // we would normally do on return here, and reset it.
+ rawValue = (in.readLong() << (8 - shiftRightBits)) | ((in.readByte() & 0xFFL) >>> shiftRightBits);
+ shiftRightBits = 0;
+ break;
+ default:
+ throw new AssertionError("bitsPerValue too large: " + bitsPerValue);
}
+ return (rawValue >>> shiftRightBits) & valueMask;
- return result;
} catch (IOException ioe) {
throw new IllegalStateException("failed", ioe);
}