Index: lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsReader.java (revision 1370738) +++ lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsReader.java (working copy) @@ -139,13 +139,13 @@ static void readBlock(IndexInput in, byte[] encoded, IntBuffer encodedBuffer, int[] buffer) throws IOException { int header = in.readVInt(); - in.readBytes(encoded, 0, ForUtil.getEncodedSize(header)); - ForUtil.decompress(encodedBuffer, buffer, header); + in.readBytes(encoded, 0, ForUtil.directNumBytes(header)); + ForUtil.decodeDirect(encoded, buffer, header); } static void skipBlock(IndexInput in) throws IOException { int header = in.readVInt(); - in.seek(in.getFilePointer() + ForUtil.getEncodedSize(header)); + in.seek(in.getFilePointer() + ForUtil.directNumBytes(header)); } // Must keep final because we do non-standard clone Index: lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsWriter.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsWriter.java (revision 1370738) +++ lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsWriter.java (working copy) @@ -215,9 +215,9 @@ } private void writeBlock(int[] buffer, IndexOutput out) throws IOException { - final int header = ForUtil.compress(buffer, encodedBuffer); + final int header = ForUtil.encodeDirect(buffer, encoded); out.writeVInt(header); - out.writeBytes(encoded, ForUtil.getEncodedSize(header)); + out.writeBytes(encoded, ForUtil.directNumBytes(header)); } @Override Index: lucene/core/src/java/org/apache/lucene/codecs/block/ForUtil.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/block/ForUtil.java (revision 1370738) +++ lucene/core/src/java/org/apache/lucene/codecs/block/ForUtil.java (working copy) @@ -17,6 +17,7 @@ */ import java.nio.IntBuffer; +import java.util.Arrays; /** * Encode all values in normal area with fixed bit width, @@ -78,6 +79,114 @@ decompressCore(intBuffer, data, numBits); } + static final int encodeDirect(int[] data, byte[] encoded) { + final int numBits = getNumBits(data); + if (numBits == 0) { + final int value = data[0]; + encoded[0] = (byte) (value >> 24); + encoded[1] = (byte) (value >> 16); + encoded[2] = (byte) (value >> 8); + encoded[3] = (byte) value; + return numBits; + } + + int dataUpto = 0; + int dataValue = data[0]; + int bitsLeftData = numBits; + + int encodedUpto = 0; + encoded[0] = 0; + int bitsLeftEncoded = 8; + + //System.out.println(" encode"); + //System.out.println(" data[0]=" + dataValue); + while (true) { + //System.out.println(" cycle bitsLeftData=" + bitsLeftData + " bitsLeftEncoded=" + bitsLeftEncoded); + if (bitsLeftData <= bitsLeftEncoded) { + // Remainder of datum fits in current byte: + encoded[encodedUpto] |= dataValue << (8-bitsLeftEncoded); + //System.out.println(" encoded[" + encodedUpto + "]=" + Integer.toBinaryString(encoded[encodedUpto]&0xFF)); + dataUpto++; + if (dataUpto == data.length) { + break; + } + dataValue = data[dataUpto]; + //System.out.println(" next data[" + dataUpto + "]=" + dataValue); + bitsLeftEncoded -= bitsLeftData; + bitsLeftData = numBits; + if (bitsLeftEncoded == 0) { + //System.out.println(" next encoded (on next data)"); + encodedUpto++; + encoded[encodedUpto] = 0; + bitsLeftEncoded = 8; + } + } else { + //System.out.println(" next encoded"); + encoded[encodedUpto] |= (dataValue & MASK[bitsLeftEncoded]) << (8-bitsLeftEncoded); + //System.out.println(" encoded[" + encodedUpto + "]=" + Integer.toBinaryString(encoded[encodedUpto]&0xFF)); + dataValue = dataValue >>> bitsLeftEncoded; + bitsLeftData -= bitsLeftEncoded; + encodedUpto++; + encoded[encodedUpto] = 0; + bitsLeftEncoded = 8; + } + } + + return numBits; + } + + static final int directNumBytes(int numBits) { + return numBits == 0 ? 4 : numBits*blockSize/8; + } + + // nocommit at least specialize 8/16 cases...? + static final void decodeDirect(byte[] encoded, int[] data, int numBits) { + + if (numBits == 0) { + final int value = (encoded[0] & 0xFF) << 24 | + (encoded[1] & 0xFF) << 16 | + (encoded[2] & 0xFF) << 8 | + (encoded[3] & 0xFF); + Arrays.fill(data, value); + return; + } + int dataUpto = 0; + int dataValue = 0; + int bitsLeftData = numBits; + + int encodedUpto = 0; + int bitsLeftEncoded = 8; + + //System.out.println(" decode numBits=" + numBits); + //System.out.println(" encoded[" + encodedUpto + "]=" + Integer.toBinaryString(encoded[encodedUpto]&0xFF)); + + while (true) { + //System.out.println(" cycle bitsLeftData=" + bitsLeftData + " bitsLeftEncoded=" + bitsLeftEncoded + " dataValue=" + dataValue); + if (bitsLeftData <= bitsLeftEncoded) { + dataValue |= ((encoded[encodedUpto] >>> (8-bitsLeftEncoded)) & MASK[bitsLeftData]) << (numBits - bitsLeftData); + //System.out.println(" data[" + dataUpto + "]=" + dataValue); + data[dataUpto++] = dataValue; + if (dataUpto == data.length) { + break; + } + dataValue = 0; + bitsLeftEncoded -= bitsLeftData; + bitsLeftData = numBits; + if (bitsLeftEncoded == 0) { + encodedUpto++; + //System.out.println(" next encoded[" + encodedUpto + "]=" + Integer.toBinaryString(encoded[encodedUpto]&0xFF)); + bitsLeftEncoded = 8; + } + } else { + dataValue |= ((encoded[encodedUpto] >>> (8-bitsLeftEncoded)) & MASK[bitsLeftEncoded]) << (numBits - bitsLeftData); + bitsLeftData -= bitsLeftEncoded; + encodedUpto++; + //System.out.println(" next encoded[" + encodedUpto + "]=" + Integer.toBinaryString(encoded[encodedUpto]&0xFF)); + bitsLeftEncoded = 8; + } + } + } + public static void decompressCore(IntBuffer intBuffer, int[] data, int numBits) { switch(numBits) { case 0: PackedIntsDecompress.decode0(intBuffer, data); break; @@ -170,6 +279,7 @@ * Expert: get compressed block size(in byte) */ static int getEncodedSize(int numBits) { + // Works becauase blockSize is always 0 mod 8: return numBits == 0 ? 4 : numBits*blockSize/8; } }