Index: lucene/core/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat
===================================================================
--- lucene/core/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat (revision 1575909)
+++ lucene/core/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat (working copy)
@@ -15,3 +15,4 @@
org.apache.lucene.codecs.lucene40.Lucene40PostingsFormat
org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat
+org.apache.lucene.codecs.nativemmap.NativeMMapPostingsFormat
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked2.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked2.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked2.java (working copy)
@@ -39,6 +39,17 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block = unsafe.getLong(address);
+ address += 8;
+ for (int shift = 62; shift >= 0; shift -= 2) {
+ values[valuesOffset++] = (int) ((block >>> shift) & 3);
+ }
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int j = 0; j < iterations; ++j) {
final byte block = blocks[blocksOffset++];
Index: lucene/core/src/java/org/apache/lucene/util/packed/gen_BulkOperation.py
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/gen_BulkOperation.py (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/gen_BulkOperation.py (working copy)
@@ -145,6 +145,11 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void decode(long[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
throw new UnsupportedOperationException();
}
@@ -205,6 +210,48 @@
f.write(" }\n")
f.write(" }\n\n")
+ if bits == 32:
+ # Unsafe version:
+ f.write(" @Override\n")
+ f.write(" public void decode(long address, int blocksOffset, %s[] values, int valuesOffset, int iterations) {\n" %typ)
+ if bits < bpv:
+ f.write(" throw new UnsupportedOperationException();\n")
+ else:
+ f.write(" for (int i = 0; i < iterations; ++i) {\n")
+ mask = (1 << bpv) - 1
+
+ if is_power_of_two(bpv):
+ f.write(" final long block = unsafe.getLong(address);\n")
+ f.write(" address += 8;\n")
+ f.write(" for (int shift = %d; shift >= 0; shift -= %d) {\n" %(64 - bpv, bpv))
+ f.write(" values[valuesOffset++] = %s(block >>> shift) & %d%s;\n" %(cast_start, mask, cast_end))
+ f.write(" }\n")
+ else:
+ for i in xrange(0, values):
+ block_offset = i * bpv / 64
+ bit_offset = (i * bpv) % 64
+ if bit_offset == 0:
+ # start of block
+ f.write(" final long block%d = unsafe.getLong(address);\n" %block_offset);
+ f.write(" address += 8;\n")
+ f.write(" values[valuesOffset++] = %sblock%d >>> %d%s;\n" %(cast_start, block_offset, 64 - bpv, cast_end))
+ elif bit_offset + bpv == 64:
+ # end of block
+ f.write(" values[valuesOffset++] = %sblock%d & %dL%s;\n" %(cast_start, block_offset, mask, cast_end))
+ elif bit_offset + bpv < 64:
+ # middle of block
+ f.write(" values[valuesOffset++] = %s(block%d >>> %d) & %dL%s;\n" %(cast_start, block_offset, 64 - bit_offset - bpv, mask, cast_end))
+ else:
+ # value spans across 2 blocks
+ mask1 = (1 << (64 - bit_offset)) -1
+ shift1 = bit_offset + bpv - 64
+ shift2 = 64 - shift1
+ f.write(" final long block%d = unsafe.getLong(address);\n" % (block_offset+1))
+ f.write(" address += 8;\n")
+ f.write(" values[valuesOffset++] = %s((block%d & %dL) << %d) | (block%d >>> %d)%s;\n" %(cast_start, block_offset, mask1, shift1, block_offset + 1, shift2, cast_end))
+ f.write(" }\n")
+ f.write(" }\n\n")
+
byte_blocks, byte_values = block_value_count(bpv, 8)
f.write(" @Override\n")
@@ -278,7 +325,23 @@
* Efficient sequential read/write of packed integers.
*/\n''')
+ f.write('import java.lang.reflect.*;')
+ f.write('import sun.misc.Unsafe;\n')
+
f.write('abstract class BulkOperation implements PackedInts.Decoder, PackedInts.Encoder {\n')
+ f.write('''
+ protected static final Unsafe unsafe;
+
+ static {
+ try {
+ Field f = Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe) f.get(null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ ''')
f.write(' private static final BulkOperation[] packedBulkOps = new BulkOperation[] {\n')
for bpv in xrange(1, 65):
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked21.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked21.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked21.java (working copy)
@@ -120,6 +120,118 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 43);
+ values[valuesOffset++] = (int) ((block0 >>> 22) & 2097151L);
+ values[valuesOffset++] = (int) ((block0 >>> 1) & 2097151L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 1L) << 20) | (block1 >>> 44));
+ values[valuesOffset++] = (int) ((block1 >>> 23) & 2097151L);
+ values[valuesOffset++] = (int) ((block1 >>> 2) & 2097151L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 3L) << 19) | (block2 >>> 45));
+ values[valuesOffset++] = (int) ((block2 >>> 24) & 2097151L);
+ values[valuesOffset++] = (int) ((block2 >>> 3) & 2097151L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 7L) << 18) | (block3 >>> 46));
+ values[valuesOffset++] = (int) ((block3 >>> 25) & 2097151L);
+ values[valuesOffset++] = (int) ((block3 >>> 4) & 2097151L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 15L) << 17) | (block4 >>> 47));
+ values[valuesOffset++] = (int) ((block4 >>> 26) & 2097151L);
+ values[valuesOffset++] = (int) ((block4 >>> 5) & 2097151L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 31L) << 16) | (block5 >>> 48));
+ values[valuesOffset++] = (int) ((block5 >>> 27) & 2097151L);
+ values[valuesOffset++] = (int) ((block5 >>> 6) & 2097151L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 63L) << 15) | (block6 >>> 49));
+ values[valuesOffset++] = (int) ((block6 >>> 28) & 2097151L);
+ values[valuesOffset++] = (int) ((block6 >>> 7) & 2097151L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 127L) << 14) | (block7 >>> 50));
+ values[valuesOffset++] = (int) ((block7 >>> 29) & 2097151L);
+ values[valuesOffset++] = (int) ((block7 >>> 8) & 2097151L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 255L) << 13) | (block8 >>> 51));
+ values[valuesOffset++] = (int) ((block8 >>> 30) & 2097151L);
+ values[valuesOffset++] = (int) ((block8 >>> 9) & 2097151L);
+ final long block9 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block8 & 511L) << 12) | (block9 >>> 52));
+ values[valuesOffset++] = (int) ((block9 >>> 31) & 2097151L);
+ values[valuesOffset++] = (int) ((block9 >>> 10) & 2097151L);
+ final long block10 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block9 & 1023L) << 11) | (block10 >>> 53));
+ values[valuesOffset++] = (int) ((block10 >>> 32) & 2097151L);
+ values[valuesOffset++] = (int) ((block10 >>> 11) & 2097151L);
+ final long block11 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block10 & 2047L) << 10) | (block11 >>> 54));
+ values[valuesOffset++] = (int) ((block11 >>> 33) & 2097151L);
+ values[valuesOffset++] = (int) ((block11 >>> 12) & 2097151L);
+ final long block12 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block11 & 4095L) << 9) | (block12 >>> 55));
+ values[valuesOffset++] = (int) ((block12 >>> 34) & 2097151L);
+ values[valuesOffset++] = (int) ((block12 >>> 13) & 2097151L);
+ final long block13 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block12 & 8191L) << 8) | (block13 >>> 56));
+ values[valuesOffset++] = (int) ((block13 >>> 35) & 2097151L);
+ values[valuesOffset++] = (int) ((block13 >>> 14) & 2097151L);
+ final long block14 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block13 & 16383L) << 7) | (block14 >>> 57));
+ values[valuesOffset++] = (int) ((block14 >>> 36) & 2097151L);
+ values[valuesOffset++] = (int) ((block14 >>> 15) & 2097151L);
+ final long block15 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block14 & 32767L) << 6) | (block15 >>> 58));
+ values[valuesOffset++] = (int) ((block15 >>> 37) & 2097151L);
+ values[valuesOffset++] = (int) ((block15 >>> 16) & 2097151L);
+ final long block16 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block15 & 65535L) << 5) | (block16 >>> 59));
+ values[valuesOffset++] = (int) ((block16 >>> 38) & 2097151L);
+ values[valuesOffset++] = (int) ((block16 >>> 17) & 2097151L);
+ final long block17 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block16 & 131071L) << 4) | (block17 >>> 60));
+ values[valuesOffset++] = (int) ((block17 >>> 39) & 2097151L);
+ values[valuesOffset++] = (int) ((block17 >>> 18) & 2097151L);
+ final long block18 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block17 & 262143L) << 3) | (block18 >>> 61));
+ values[valuesOffset++] = (int) ((block18 >>> 40) & 2097151L);
+ values[valuesOffset++] = (int) ((block18 >>> 19) & 2097151L);
+ final long block19 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block18 & 524287L) << 2) | (block19 >>> 62));
+ values[valuesOffset++] = (int) ((block19 >>> 41) & 2097151L);
+ values[valuesOffset++] = (int) ((block19 >>> 20) & 2097151L);
+ final long block20 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block19 & 1048575L) << 1) | (block20 >>> 63));
+ values[valuesOffset++] = (int) ((block20 >>> 42) & 2097151L);
+ values[valuesOffset++] = (int) ((block20 >>> 21) & 2097151L);
+ values[valuesOffset++] = (int) (block20 & 2097151L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked17.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked17.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked17.java (working copy)
@@ -116,6 +116,110 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 47);
+ values[valuesOffset++] = (int) ((block0 >>> 30) & 131071L);
+ values[valuesOffset++] = (int) ((block0 >>> 13) & 131071L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 8191L) << 4) | (block1 >>> 60));
+ values[valuesOffset++] = (int) ((block1 >>> 43) & 131071L);
+ values[valuesOffset++] = (int) ((block1 >>> 26) & 131071L);
+ values[valuesOffset++] = (int) ((block1 >>> 9) & 131071L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 511L) << 8) | (block2 >>> 56));
+ values[valuesOffset++] = (int) ((block2 >>> 39) & 131071L);
+ values[valuesOffset++] = (int) ((block2 >>> 22) & 131071L);
+ values[valuesOffset++] = (int) ((block2 >>> 5) & 131071L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 31L) << 12) | (block3 >>> 52));
+ values[valuesOffset++] = (int) ((block3 >>> 35) & 131071L);
+ values[valuesOffset++] = (int) ((block3 >>> 18) & 131071L);
+ values[valuesOffset++] = (int) ((block3 >>> 1) & 131071L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 1L) << 16) | (block4 >>> 48));
+ values[valuesOffset++] = (int) ((block4 >>> 31) & 131071L);
+ values[valuesOffset++] = (int) ((block4 >>> 14) & 131071L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 16383L) << 3) | (block5 >>> 61));
+ values[valuesOffset++] = (int) ((block5 >>> 44) & 131071L);
+ values[valuesOffset++] = (int) ((block5 >>> 27) & 131071L);
+ values[valuesOffset++] = (int) ((block5 >>> 10) & 131071L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 1023L) << 7) | (block6 >>> 57));
+ values[valuesOffset++] = (int) ((block6 >>> 40) & 131071L);
+ values[valuesOffset++] = (int) ((block6 >>> 23) & 131071L);
+ values[valuesOffset++] = (int) ((block6 >>> 6) & 131071L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 63L) << 11) | (block7 >>> 53));
+ values[valuesOffset++] = (int) ((block7 >>> 36) & 131071L);
+ values[valuesOffset++] = (int) ((block7 >>> 19) & 131071L);
+ values[valuesOffset++] = (int) ((block7 >>> 2) & 131071L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 3L) << 15) | (block8 >>> 49));
+ values[valuesOffset++] = (int) ((block8 >>> 32) & 131071L);
+ values[valuesOffset++] = (int) ((block8 >>> 15) & 131071L);
+ final long block9 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block8 & 32767L) << 2) | (block9 >>> 62));
+ values[valuesOffset++] = (int) ((block9 >>> 45) & 131071L);
+ values[valuesOffset++] = (int) ((block9 >>> 28) & 131071L);
+ values[valuesOffset++] = (int) ((block9 >>> 11) & 131071L);
+ final long block10 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block9 & 2047L) << 6) | (block10 >>> 58));
+ values[valuesOffset++] = (int) ((block10 >>> 41) & 131071L);
+ values[valuesOffset++] = (int) ((block10 >>> 24) & 131071L);
+ values[valuesOffset++] = (int) ((block10 >>> 7) & 131071L);
+ final long block11 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block10 & 127L) << 10) | (block11 >>> 54));
+ values[valuesOffset++] = (int) ((block11 >>> 37) & 131071L);
+ values[valuesOffset++] = (int) ((block11 >>> 20) & 131071L);
+ values[valuesOffset++] = (int) ((block11 >>> 3) & 131071L);
+ final long block12 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block11 & 7L) << 14) | (block12 >>> 50));
+ values[valuesOffset++] = (int) ((block12 >>> 33) & 131071L);
+ values[valuesOffset++] = (int) ((block12 >>> 16) & 131071L);
+ final long block13 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block12 & 65535L) << 1) | (block13 >>> 63));
+ values[valuesOffset++] = (int) ((block13 >>> 46) & 131071L);
+ values[valuesOffset++] = (int) ((block13 >>> 29) & 131071L);
+ values[valuesOffset++] = (int) ((block13 >>> 12) & 131071L);
+ final long block14 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block13 & 4095L) << 5) | (block14 >>> 59));
+ values[valuesOffset++] = (int) ((block14 >>> 42) & 131071L);
+ values[valuesOffset++] = (int) ((block14 >>> 25) & 131071L);
+ values[valuesOffset++] = (int) ((block14 >>> 8) & 131071L);
+ final long block15 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block14 & 255L) << 9) | (block15 >>> 55));
+ values[valuesOffset++] = (int) ((block15 >>> 38) & 131071L);
+ values[valuesOffset++] = (int) ((block15 >>> 21) & 131071L);
+ values[valuesOffset++] = (int) ((block15 >>> 4) & 131071L);
+ final long block16 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block15 & 15L) << 13) | (block16 >>> 51));
+ values[valuesOffset++] = (int) ((block16 >>> 34) & 131071L);
+ values[valuesOffset++] = (int) ((block16 >>> 17) & 131071L);
+ values[valuesOffset++] = (int) (block16 & 131071L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked7.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked7.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked7.java (working copy)
@@ -106,6 +106,91 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ // System.out.println("decode7 address=" + address + " iters=" + iterations);
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 57);
+ values[valuesOffset++] = (int) ((block0 >>> 50) & 127L);
+ values[valuesOffset++] = (int) ((block0 >>> 43) & 127L);
+ values[valuesOffset++] = (int) ((block0 >>> 36) & 127L);
+ values[valuesOffset++] = (int) ((block0 >>> 29) & 127L);
+ values[valuesOffset++] = (int) ((block0 >>> 22) & 127L);
+ values[valuesOffset++] = (int) ((block0 >>> 15) & 127L);
+ values[valuesOffset++] = (int) ((block0 >>> 8) & 127L);
+ values[valuesOffset++] = (int) ((block0 >>> 1) & 127L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 1L) << 6) | (block1 >>> 58));
+ values[valuesOffset++] = (int) ((block1 >>> 51) & 127L);
+ values[valuesOffset++] = (int) ((block1 >>> 44) & 127L);
+ values[valuesOffset++] = (int) ((block1 >>> 37) & 127L);
+ values[valuesOffset++] = (int) ((block1 >>> 30) & 127L);
+ values[valuesOffset++] = (int) ((block1 >>> 23) & 127L);
+ values[valuesOffset++] = (int) ((block1 >>> 16) & 127L);
+ values[valuesOffset++] = (int) ((block1 >>> 9) & 127L);
+ values[valuesOffset++] = (int) ((block1 >>> 2) & 127L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 3L) << 5) | (block2 >>> 59));
+ values[valuesOffset++] = (int) ((block2 >>> 52) & 127L);
+ values[valuesOffset++] = (int) ((block2 >>> 45) & 127L);
+ values[valuesOffset++] = (int) ((block2 >>> 38) & 127L);
+ values[valuesOffset++] = (int) ((block2 >>> 31) & 127L);
+ values[valuesOffset++] = (int) ((block2 >>> 24) & 127L);
+ values[valuesOffset++] = (int) ((block2 >>> 17) & 127L);
+ values[valuesOffset++] = (int) ((block2 >>> 10) & 127L);
+ values[valuesOffset++] = (int) ((block2 >>> 3) & 127L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 7L) << 4) | (block3 >>> 60));
+ values[valuesOffset++] = (int) ((block3 >>> 53) & 127L);
+ values[valuesOffset++] = (int) ((block3 >>> 46) & 127L);
+ values[valuesOffset++] = (int) ((block3 >>> 39) & 127L);
+ values[valuesOffset++] = (int) ((block3 >>> 32) & 127L);
+ values[valuesOffset++] = (int) ((block3 >>> 25) & 127L);
+ values[valuesOffset++] = (int) ((block3 >>> 18) & 127L);
+ values[valuesOffset++] = (int) ((block3 >>> 11) & 127L);
+ values[valuesOffset++] = (int) ((block3 >>> 4) & 127L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 15L) << 3) | (block4 >>> 61));
+ values[valuesOffset++] = (int) ((block4 >>> 54) & 127L);
+ values[valuesOffset++] = (int) ((block4 >>> 47) & 127L);
+ values[valuesOffset++] = (int) ((block4 >>> 40) & 127L);
+ values[valuesOffset++] = (int) ((block4 >>> 33) & 127L);
+ values[valuesOffset++] = (int) ((block4 >>> 26) & 127L);
+ values[valuesOffset++] = (int) ((block4 >>> 19) & 127L);
+ values[valuesOffset++] = (int) ((block4 >>> 12) & 127L);
+ values[valuesOffset++] = (int) ((block4 >>> 5) & 127L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 31L) << 2) | (block5 >>> 62));
+ values[valuesOffset++] = (int) ((block5 >>> 55) & 127L);
+ values[valuesOffset++] = (int) ((block5 >>> 48) & 127L);
+ values[valuesOffset++] = (int) ((block5 >>> 41) & 127L);
+ values[valuesOffset++] = (int) ((block5 >>> 34) & 127L);
+ values[valuesOffset++] = (int) ((block5 >>> 27) & 127L);
+ values[valuesOffset++] = (int) ((block5 >>> 20) & 127L);
+ values[valuesOffset++] = (int) ((block5 >>> 13) & 127L);
+ values[valuesOffset++] = (int) ((block5 >>> 6) & 127L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 63L) << 1) | (block6 >>> 63));
+ values[valuesOffset++] = (int) ((block6 >>> 56) & 127L);
+ values[valuesOffset++] = (int) ((block6 >>> 49) & 127L);
+ values[valuesOffset++] = (int) ((block6 >>> 42) & 127L);
+ values[valuesOffset++] = (int) ((block6 >>> 35) & 127L);
+ values[valuesOffset++] = (int) ((block6 >>> 28) & 127L);
+ values[valuesOffset++] = (int) ((block6 >>> 21) & 127L);
+ values[valuesOffset++] = (int) ((block6 >>> 14) & 127L);
+ values[valuesOffset++] = (int) ((block6 >>> 7) & 127L);
+ values[valuesOffset++] = (int) (block6 & 127L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked14.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked14.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked14.java (working copy)
@@ -74,6 +74,58 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 50);
+ values[valuesOffset++] = (int) ((block0 >>> 36) & 16383L);
+ values[valuesOffset++] = (int) ((block0 >>> 22) & 16383L);
+ values[valuesOffset++] = (int) ((block0 >>> 8) & 16383L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 255L) << 6) | (block1 >>> 58));
+ values[valuesOffset++] = (int) ((block1 >>> 44) & 16383L);
+ values[valuesOffset++] = (int) ((block1 >>> 30) & 16383L);
+ values[valuesOffset++] = (int) ((block1 >>> 16) & 16383L);
+ values[valuesOffset++] = (int) ((block1 >>> 2) & 16383L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 3L) << 12) | (block2 >>> 52));
+ values[valuesOffset++] = (int) ((block2 >>> 38) & 16383L);
+ values[valuesOffset++] = (int) ((block2 >>> 24) & 16383L);
+ values[valuesOffset++] = (int) ((block2 >>> 10) & 16383L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 1023L) << 4) | (block3 >>> 60));
+ values[valuesOffset++] = (int) ((block3 >>> 46) & 16383L);
+ values[valuesOffset++] = (int) ((block3 >>> 32) & 16383L);
+ values[valuesOffset++] = (int) ((block3 >>> 18) & 16383L);
+ values[valuesOffset++] = (int) ((block3 >>> 4) & 16383L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 15L) << 10) | (block4 >>> 54));
+ values[valuesOffset++] = (int) ((block4 >>> 40) & 16383L);
+ values[valuesOffset++] = (int) ((block4 >>> 26) & 16383L);
+ values[valuesOffset++] = (int) ((block4 >>> 12) & 16383L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 4095L) << 2) | (block5 >>> 62));
+ values[valuesOffset++] = (int) ((block5 >>> 48) & 16383L);
+ values[valuesOffset++] = (int) ((block5 >>> 34) & 16383L);
+ values[valuesOffset++] = (int) ((block5 >>> 20) & 16383L);
+ values[valuesOffset++] = (int) ((block5 >>> 6) & 16383L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 63L) << 8) | (block6 >>> 56));
+ values[valuesOffset++] = (int) ((block6 >>> 42) & 16383L);
+ values[valuesOffset++] = (int) ((block6 >>> 28) & 16383L);
+ values[valuesOffset++] = (int) ((block6 >>> 14) & 16383L);
+ values[valuesOffset++] = (int) (block6 & 16383L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked4.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked4.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked4.java (working copy)
@@ -39,6 +39,17 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block = unsafe.getLong(address);
+ address += 8;
+ for (int shift = 60; shift >= 0; shift -= 4) {
+ values[valuesOffset++] = (int) ((block >>> shift) & 15);
+ }
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int j = 0; j < iterations; ++j) {
final byte block = blocks[blocksOffset++];
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperation.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperation.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperation.java (working copy)
@@ -23,8 +23,21 @@
/**
* Efficient sequential read/write of packed integers.
*/
+import java.lang.reflect.*;import sun.misc.Unsafe;
abstract class BulkOperation implements PackedInts.Decoder, PackedInts.Encoder {
- private static final BulkOperation[] packedBulkOps = new BulkOperation[] {
+
+ protected static final Unsafe unsafe;
+
+ static {
+ try {
+ Field f = Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe) f.get(null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ private static final BulkOperation[] packedBulkOps = new BulkOperation[] {
new BulkOperationPacked1(),
new BulkOperationPacked2(),
new BulkOperationPacked3(),
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked11.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked11.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked11.java (working copy)
@@ -110,6 +110,98 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 53);
+ values[valuesOffset++] = (int) ((block0 >>> 42) & 2047L);
+ values[valuesOffset++] = (int) ((block0 >>> 31) & 2047L);
+ values[valuesOffset++] = (int) ((block0 >>> 20) & 2047L);
+ values[valuesOffset++] = (int) ((block0 >>> 9) & 2047L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 511L) << 2) | (block1 >>> 62));
+ values[valuesOffset++] = (int) ((block1 >>> 51) & 2047L);
+ values[valuesOffset++] = (int) ((block1 >>> 40) & 2047L);
+ values[valuesOffset++] = (int) ((block1 >>> 29) & 2047L);
+ values[valuesOffset++] = (int) ((block1 >>> 18) & 2047L);
+ values[valuesOffset++] = (int) ((block1 >>> 7) & 2047L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 127L) << 4) | (block2 >>> 60));
+ values[valuesOffset++] = (int) ((block2 >>> 49) & 2047L);
+ values[valuesOffset++] = (int) ((block2 >>> 38) & 2047L);
+ values[valuesOffset++] = (int) ((block2 >>> 27) & 2047L);
+ values[valuesOffset++] = (int) ((block2 >>> 16) & 2047L);
+ values[valuesOffset++] = (int) ((block2 >>> 5) & 2047L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 31L) << 6) | (block3 >>> 58));
+ values[valuesOffset++] = (int) ((block3 >>> 47) & 2047L);
+ values[valuesOffset++] = (int) ((block3 >>> 36) & 2047L);
+ values[valuesOffset++] = (int) ((block3 >>> 25) & 2047L);
+ values[valuesOffset++] = (int) ((block3 >>> 14) & 2047L);
+ values[valuesOffset++] = (int) ((block3 >>> 3) & 2047L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 7L) << 8) | (block4 >>> 56));
+ values[valuesOffset++] = (int) ((block4 >>> 45) & 2047L);
+ values[valuesOffset++] = (int) ((block4 >>> 34) & 2047L);
+ values[valuesOffset++] = (int) ((block4 >>> 23) & 2047L);
+ values[valuesOffset++] = (int) ((block4 >>> 12) & 2047L);
+ values[valuesOffset++] = (int) ((block4 >>> 1) & 2047L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 1L) << 10) | (block5 >>> 54));
+ values[valuesOffset++] = (int) ((block5 >>> 43) & 2047L);
+ values[valuesOffset++] = (int) ((block5 >>> 32) & 2047L);
+ values[valuesOffset++] = (int) ((block5 >>> 21) & 2047L);
+ values[valuesOffset++] = (int) ((block5 >>> 10) & 2047L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 1023L) << 1) | (block6 >>> 63));
+ values[valuesOffset++] = (int) ((block6 >>> 52) & 2047L);
+ values[valuesOffset++] = (int) ((block6 >>> 41) & 2047L);
+ values[valuesOffset++] = (int) ((block6 >>> 30) & 2047L);
+ values[valuesOffset++] = (int) ((block6 >>> 19) & 2047L);
+ values[valuesOffset++] = (int) ((block6 >>> 8) & 2047L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 255L) << 3) | (block7 >>> 61));
+ values[valuesOffset++] = (int) ((block7 >>> 50) & 2047L);
+ values[valuesOffset++] = (int) ((block7 >>> 39) & 2047L);
+ values[valuesOffset++] = (int) ((block7 >>> 28) & 2047L);
+ values[valuesOffset++] = (int) ((block7 >>> 17) & 2047L);
+ values[valuesOffset++] = (int) ((block7 >>> 6) & 2047L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 63L) << 5) | (block8 >>> 59));
+ values[valuesOffset++] = (int) ((block8 >>> 48) & 2047L);
+ values[valuesOffset++] = (int) ((block8 >>> 37) & 2047L);
+ values[valuesOffset++] = (int) ((block8 >>> 26) & 2047L);
+ values[valuesOffset++] = (int) ((block8 >>> 15) & 2047L);
+ values[valuesOffset++] = (int) ((block8 >>> 4) & 2047L);
+ final long block9 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block8 & 15L) << 7) | (block9 >>> 57));
+ values[valuesOffset++] = (int) ((block9 >>> 46) & 2047L);
+ values[valuesOffset++] = (int) ((block9 >>> 35) & 2047L);
+ values[valuesOffset++] = (int) ((block9 >>> 24) & 2047L);
+ values[valuesOffset++] = (int) ((block9 >>> 13) & 2047L);
+ values[valuesOffset++] = (int) ((block9 >>> 2) & 2047L);
+ final long block10 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block9 & 3L) << 9) | (block10 >>> 55));
+ values[valuesOffset++] = (int) ((block10 >>> 44) & 2047L);
+ values[valuesOffset++] = (int) ((block10 >>> 33) & 2047L);
+ values[valuesOffset++] = (int) ((block10 >>> 22) & 2047L);
+ values[valuesOffset++] = (int) ((block10 >>> 11) & 2047L);
+ values[valuesOffset++] = (int) (block10 & 2047L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked23.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked23.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked23.java (working copy)
@@ -122,6 +122,122 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 41);
+ values[valuesOffset++] = (int) ((block0 >>> 18) & 8388607L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 262143L) << 5) | (block1 >>> 59));
+ values[valuesOffset++] = (int) ((block1 >>> 36) & 8388607L);
+ values[valuesOffset++] = (int) ((block1 >>> 13) & 8388607L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 8191L) << 10) | (block2 >>> 54));
+ values[valuesOffset++] = (int) ((block2 >>> 31) & 8388607L);
+ values[valuesOffset++] = (int) ((block2 >>> 8) & 8388607L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 255L) << 15) | (block3 >>> 49));
+ values[valuesOffset++] = (int) ((block3 >>> 26) & 8388607L);
+ values[valuesOffset++] = (int) ((block3 >>> 3) & 8388607L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 7L) << 20) | (block4 >>> 44));
+ values[valuesOffset++] = (int) ((block4 >>> 21) & 8388607L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 2097151L) << 2) | (block5 >>> 62));
+ values[valuesOffset++] = (int) ((block5 >>> 39) & 8388607L);
+ values[valuesOffset++] = (int) ((block5 >>> 16) & 8388607L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 65535L) << 7) | (block6 >>> 57));
+ values[valuesOffset++] = (int) ((block6 >>> 34) & 8388607L);
+ values[valuesOffset++] = (int) ((block6 >>> 11) & 8388607L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 2047L) << 12) | (block7 >>> 52));
+ values[valuesOffset++] = (int) ((block7 >>> 29) & 8388607L);
+ values[valuesOffset++] = (int) ((block7 >>> 6) & 8388607L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 63L) << 17) | (block8 >>> 47));
+ values[valuesOffset++] = (int) ((block8 >>> 24) & 8388607L);
+ values[valuesOffset++] = (int) ((block8 >>> 1) & 8388607L);
+ final long block9 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block8 & 1L) << 22) | (block9 >>> 42));
+ values[valuesOffset++] = (int) ((block9 >>> 19) & 8388607L);
+ final long block10 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block9 & 524287L) << 4) | (block10 >>> 60));
+ values[valuesOffset++] = (int) ((block10 >>> 37) & 8388607L);
+ values[valuesOffset++] = (int) ((block10 >>> 14) & 8388607L);
+ final long block11 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block10 & 16383L) << 9) | (block11 >>> 55));
+ values[valuesOffset++] = (int) ((block11 >>> 32) & 8388607L);
+ values[valuesOffset++] = (int) ((block11 >>> 9) & 8388607L);
+ final long block12 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block11 & 511L) << 14) | (block12 >>> 50));
+ values[valuesOffset++] = (int) ((block12 >>> 27) & 8388607L);
+ values[valuesOffset++] = (int) ((block12 >>> 4) & 8388607L);
+ final long block13 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block12 & 15L) << 19) | (block13 >>> 45));
+ values[valuesOffset++] = (int) ((block13 >>> 22) & 8388607L);
+ final long block14 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block13 & 4194303L) << 1) | (block14 >>> 63));
+ values[valuesOffset++] = (int) ((block14 >>> 40) & 8388607L);
+ values[valuesOffset++] = (int) ((block14 >>> 17) & 8388607L);
+ final long block15 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block14 & 131071L) << 6) | (block15 >>> 58));
+ values[valuesOffset++] = (int) ((block15 >>> 35) & 8388607L);
+ values[valuesOffset++] = (int) ((block15 >>> 12) & 8388607L);
+ final long block16 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block15 & 4095L) << 11) | (block16 >>> 53));
+ values[valuesOffset++] = (int) ((block16 >>> 30) & 8388607L);
+ values[valuesOffset++] = (int) ((block16 >>> 7) & 8388607L);
+ final long block17 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block16 & 127L) << 16) | (block17 >>> 48));
+ values[valuesOffset++] = (int) ((block17 >>> 25) & 8388607L);
+ values[valuesOffset++] = (int) ((block17 >>> 2) & 8388607L);
+ final long block18 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block17 & 3L) << 21) | (block18 >>> 43));
+ values[valuesOffset++] = (int) ((block18 >>> 20) & 8388607L);
+ final long block19 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block18 & 1048575L) << 3) | (block19 >>> 61));
+ values[valuesOffset++] = (int) ((block19 >>> 38) & 8388607L);
+ values[valuesOffset++] = (int) ((block19 >>> 15) & 8388607L);
+ final long block20 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block19 & 32767L) << 8) | (block20 >>> 56));
+ values[valuesOffset++] = (int) ((block20 >>> 33) & 8388607L);
+ values[valuesOffset++] = (int) ((block20 >>> 10) & 8388607L);
+ final long block21 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block20 & 1023L) << 13) | (block21 >>> 51));
+ values[valuesOffset++] = (int) ((block21 >>> 28) & 8388607L);
+ values[valuesOffset++] = (int) ((block21 >>> 5) & 8388607L);
+ final long block22 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block21 & 31L) << 18) | (block22 >>> 46));
+ values[valuesOffset++] = (int) ((block22 >>> 23) & 8388607L);
+ values[valuesOffset++] = (int) (block22 & 8388607L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked19.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked19.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked19.java (working copy)
@@ -118,6 +118,114 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 45);
+ values[valuesOffset++] = (int) ((block0 >>> 26) & 524287L);
+ values[valuesOffset++] = (int) ((block0 >>> 7) & 524287L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 127L) << 12) | (block1 >>> 52));
+ values[valuesOffset++] = (int) ((block1 >>> 33) & 524287L);
+ values[valuesOffset++] = (int) ((block1 >>> 14) & 524287L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 16383L) << 5) | (block2 >>> 59));
+ values[valuesOffset++] = (int) ((block2 >>> 40) & 524287L);
+ values[valuesOffset++] = (int) ((block2 >>> 21) & 524287L);
+ values[valuesOffset++] = (int) ((block2 >>> 2) & 524287L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 3L) << 17) | (block3 >>> 47));
+ values[valuesOffset++] = (int) ((block3 >>> 28) & 524287L);
+ values[valuesOffset++] = (int) ((block3 >>> 9) & 524287L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 511L) << 10) | (block4 >>> 54));
+ values[valuesOffset++] = (int) ((block4 >>> 35) & 524287L);
+ values[valuesOffset++] = (int) ((block4 >>> 16) & 524287L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 65535L) << 3) | (block5 >>> 61));
+ values[valuesOffset++] = (int) ((block5 >>> 42) & 524287L);
+ values[valuesOffset++] = (int) ((block5 >>> 23) & 524287L);
+ values[valuesOffset++] = (int) ((block5 >>> 4) & 524287L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 15L) << 15) | (block6 >>> 49));
+ values[valuesOffset++] = (int) ((block6 >>> 30) & 524287L);
+ values[valuesOffset++] = (int) ((block6 >>> 11) & 524287L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 2047L) << 8) | (block7 >>> 56));
+ values[valuesOffset++] = (int) ((block7 >>> 37) & 524287L);
+ values[valuesOffset++] = (int) ((block7 >>> 18) & 524287L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 262143L) << 1) | (block8 >>> 63));
+ values[valuesOffset++] = (int) ((block8 >>> 44) & 524287L);
+ values[valuesOffset++] = (int) ((block8 >>> 25) & 524287L);
+ values[valuesOffset++] = (int) ((block8 >>> 6) & 524287L);
+ final long block9 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block8 & 63L) << 13) | (block9 >>> 51));
+ values[valuesOffset++] = (int) ((block9 >>> 32) & 524287L);
+ values[valuesOffset++] = (int) ((block9 >>> 13) & 524287L);
+ final long block10 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block9 & 8191L) << 6) | (block10 >>> 58));
+ values[valuesOffset++] = (int) ((block10 >>> 39) & 524287L);
+ values[valuesOffset++] = (int) ((block10 >>> 20) & 524287L);
+ values[valuesOffset++] = (int) ((block10 >>> 1) & 524287L);
+ final long block11 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block10 & 1L) << 18) | (block11 >>> 46));
+ values[valuesOffset++] = (int) ((block11 >>> 27) & 524287L);
+ values[valuesOffset++] = (int) ((block11 >>> 8) & 524287L);
+ final long block12 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block11 & 255L) << 11) | (block12 >>> 53));
+ values[valuesOffset++] = (int) ((block12 >>> 34) & 524287L);
+ values[valuesOffset++] = (int) ((block12 >>> 15) & 524287L);
+ final long block13 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block12 & 32767L) << 4) | (block13 >>> 60));
+ values[valuesOffset++] = (int) ((block13 >>> 41) & 524287L);
+ values[valuesOffset++] = (int) ((block13 >>> 22) & 524287L);
+ values[valuesOffset++] = (int) ((block13 >>> 3) & 524287L);
+ final long block14 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block13 & 7L) << 16) | (block14 >>> 48));
+ values[valuesOffset++] = (int) ((block14 >>> 29) & 524287L);
+ values[valuesOffset++] = (int) ((block14 >>> 10) & 524287L);
+ final long block15 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block14 & 1023L) << 9) | (block15 >>> 55));
+ values[valuesOffset++] = (int) ((block15 >>> 36) & 524287L);
+ values[valuesOffset++] = (int) ((block15 >>> 17) & 524287L);
+ final long block16 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block15 & 131071L) << 2) | (block16 >>> 62));
+ values[valuesOffset++] = (int) ((block16 >>> 43) & 524287L);
+ values[valuesOffset++] = (int) ((block16 >>> 24) & 524287L);
+ values[valuesOffset++] = (int) ((block16 >>> 5) & 524287L);
+ final long block17 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block16 & 31L) << 14) | (block17 >>> 50));
+ values[valuesOffset++] = (int) ((block17 >>> 31) & 524287L);
+ values[valuesOffset++] = (int) ((block17 >>> 12) & 524287L);
+ final long block18 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block17 & 4095L) << 7) | (block18 >>> 57));
+ values[valuesOffset++] = (int) ((block18 >>> 38) & 524287L);
+ values[valuesOffset++] = (int) ((block18 >>> 19) & 524287L);
+ values[valuesOffset++] = (int) (block18 & 524287L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked1.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked1.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked1.java (working copy)
@@ -39,6 +39,17 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block = unsafe.getLong(address);
+ address += 8;
+ for (int shift = 63; shift >= 0; shift -= 1) {
+ values[valuesOffset++] = (int) ((block >>> shift) & 1);
+ }
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int j = 0; j < iterations; ++j) {
final byte block = blocks[blocksOffset++];
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked9.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked9.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked9.java (working copy)
@@ -108,6 +108,94 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 55);
+ values[valuesOffset++] = (int) ((block0 >>> 46) & 511L);
+ values[valuesOffset++] = (int) ((block0 >>> 37) & 511L);
+ values[valuesOffset++] = (int) ((block0 >>> 28) & 511L);
+ values[valuesOffset++] = (int) ((block0 >>> 19) & 511L);
+ values[valuesOffset++] = (int) ((block0 >>> 10) & 511L);
+ values[valuesOffset++] = (int) ((block0 >>> 1) & 511L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 1L) << 8) | (block1 >>> 56));
+ values[valuesOffset++] = (int) ((block1 >>> 47) & 511L);
+ values[valuesOffset++] = (int) ((block1 >>> 38) & 511L);
+ values[valuesOffset++] = (int) ((block1 >>> 29) & 511L);
+ values[valuesOffset++] = (int) ((block1 >>> 20) & 511L);
+ values[valuesOffset++] = (int) ((block1 >>> 11) & 511L);
+ values[valuesOffset++] = (int) ((block1 >>> 2) & 511L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 3L) << 7) | (block2 >>> 57));
+ values[valuesOffset++] = (int) ((block2 >>> 48) & 511L);
+ values[valuesOffset++] = (int) ((block2 >>> 39) & 511L);
+ values[valuesOffset++] = (int) ((block2 >>> 30) & 511L);
+ values[valuesOffset++] = (int) ((block2 >>> 21) & 511L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 511L);
+ values[valuesOffset++] = (int) ((block2 >>> 3) & 511L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 7L) << 6) | (block3 >>> 58));
+ values[valuesOffset++] = (int) ((block3 >>> 49) & 511L);
+ values[valuesOffset++] = (int) ((block3 >>> 40) & 511L);
+ values[valuesOffset++] = (int) ((block3 >>> 31) & 511L);
+ values[valuesOffset++] = (int) ((block3 >>> 22) & 511L);
+ values[valuesOffset++] = (int) ((block3 >>> 13) & 511L);
+ values[valuesOffset++] = (int) ((block3 >>> 4) & 511L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 15L) << 5) | (block4 >>> 59));
+ values[valuesOffset++] = (int) ((block4 >>> 50) & 511L);
+ values[valuesOffset++] = (int) ((block4 >>> 41) & 511L);
+ values[valuesOffset++] = (int) ((block4 >>> 32) & 511L);
+ values[valuesOffset++] = (int) ((block4 >>> 23) & 511L);
+ values[valuesOffset++] = (int) ((block4 >>> 14) & 511L);
+ values[valuesOffset++] = (int) ((block4 >>> 5) & 511L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 31L) << 4) | (block5 >>> 60));
+ values[valuesOffset++] = (int) ((block5 >>> 51) & 511L);
+ values[valuesOffset++] = (int) ((block5 >>> 42) & 511L);
+ values[valuesOffset++] = (int) ((block5 >>> 33) & 511L);
+ values[valuesOffset++] = (int) ((block5 >>> 24) & 511L);
+ values[valuesOffset++] = (int) ((block5 >>> 15) & 511L);
+ values[valuesOffset++] = (int) ((block5 >>> 6) & 511L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 63L) << 3) | (block6 >>> 61));
+ values[valuesOffset++] = (int) ((block6 >>> 52) & 511L);
+ values[valuesOffset++] = (int) ((block6 >>> 43) & 511L);
+ values[valuesOffset++] = (int) ((block6 >>> 34) & 511L);
+ values[valuesOffset++] = (int) ((block6 >>> 25) & 511L);
+ values[valuesOffset++] = (int) ((block6 >>> 16) & 511L);
+ values[valuesOffset++] = (int) ((block6 >>> 7) & 511L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 127L) << 2) | (block7 >>> 62));
+ values[valuesOffset++] = (int) ((block7 >>> 53) & 511L);
+ values[valuesOffset++] = (int) ((block7 >>> 44) & 511L);
+ values[valuesOffset++] = (int) ((block7 >>> 35) & 511L);
+ values[valuesOffset++] = (int) ((block7 >>> 26) & 511L);
+ values[valuesOffset++] = (int) ((block7 >>> 17) & 511L);
+ values[valuesOffset++] = (int) ((block7 >>> 8) & 511L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 255L) << 1) | (block8 >>> 63));
+ values[valuesOffset++] = (int) ((block8 >>> 54) & 511L);
+ values[valuesOffset++] = (int) ((block8 >>> 45) & 511L);
+ values[valuesOffset++] = (int) ((block8 >>> 36) & 511L);
+ values[valuesOffset++] = (int) ((block8 >>> 27) & 511L);
+ values[valuesOffset++] = (int) ((block8 >>> 18) & 511L);
+ values[valuesOffset++] = (int) ((block8 >>> 9) & 511L);
+ values[valuesOffset++] = (int) (block8 & 511L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked20.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked20.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked20.java (working copy)
@@ -56,6 +56,38 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 44);
+ values[valuesOffset++] = (int) ((block0 >>> 24) & 1048575L);
+ values[valuesOffset++] = (int) ((block0 >>> 4) & 1048575L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 15L) << 16) | (block1 >>> 48));
+ values[valuesOffset++] = (int) ((block1 >>> 28) & 1048575L);
+ values[valuesOffset++] = (int) ((block1 >>> 8) & 1048575L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 255L) << 12) | (block2 >>> 52));
+ values[valuesOffset++] = (int) ((block2 >>> 32) & 1048575L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 1048575L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 4095L) << 8) | (block3 >>> 56));
+ values[valuesOffset++] = (int) ((block3 >>> 36) & 1048575L);
+ values[valuesOffset++] = (int) ((block3 >>> 16) & 1048575L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 65535L) << 4) | (block4 >>> 60));
+ values[valuesOffset++] = (int) ((block4 >>> 40) & 1048575L);
+ values[valuesOffset++] = (int) ((block4 >>> 20) & 1048575L);
+ values[valuesOffset++] = (int) (block4 & 1048575L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked16.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked16.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked16.java (working copy)
@@ -39,6 +39,17 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block = unsafe.getLong(address);
+ address += 8;
+ for (int shift = 48; shift >= 0; shift -= 16) {
+ values[valuesOffset++] = (int) ((block >>> shift) & 65535);
+ }
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int j = 0; j < iterations; ++j) {
values[valuesOffset++] = ((blocks[blocksOffset++] & 0xFF) << 8) | (blocks[blocksOffset++] & 0xFF);
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked6.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked6.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked6.java (working copy)
@@ -70,6 +70,51 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ //System.out.println("decode6 address=" + address + " iters=" + iterations);
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 58);
+ values[valuesOffset++] = (int) ((block0 >>> 52) & 63L);
+ values[valuesOffset++] = (int) ((block0 >>> 46) & 63L);
+ values[valuesOffset++] = (int) ((block0 >>> 40) & 63L);
+ values[valuesOffset++] = (int) ((block0 >>> 34) & 63L);
+ values[valuesOffset++] = (int) ((block0 >>> 28) & 63L);
+ values[valuesOffset++] = (int) ((block0 >>> 22) & 63L);
+ values[valuesOffset++] = (int) ((block0 >>> 16) & 63L);
+ values[valuesOffset++] = (int) ((block0 >>> 10) & 63L);
+ values[valuesOffset++] = (int) ((block0 >>> 4) & 63L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 15L) << 2) | (block1 >>> 62));
+ values[valuesOffset++] = (int) ((block1 >>> 56) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 50) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 44) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 38) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 32) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 26) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 20) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 14) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 8) & 63L);
+ values[valuesOffset++] = (int) ((block1 >>> 2) & 63L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 3L) << 4) | (block2 >>> 60));
+ values[valuesOffset++] = (int) ((block2 >>> 54) & 63L);
+ values[valuesOffset++] = (int) ((block2 >>> 48) & 63L);
+ values[valuesOffset++] = (int) ((block2 >>> 42) & 63L);
+ values[valuesOffset++] = (int) ((block2 >>> 36) & 63L);
+ values[valuesOffset++] = (int) ((block2 >>> 30) & 63L);
+ values[valuesOffset++] = (int) ((block2 >>> 24) & 63L);
+ values[valuesOffset++] = (int) ((block2 >>> 18) & 63L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 63L);
+ values[valuesOffset++] = (int) ((block2 >>> 6) & 63L);
+ values[valuesOffset++] = (int) (block2 & 63L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked.java (working copy)
@@ -142,6 +142,31 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values,
+ int valuesOffset, int iterations) {
+ if (bitsPerValue > 32) {
+ throw new UnsupportedOperationException("Cannot decode " + bitsPerValue + "-bits values into an int[]");
+ }
+ int bitsLeft = 64;
+ long encoded = unsafe.getLong(address);
+ address += 8;
+ for (int i = 0; i < longValueCount * iterations; ++i) {
+ bitsLeft -= bitsPerValue;
+ if (bitsLeft < 0) {
+ long encodedNext = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int)
+ (((encoded & ((1L << (bitsPerValue + bitsLeft)) - 1)) << -bitsLeft)
+ | (encodedNext >>> (64 + bitsLeft)));
+ bitsLeft += 64;
+ encoded = encodedNext;
+ } else {
+ values[valuesOffset++] = (int) ((encoded >>> bitsLeft) & mask);
+ }
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values,
int valuesOffset, int iterations) {
int nextValue = 0;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked13.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked13.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked13.java (working copy)
@@ -112,6 +112,102 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 51);
+ values[valuesOffset++] = (int) ((block0 >>> 38) & 8191L);
+ values[valuesOffset++] = (int) ((block0 >>> 25) & 8191L);
+ values[valuesOffset++] = (int) ((block0 >>> 12) & 8191L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 4095L) << 1) | (block1 >>> 63));
+ values[valuesOffset++] = (int) ((block1 >>> 50) & 8191L);
+ values[valuesOffset++] = (int) ((block1 >>> 37) & 8191L);
+ values[valuesOffset++] = (int) ((block1 >>> 24) & 8191L);
+ values[valuesOffset++] = (int) ((block1 >>> 11) & 8191L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 2047L) << 2) | (block2 >>> 62));
+ values[valuesOffset++] = (int) ((block2 >>> 49) & 8191L);
+ values[valuesOffset++] = (int) ((block2 >>> 36) & 8191L);
+ values[valuesOffset++] = (int) ((block2 >>> 23) & 8191L);
+ values[valuesOffset++] = (int) ((block2 >>> 10) & 8191L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 1023L) << 3) | (block3 >>> 61));
+ values[valuesOffset++] = (int) ((block3 >>> 48) & 8191L);
+ values[valuesOffset++] = (int) ((block3 >>> 35) & 8191L);
+ values[valuesOffset++] = (int) ((block3 >>> 22) & 8191L);
+ values[valuesOffset++] = (int) ((block3 >>> 9) & 8191L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 511L) << 4) | (block4 >>> 60));
+ values[valuesOffset++] = (int) ((block4 >>> 47) & 8191L);
+ values[valuesOffset++] = (int) ((block4 >>> 34) & 8191L);
+ values[valuesOffset++] = (int) ((block4 >>> 21) & 8191L);
+ values[valuesOffset++] = (int) ((block4 >>> 8) & 8191L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 255L) << 5) | (block5 >>> 59));
+ values[valuesOffset++] = (int) ((block5 >>> 46) & 8191L);
+ values[valuesOffset++] = (int) ((block5 >>> 33) & 8191L);
+ values[valuesOffset++] = (int) ((block5 >>> 20) & 8191L);
+ values[valuesOffset++] = (int) ((block5 >>> 7) & 8191L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 127L) << 6) | (block6 >>> 58));
+ values[valuesOffset++] = (int) ((block6 >>> 45) & 8191L);
+ values[valuesOffset++] = (int) ((block6 >>> 32) & 8191L);
+ values[valuesOffset++] = (int) ((block6 >>> 19) & 8191L);
+ values[valuesOffset++] = (int) ((block6 >>> 6) & 8191L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 63L) << 7) | (block7 >>> 57));
+ values[valuesOffset++] = (int) ((block7 >>> 44) & 8191L);
+ values[valuesOffset++] = (int) ((block7 >>> 31) & 8191L);
+ values[valuesOffset++] = (int) ((block7 >>> 18) & 8191L);
+ values[valuesOffset++] = (int) ((block7 >>> 5) & 8191L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 31L) << 8) | (block8 >>> 56));
+ values[valuesOffset++] = (int) ((block8 >>> 43) & 8191L);
+ values[valuesOffset++] = (int) ((block8 >>> 30) & 8191L);
+ values[valuesOffset++] = (int) ((block8 >>> 17) & 8191L);
+ values[valuesOffset++] = (int) ((block8 >>> 4) & 8191L);
+ final long block9 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block8 & 15L) << 9) | (block9 >>> 55));
+ values[valuesOffset++] = (int) ((block9 >>> 42) & 8191L);
+ values[valuesOffset++] = (int) ((block9 >>> 29) & 8191L);
+ values[valuesOffset++] = (int) ((block9 >>> 16) & 8191L);
+ values[valuesOffset++] = (int) ((block9 >>> 3) & 8191L);
+ final long block10 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block9 & 7L) << 10) | (block10 >>> 54));
+ values[valuesOffset++] = (int) ((block10 >>> 41) & 8191L);
+ values[valuesOffset++] = (int) ((block10 >>> 28) & 8191L);
+ values[valuesOffset++] = (int) ((block10 >>> 15) & 8191L);
+ values[valuesOffset++] = (int) ((block10 >>> 2) & 8191L);
+ final long block11 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block10 & 3L) << 11) | (block11 >>> 53));
+ values[valuesOffset++] = (int) ((block11 >>> 40) & 8191L);
+ values[valuesOffset++] = (int) ((block11 >>> 27) & 8191L);
+ values[valuesOffset++] = (int) ((block11 >>> 14) & 8191L);
+ values[valuesOffset++] = (int) ((block11 >>> 1) & 8191L);
+ final long block12 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block11 & 1L) << 12) | (block12 >>> 52));
+ values[valuesOffset++] = (int) ((block12 >>> 39) & 8191L);
+ values[valuesOffset++] = (int) ((block12 >>> 26) & 8191L);
+ values[valuesOffset++] = (int) ((block12 >>> 13) & 8191L);
+ values[valuesOffset++] = (int) (block12 & 8191L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked3.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked3.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked3.java (working copy)
@@ -102,6 +102,82 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 61);
+ values[valuesOffset++] = (int) ((block0 >>> 58) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 55) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 52) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 49) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 46) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 43) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 40) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 37) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 34) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 31) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 28) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 25) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 22) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 19) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 16) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 13) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 10) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 7) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 4) & 7L);
+ values[valuesOffset++] = (int) ((block0 >>> 1) & 7L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 1L) << 2) | (block1 >>> 62));
+ values[valuesOffset++] = (int) ((block1 >>> 59) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 56) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 53) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 50) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 47) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 44) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 41) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 38) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 35) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 32) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 29) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 26) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 23) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 20) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 17) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 14) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 11) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 8) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 5) & 7L);
+ values[valuesOffset++] = (int) ((block1 >>> 2) & 7L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 3L) << 1) | (block2 >>> 63));
+ values[valuesOffset++] = (int) ((block2 >>> 60) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 57) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 54) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 51) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 48) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 45) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 42) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 39) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 36) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 33) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 30) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 27) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 24) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 21) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 18) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 15) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 9) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 6) & 7L);
+ values[valuesOffset++] = (int) ((block2 >>> 3) & 7L);
+ values[valuesOffset++] = (int) (block2 & 7L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked10.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked10.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked10.java (working copy)
@@ -72,6 +72,54 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 54);
+ values[valuesOffset++] = (int) ((block0 >>> 44) & 1023L);
+ values[valuesOffset++] = (int) ((block0 >>> 34) & 1023L);
+ values[valuesOffset++] = (int) ((block0 >>> 24) & 1023L);
+ values[valuesOffset++] = (int) ((block0 >>> 14) & 1023L);
+ values[valuesOffset++] = (int) ((block0 >>> 4) & 1023L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 15L) << 6) | (block1 >>> 58));
+ values[valuesOffset++] = (int) ((block1 >>> 48) & 1023L);
+ values[valuesOffset++] = (int) ((block1 >>> 38) & 1023L);
+ values[valuesOffset++] = (int) ((block1 >>> 28) & 1023L);
+ values[valuesOffset++] = (int) ((block1 >>> 18) & 1023L);
+ values[valuesOffset++] = (int) ((block1 >>> 8) & 1023L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 255L) << 2) | (block2 >>> 62));
+ values[valuesOffset++] = (int) ((block2 >>> 52) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >>> 42) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >>> 32) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >>> 22) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >>> 2) & 1023L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 3L) << 8) | (block3 >>> 56));
+ values[valuesOffset++] = (int) ((block3 >>> 46) & 1023L);
+ values[valuesOffset++] = (int) ((block3 >>> 36) & 1023L);
+ values[valuesOffset++] = (int) ((block3 >>> 26) & 1023L);
+ values[valuesOffset++] = (int) ((block3 >>> 16) & 1023L);
+ values[valuesOffset++] = (int) ((block3 >>> 6) & 1023L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 63L) << 4) | (block4 >>> 60));
+ values[valuesOffset++] = (int) ((block4 >>> 50) & 1023L);
+ values[valuesOffset++] = (int) ((block4 >>> 40) & 1023L);
+ values[valuesOffset++] = (int) ((block4 >>> 30) & 1023L);
+ values[valuesOffset++] = (int) ((block4 >>> 20) & 1023L);
+ values[valuesOffset++] = (int) ((block4 >>> 10) & 1023L);
+ values[valuesOffset++] = (int) (block4 & 1023L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked22.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked22.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked22.java (working copy)
@@ -78,6 +78,66 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 42);
+ values[valuesOffset++] = (int) ((block0 >>> 20) & 4194303L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 1048575L) << 2) | (block1 >>> 62));
+ values[valuesOffset++] = (int) ((block1 >>> 40) & 4194303L);
+ values[valuesOffset++] = (int) ((block1 >>> 18) & 4194303L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 262143L) << 4) | (block2 >>> 60));
+ values[valuesOffset++] = (int) ((block2 >>> 38) & 4194303L);
+ values[valuesOffset++] = (int) ((block2 >>> 16) & 4194303L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 65535L) << 6) | (block3 >>> 58));
+ values[valuesOffset++] = (int) ((block3 >>> 36) & 4194303L);
+ values[valuesOffset++] = (int) ((block3 >>> 14) & 4194303L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 16383L) << 8) | (block4 >>> 56));
+ values[valuesOffset++] = (int) ((block4 >>> 34) & 4194303L);
+ values[valuesOffset++] = (int) ((block4 >>> 12) & 4194303L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 4095L) << 10) | (block5 >>> 54));
+ values[valuesOffset++] = (int) ((block5 >>> 32) & 4194303L);
+ values[valuesOffset++] = (int) ((block5 >>> 10) & 4194303L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 1023L) << 12) | (block6 >>> 52));
+ values[valuesOffset++] = (int) ((block6 >>> 30) & 4194303L);
+ values[valuesOffset++] = (int) ((block6 >>> 8) & 4194303L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 255L) << 14) | (block7 >>> 50));
+ values[valuesOffset++] = (int) ((block7 >>> 28) & 4194303L);
+ values[valuesOffset++] = (int) ((block7 >>> 6) & 4194303L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 63L) << 16) | (block8 >>> 48));
+ values[valuesOffset++] = (int) ((block8 >>> 26) & 4194303L);
+ values[valuesOffset++] = (int) ((block8 >>> 4) & 4194303L);
+ final long block9 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block8 & 15L) << 18) | (block9 >>> 46));
+ values[valuesOffset++] = (int) ((block9 >>> 24) & 4194303L);
+ values[valuesOffset++] = (int) ((block9 >>> 2) & 4194303L);
+ final long block10 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block9 & 3L) << 20) | (block10 >>> 44));
+ values[valuesOffset++] = (int) ((block10 >>> 22) & 4194303L);
+ values[valuesOffset++] = (int) (block10 & 4194303L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked18.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked18.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked18.java (working copy)
@@ -76,6 +76,62 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 46);
+ values[valuesOffset++] = (int) ((block0 >>> 28) & 262143L);
+ values[valuesOffset++] = (int) ((block0 >>> 10) & 262143L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 1023L) << 8) | (block1 >>> 56));
+ values[valuesOffset++] = (int) ((block1 >>> 38) & 262143L);
+ values[valuesOffset++] = (int) ((block1 >>> 20) & 262143L);
+ values[valuesOffset++] = (int) ((block1 >>> 2) & 262143L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 3L) << 16) | (block2 >>> 48));
+ values[valuesOffset++] = (int) ((block2 >>> 30) & 262143L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 262143L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 4095L) << 6) | (block3 >>> 58));
+ values[valuesOffset++] = (int) ((block3 >>> 40) & 262143L);
+ values[valuesOffset++] = (int) ((block3 >>> 22) & 262143L);
+ values[valuesOffset++] = (int) ((block3 >>> 4) & 262143L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 15L) << 14) | (block4 >>> 50));
+ values[valuesOffset++] = (int) ((block4 >>> 32) & 262143L);
+ values[valuesOffset++] = (int) ((block4 >>> 14) & 262143L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 16383L) << 4) | (block5 >>> 60));
+ values[valuesOffset++] = (int) ((block5 >>> 42) & 262143L);
+ values[valuesOffset++] = (int) ((block5 >>> 24) & 262143L);
+ values[valuesOffset++] = (int) ((block5 >>> 6) & 262143L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 63L) << 12) | (block6 >>> 52));
+ values[valuesOffset++] = (int) ((block6 >>> 34) & 262143L);
+ values[valuesOffset++] = (int) ((block6 >>> 16) & 262143L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 65535L) << 2) | (block7 >>> 62));
+ values[valuesOffset++] = (int) ((block7 >>> 44) & 262143L);
+ values[valuesOffset++] = (int) ((block7 >>> 26) & 262143L);
+ values[valuesOffset++] = (int) ((block7 >>> 8) & 262143L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 255L) << 10) | (block8 >>> 54));
+ values[valuesOffset++] = (int) ((block8 >>> 36) & 262143L);
+ values[valuesOffset++] = (int) ((block8 >>> 18) & 262143L);
+ values[valuesOffset++] = (int) (block8 & 262143L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPackedSingleBlock.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPackedSingleBlock.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPackedSingleBlock.java (working copy)
@@ -131,6 +131,18 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values,
+ int valuesOffset, int iterations) {
+ //if (bitsPerValue > 32) {
+ // throw new UnsupportedOperationException("Cannot decode " + bitsPerValue + "-bits values into an int[]");
+ //}
+ for (int i = 0; i < iterations; ++i) {
+ valuesOffset = decode(unsafe.getLong(address), values, valuesOffset);
+ address += 8;
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values,
int valuesOffset, int iterations) {
if (bitsPerValue > 32) {
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked8.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked8.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked8.java (working copy)
@@ -39,6 +39,17 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block = unsafe.getLong(address);
+ address += 8;
+ for (int shift = 56; shift >= 0; shift -= 8) {
+ values[valuesOffset++] = (int) ((block >>> shift) & 255);
+ }
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int j = 0; j < iterations; ++j) {
values[valuesOffset++] = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked15.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked15.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked15.java (working copy)
@@ -114,6 +114,106 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 49);
+ values[valuesOffset++] = (int) ((block0 >>> 34) & 32767L);
+ values[valuesOffset++] = (int) ((block0 >>> 19) & 32767L);
+ values[valuesOffset++] = (int) ((block0 >>> 4) & 32767L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 15L) << 11) | (block1 >>> 53));
+ values[valuesOffset++] = (int) ((block1 >>> 38) & 32767L);
+ values[valuesOffset++] = (int) ((block1 >>> 23) & 32767L);
+ values[valuesOffset++] = (int) ((block1 >>> 8) & 32767L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 255L) << 7) | (block2 >>> 57));
+ values[valuesOffset++] = (int) ((block2 >>> 42) & 32767L);
+ values[valuesOffset++] = (int) ((block2 >>> 27) & 32767L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 32767L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 4095L) << 3) | (block3 >>> 61));
+ values[valuesOffset++] = (int) ((block3 >>> 46) & 32767L);
+ values[valuesOffset++] = (int) ((block3 >>> 31) & 32767L);
+ values[valuesOffset++] = (int) ((block3 >>> 16) & 32767L);
+ values[valuesOffset++] = (int) ((block3 >>> 1) & 32767L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 1L) << 14) | (block4 >>> 50));
+ values[valuesOffset++] = (int) ((block4 >>> 35) & 32767L);
+ values[valuesOffset++] = (int) ((block4 >>> 20) & 32767L);
+ values[valuesOffset++] = (int) ((block4 >>> 5) & 32767L);
+ final long block5 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block4 & 31L) << 10) | (block5 >>> 54));
+ values[valuesOffset++] = (int) ((block5 >>> 39) & 32767L);
+ values[valuesOffset++] = (int) ((block5 >>> 24) & 32767L);
+ values[valuesOffset++] = (int) ((block5 >>> 9) & 32767L);
+ final long block6 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block5 & 511L) << 6) | (block6 >>> 58));
+ values[valuesOffset++] = (int) ((block6 >>> 43) & 32767L);
+ values[valuesOffset++] = (int) ((block6 >>> 28) & 32767L);
+ values[valuesOffset++] = (int) ((block6 >>> 13) & 32767L);
+ final long block7 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block6 & 8191L) << 2) | (block7 >>> 62));
+ values[valuesOffset++] = (int) ((block7 >>> 47) & 32767L);
+ values[valuesOffset++] = (int) ((block7 >>> 32) & 32767L);
+ values[valuesOffset++] = (int) ((block7 >>> 17) & 32767L);
+ values[valuesOffset++] = (int) ((block7 >>> 2) & 32767L);
+ final long block8 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block7 & 3L) << 13) | (block8 >>> 51));
+ values[valuesOffset++] = (int) ((block8 >>> 36) & 32767L);
+ values[valuesOffset++] = (int) ((block8 >>> 21) & 32767L);
+ values[valuesOffset++] = (int) ((block8 >>> 6) & 32767L);
+ final long block9 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block8 & 63L) << 9) | (block9 >>> 55));
+ values[valuesOffset++] = (int) ((block9 >>> 40) & 32767L);
+ values[valuesOffset++] = (int) ((block9 >>> 25) & 32767L);
+ values[valuesOffset++] = (int) ((block9 >>> 10) & 32767L);
+ final long block10 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block9 & 1023L) << 5) | (block10 >>> 59));
+ values[valuesOffset++] = (int) ((block10 >>> 44) & 32767L);
+ values[valuesOffset++] = (int) ((block10 >>> 29) & 32767L);
+ values[valuesOffset++] = (int) ((block10 >>> 14) & 32767L);
+ final long block11 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block10 & 16383L) << 1) | (block11 >>> 63));
+ values[valuesOffset++] = (int) ((block11 >>> 48) & 32767L);
+ values[valuesOffset++] = (int) ((block11 >>> 33) & 32767L);
+ values[valuesOffset++] = (int) ((block11 >>> 18) & 32767L);
+ values[valuesOffset++] = (int) ((block11 >>> 3) & 32767L);
+ final long block12 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block11 & 7L) << 12) | (block12 >>> 52));
+ values[valuesOffset++] = (int) ((block12 >>> 37) & 32767L);
+ values[valuesOffset++] = (int) ((block12 >>> 22) & 32767L);
+ values[valuesOffset++] = (int) ((block12 >>> 7) & 32767L);
+ final long block13 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block12 & 127L) << 8) | (block13 >>> 56));
+ values[valuesOffset++] = (int) ((block13 >>> 41) & 32767L);
+ values[valuesOffset++] = (int) ((block13 >>> 26) & 32767L);
+ values[valuesOffset++] = (int) ((block13 >>> 11) & 32767L);
+ final long block14 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block13 & 2047L) << 4) | (block14 >>> 60));
+ values[valuesOffset++] = (int) ((block14 >>> 45) & 32767L);
+ values[valuesOffset++] = (int) ((block14 >>> 30) & 32767L);
+ values[valuesOffset++] = (int) ((block14 >>> 15) & 32767L);
+ values[valuesOffset++] = (int) (block14 & 32767L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked5.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked5.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked5.java (working copy)
@@ -104,6 +104,86 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 59);
+ values[valuesOffset++] = (int) ((block0 >>> 54) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 49) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 44) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 39) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 34) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 29) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 24) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 19) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 14) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 9) & 31L);
+ values[valuesOffset++] = (int) ((block0 >>> 4) & 31L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 15L) << 1) | (block1 >>> 63));
+ values[valuesOffset++] = (int) ((block1 >>> 58) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 53) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 48) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 43) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 38) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 33) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 28) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 23) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 18) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 13) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 8) & 31L);
+ values[valuesOffset++] = (int) ((block1 >>> 3) & 31L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 7L) << 2) | (block2 >>> 62));
+ values[valuesOffset++] = (int) ((block2 >>> 57) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 52) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 47) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 42) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 37) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 32) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 27) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 22) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 17) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 7) & 31L);
+ values[valuesOffset++] = (int) ((block2 >>> 2) & 31L);
+ final long block3 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block2 & 3L) << 3) | (block3 >>> 61));
+ values[valuesOffset++] = (int) ((block3 >>> 56) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 51) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 46) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 41) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 36) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 31) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 26) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 21) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 16) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 11) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 6) & 31L);
+ values[valuesOffset++] = (int) ((block3 >>> 1) & 31L);
+ final long block4 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block3 & 1L) << 4) | (block4 >>> 60));
+ values[valuesOffset++] = (int) ((block4 >>> 55) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 50) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 45) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 40) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 35) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 30) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 25) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 20) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 15) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 10) & 31L);
+ values[valuesOffset++] = (int) ((block4 >>> 5) & 31L);
+ values[valuesOffset++] = (int) (block4 & 31L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/PackedInts.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/PackedInts.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/PackedInts.java (working copy)
@@ -350,6 +350,8 @@
*/
void decode(long[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations);
+ void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations);
+
/**
* Read 8 * iterations * blockCount() blocks from blocks,
* decode them and write iterations * valueCount() values into
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked12.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked12.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked12.java (working copy)
@@ -54,6 +54,34 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 52);
+ values[valuesOffset++] = (int) ((block0 >>> 40) & 4095L);
+ values[valuesOffset++] = (int) ((block0 >>> 28) & 4095L);
+ values[valuesOffset++] = (int) ((block0 >>> 16) & 4095L);
+ values[valuesOffset++] = (int) ((block0 >>> 4) & 4095L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 15L) << 8) | (block1 >>> 56));
+ values[valuesOffset++] = (int) ((block1 >>> 44) & 4095L);
+ values[valuesOffset++] = (int) ((block1 >>> 32) & 4095L);
+ values[valuesOffset++] = (int) ((block1 >>> 20) & 4095L);
+ values[valuesOffset++] = (int) ((block1 >>> 8) & 4095L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 255L) << 4) | (block2 >>> 60));
+ values[valuesOffset++] = (int) ((block2 >>> 48) & 4095L);
+ values[valuesOffset++] = (int) ((block2 >>> 36) & 4095L);
+ values[valuesOffset++] = (int) ((block2 >>> 24) & 4095L);
+ values[valuesOffset++] = (int) ((block2 >>> 12) & 4095L);
+ values[valuesOffset++] = (int) (block2 & 4095L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked24.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked24.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BulkOperationPacked24.java (working copy)
@@ -46,6 +46,26 @@
}
@Override
+ public void decode(long address, int blocksOffset, int[] values, int valuesOffset, int iterations) {
+ for (int i = 0; i < iterations; ++i) {
+ final long block0 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (block0 >>> 40);
+ values[valuesOffset++] = (int) ((block0 >>> 16) & 16777215L);
+ final long block1 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block0 & 65535L) << 8) | (block1 >>> 56));
+ values[valuesOffset++] = (int) ((block1 >>> 32) & 16777215L);
+ values[valuesOffset++] = (int) ((block1 >>> 8) & 16777215L);
+ final long block2 = unsafe.getLong(address);
+ address += 8;
+ values[valuesOffset++] = (int) (((block1 & 255L) << 16) | (block2 >>> 48));
+ values[valuesOffset++] = (int) ((block2 >>> 24) & 16777215L);
+ values[valuesOffset++] = (int) (block2 & 16777215L);
+ }
+ }
+
+ @Override
public void decode(byte[] blocks, int blocksOffset, int[] values, int valuesOffset, int iterations) {
for (int i = 0; i < iterations; ++i) {
final int byte0 = blocks[blocksOffset++] & 0xFF;
Index: lucene/core/src/java/org/apache/lucene/store/FSDirectory.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/store/FSDirectory.java (revision 1575909)
+++ lucene/core/src/java/org/apache/lucene/store/FSDirectory.java (working copy)
@@ -401,6 +401,11 @@
public void setLength(long length) throws IOException {
file.setLength(length);
}
+
+ @Override
+ public String toString() {
+ return "FSIndexOutput(" + name + ")";
+ }
}
protected void fsync(String name) throws IOException {
Index: lucene/core/src/java/org/apache/lucene/store/NativeMMapDirectory.cpp
===================================================================
--- lucene/core/src/java/org/apache/lucene/store/NativeMMapDirectory.cpp (revision 0)
+++ lucene/core/src/java/org/apache/lucene/store/NativeMMapDirectory.cpp (working copy)
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// To see assembly:
+//
+// g++ -fpermissive -S -O4 -o test.s -I/usr/local/src/jdk1.6.0_32/include -I/usr/local/src/jdk1.6.0_32/include/linux /l/nativebq/lucene/misc/src/java/org/apache/lucene/search/NativeSearch.cpp
+//
+
+#include
+#include
+#include
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_org_apache_lucene_store_NativeMMapDirectory_map(JNIEnv *env,
+ jclass cl,
+ jint fd, jlong fileLength) {
+ long address = (long) mmap(0, fileLength, PROT_READ, MAP_SHARED, fd, 0);
+ if (address == -1) {
+ jclass exClass = env->FindClass("java/io/IOException");
+ char buf[64];
+ sprintf(buf, "errno=%d", errno);
+ return env->ThrowNew(exClass, buf);
+ }
+ //printf("map addr=%ld len=%ld\n", address, fileLength);fflush(stdout);
+ return address;
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_org_apache_lucene_store_NativeMMapDirectory_unmap(JNIEnv *env,
+ jclass cl,
+ jlong address, jlong fileLength) {
+ munmap((void *) address, fileLength);
+ //printf("unmap addr=%ld len=%ld\n", address, fileLength);fflush(stdout);
+}
Property changes on: lucene/core/src/java/org/apache/lucene/store/NativeMMapDirectory.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/core/src/java/org/apache/lucene/store/NativeMMapDirectory.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/store/NativeMMapDirectory.java (revision 0)
+++ lucene/core/src/java/org/apache/lucene/store/NativeMMapDirectory.java (working copy)
@@ -0,0 +1,196 @@
+package org.apache.lucene.store;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.EOFException;
+import java.io.RandomAccessFile;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.reflect.*;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+
+import sun.misc.Unsafe;
+
+// nocommit fix build.xml:
+
+// export LD_LIBRARY_PATH=/l/nativemmap/lucene/core
+//
+// g++ -fPIC -O4 -shared -I/usr/local/src/jdk1.7.0_25/include -I/usr/local/src/jdk1.7.0_25/include/linux -o libNativeMMapDirectory.so src/java/org/apache/lucene/store/NativeMMapDirectory.cpp
+//
+// ant test -Dtests.directory=org.apache.lucene.store.NativeMMapDirectory -Dtests.postingsformat=NativeMMap -Dtestcase=TestDemo
+
+// pushd src/java/org/apache/lucene/util/packed; python -u gen_BulkOperation.py; popd
+
+public class NativeMMapDirectory extends FSDirectory {
+
+ static {
+ System.loadLibrary("NativeMMapDirectory");
+ }
+
+ private final static native long map(int fd, long fileLength);
+ private final static native void unmap(long address, long fileLength);
+
+ public NativeMMapDirectory(File path) throws IOException {
+ this(path, null);
+ }
+
+ public NativeMMapDirectory(File path, LockFactory lockFactory) throws IOException {
+ super(path, lockFactory);
+ }
+
+ @Override
+ public IndexInput openInput(String name, IOContext context) throws IOException {
+ ensureOpen();
+ //System.out.println("openInput name=" + name + " len=" + fileLength(name));
+ File file = new File(getDirectory(), name);
+ //try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
+ return new NativeMMapIndexInput("NativeMMapIndexInput(path=\"" + file.toString() + "\")", new RandomAccessFile(file, "r"));
+ }
+
+ @Override
+ public IndexInputSlicer createSlicer(String name, IOContext context) throws IOException {
+ final NativeMMapIndexInput full = (NativeMMapIndexInput) openInput(name, context);
+
+ return new IndexInputSlicer() {
+ @Override
+ public IndexInput openSlice(String sliceDescription, long offset, long length) throws IOException {
+ ensureOpen();
+ return new NativeMMapIndexInput(full.toString() + "[slice=" + sliceDescription + "]", full.address + offset, length, full.address + offset);
+ }
+
+ @Override
+ public void close() throws IOException {
+ full.close();
+ }
+ };
+ }
+
+ int getFileDes(FileDescriptor fd) {
+ try {
+ Class> x = Class.forName("java.io.FileDescriptor");
+ Field f = x.getDeclaredField("fd");
+ f.setAccessible(true);
+ return f.getInt(fd);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static final Unsafe unsafe;
+
+ static {
+ try {
+ Field f = Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe) f.get(null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ static final long arrayBaseOffset = (long) unsafe.arrayBaseOffset(byte[].class);
+
+ public final class NativeMMapIndexInput extends IndexInput {
+
+ private final long address;
+ private final long length;
+ private final RandomAccessFile raf;
+
+ private long pos;
+
+ NativeMMapIndexInput(String resourceDescription, RandomAccessFile raf) throws IOException {
+ super(resourceDescription);
+ this.raf = raf;
+ length = raf.length();
+ if (length == 0) {
+ // mmap gets angry if you map 0 length file:
+ address = 0;
+ } else {
+ int fd = getFileDes(raf.getFD());
+ address = map(fd, length);
+ //System.out.println("map: " + resourceDescription + " fd=" + fd + " -> address=" + address + " length=" + length);
+ }
+ pos = address;
+ }
+
+ NativeMMapIndexInput(String resourceDescription, long address, long length, long pos) {
+ super(resourceDescription);
+ raf = null;
+ this.address = address;
+ this.length = length;
+ this.pos = pos;
+ }
+
+ public long getAddress() {
+ return pos;
+ }
+
+ public void setAddress(long newPos) {
+ this.pos = newPos;
+ }
+
+ @Override
+ public long getFilePointer() {
+ return pos - address;
+ }
+
+ @Override
+ public void seek(long pos) {
+ this.pos = address + pos;
+ }
+
+ @Override
+ public long length() {
+ return length;
+ }
+
+ @Override
+ public void close() throws IOException {
+ // nocommit guard against double close
+ if (raf != null) {
+ unmap(address, length);
+ raf.close();
+ }
+ }
+
+ @Override
+ public byte readByte() throws IOException {
+ // Necessary for reading segments_N while IW is committing:
+ if (pos >= address + length) {
+ throw new EOFException();
+ }
+ return unsafe.getByte(pos++);
+ }
+
+ @Override
+ public void readBytes(byte[] b, int offset, int len) throws IOException {
+ // Necessary for reading segments_N while IW is committing:
+ if (pos + len > address + length) {
+ throw new EOFException();
+ }
+ unsafe.copyMemory(null, pos, b, arrayBaseOffset + offset, len);
+ pos += len;
+ }
+
+ @Override
+ public NativeMMapIndexInput clone() {
+ return new NativeMMapIndexInput(toString(), address, length, pos);
+ }
+ }
+}
Property changes on: lucene/core/src/java/org/apache/lucene/store/NativeMMapDirectory.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/core/src/java/org/apache/lucene/codecs/nativemmap/NativeMMapPostingsFormat.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/nativemmap/NativeMMapPostingsFormat.java (revision 0)
+++ lucene/core/src/java/org/apache/lucene/codecs/nativemmap/NativeMMapPostingsFormat.java (working copy)
@@ -0,0 +1,145 @@
+package org.apache.lucene.codecs.nativemmap;
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.lucene.codecs.BlockTreeTermsReader;
+import org.apache.lucene.codecs.BlockTreeTermsWriter;
+import org.apache.lucene.codecs.CodecUtil;
+import org.apache.lucene.codecs.FieldsConsumer;
+import org.apache.lucene.codecs.FieldsProducer;
+import org.apache.lucene.codecs.MultiLevelSkipListWriter;
+import org.apache.lucene.codecs.PostingsFormat;
+import org.apache.lucene.codecs.PostingsReaderBase;
+import org.apache.lucene.codecs.PostingsWriterBase;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.FieldInfo.IndexOptions;
+import org.apache.lucene.index.SegmentReadState;
+import org.apache.lucene.index.SegmentWriteState;
+import org.apache.lucene.store.DataOutput;
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.packed.PackedInts;
+
+// nocommit also test aligned reads
+
+/**
+ * Very similar to {@link NativeMMapPostingsFormat}, except
+ * requires that {@link NativeMMapDirectory} is used so that
+ * direct (Unsafe!) access to memory-mapped longs is
+ * possible.
+ *
+ * @lucene.experimental
+ */
+
+public final class NativeMMapPostingsFormat extends PostingsFormat {
+ /**
+ * Filename extension for document number, frequencies, and skip data.
+ * See chapter: Frequencies and Skip Data
+ */
+ public static final String DOC_EXTENSION = "doc";
+
+ /**
+ * Filename extension for positions.
+ * See chapter: Positions
+ */
+ public static final String POS_EXTENSION = "pos";
+
+ /**
+ * Filename extension for payloads and offsets.
+ * See chapter: Payloads and Offsets
+ */
+ public static final String PAY_EXTENSION = "pay";
+
+ private final int minTermBlockSize;
+ private final int maxTermBlockSize;
+
+ /**
+ * Fixed packed block size, number of integers encoded in
+ * a single packed block.
+ */
+ // NOTE: must be multiple of 64 because of PackedInts long-aligned encoding/decoding
+ public final static int BLOCK_SIZE = 128;
+
+ /** Creates {@code NativeMMapPostingsFormat} with default
+ * settings. */
+ public NativeMMapPostingsFormat() {
+ this(BlockTreeTermsWriter.DEFAULT_MIN_BLOCK_SIZE, BlockTreeTermsWriter.DEFAULT_MAX_BLOCK_SIZE);
+ }
+
+ /** Creates {@code NativeMMapPostingsFormat} with custom
+ * values for {@code minBlockSize} and {@code
+ * maxBlockSize} passed to block terms dictionary.
+ * @see BlockTreeTermsWriter#BlockTreeTermsWriter(SegmentWriteState,PostingsWriterBase,int,int) */
+ public NativeMMapPostingsFormat(int minTermBlockSize, int maxTermBlockSize) {
+ super("NativeMMap");
+ this.minTermBlockSize = minTermBlockSize;
+ assert minTermBlockSize > 1;
+ this.maxTermBlockSize = maxTermBlockSize;
+ assert minTermBlockSize <= maxTermBlockSize;
+ }
+
+ @Override
+ public String toString() {
+ return getName() + "(blocksize=" + BLOCK_SIZE + ")";
+ }
+
+ @Override
+ public FieldsConsumer fieldsConsumer(SegmentWriteState state) throws IOException {
+ PostingsWriterBase postingsWriter = new NativeMMapPostingsWriter(state);
+
+ boolean success = false;
+ try {
+ FieldsConsumer ret = new BlockTreeTermsWriter(state,
+ postingsWriter,
+ minTermBlockSize,
+ maxTermBlockSize);
+ success = true;
+ return ret;
+ } finally {
+ if (!success) {
+ IOUtils.closeWhileHandlingException(postingsWriter);
+ }
+ }
+ }
+
+ @Override
+ public FieldsProducer fieldsProducer(SegmentReadState state) throws IOException {
+ PostingsReaderBase postingsReader = new NativeMMapPostingsReader(state.directory,
+ state.fieldInfos,
+ state.segmentInfo,
+ state.context,
+ state.segmentSuffix);
+ boolean success = false;
+ try {
+ FieldsProducer ret = new BlockTreeTermsReader(state.directory,
+ state.fieldInfos,
+ state.segmentInfo,
+ postingsReader,
+ state.context,
+ state.segmentSuffix);
+ success = true;
+ return ret;
+ } finally {
+ if (!success) {
+ IOUtils.closeWhileHandlingException(postingsReader);
+ }
+ }
+ }
+}
Property changes on: lucene/core/src/java/org/apache/lucene/codecs/nativemmap/NativeMMapPostingsFormat.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/core/src/java/org/apache/lucene/codecs/nativemmap/ForUtil.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/nativemmap/ForUtil.java (revision 0)
+++ lucene/core/src/java/org/apache/lucene/codecs/nativemmap/ForUtil.java (working copy)
@@ -0,0 +1,274 @@
+package org.apache.lucene.codecs.nativemmap;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.lucene.store.DataInput;
+import org.apache.lucene.store.DataOutput;
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.store.NativeMMapDirectory.NativeMMapIndexInput;
+import org.apache.lucene.util.packed.PackedInts.Decoder;
+import org.apache.lucene.util.packed.PackedInts.FormatAndBits;
+import org.apache.lucene.util.packed.PackedInts;
+
+import static org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat.BLOCK_SIZE;
+
+/**
+ * Encode all values in normal area with fixed bit width,
+ * which is determined by the max value in this block.
+ */
+final class ForUtil {
+
+ /**
+ * Special number of bits per value used whenever all values to encode are equal.
+ */
+ private static final int ALL_VALUES_EQUAL = 0;
+
+ /**
+ * Upper limit of the number of bytes that might be required to stored
+ * BLOCK_SIZE encoded values.
+ */
+ static final int MAX_ENCODED_SIZE = BLOCK_SIZE * 4;
+
+ /**
+ * Upper limit of the number of values that might be decoded in a single call to
+ * {@link #readBlock(IndexInput, byte[], int[])}. Although values after
+ * BLOCK_SIZE are garbage, it is necessary to allocate value buffers
+ * whose size is >= MAX_DATA_SIZE to avoid {@link ArrayIndexOutOfBoundsException}s.
+ */
+ static final int MAX_DATA_SIZE;
+ static {
+ int maxDataSize = 0;
+ for(int version=PackedInts.VERSION_START;version<=PackedInts.VERSION_CURRENT;version++) {
+ for (PackedInts.Format format : PackedInts.Format.values()) {
+ for (int bpv = 1; bpv <= 32; ++bpv) {
+ if (!format.isSupported(bpv)) {
+ continue;
+ }
+ final PackedInts.Decoder decoder = PackedInts.getDecoder(format, version, bpv);
+ final int iterations = computeIterations(decoder);
+ maxDataSize = Math.max(maxDataSize, iterations * decoder.byteValueCount());
+ }
+ }
+ }
+ MAX_DATA_SIZE = maxDataSize;
+ }
+
+ /**
+ * Compute the number of iterations required to decode BLOCK_SIZE
+ * values with the provided {@link Decoder}.
+ */
+ private static int computeIterations(PackedInts.Decoder decoder) {
+ return (int) Math.ceil((float) BLOCK_SIZE / decoder.longValueCount());
+ }
+
+ /**
+ * Compute the number of longs required to encode a block of values that require
+ * bitsPerValue bits per value with format format.
+ */
+ private static int encodedSize(PackedInts.Format format, int packedIntsVersion, int bitsPerValue) {
+ final long longCount = format.longCount(packedIntsVersion, BLOCK_SIZE, bitsPerValue);
+ assert longCount >= 0 && longCount <= Integer.MAX_VALUE : longCount;
+ return (int) longCount;
+ }
+
+ private final int[] encodedSizes;
+ private final PackedInts.Encoder[] encoders;
+ private final PackedInts.Decoder[] decoders;
+ private final int[] iterations;
+
+ /**
+ * Create a new {@link ForUtil} instance and save state into out.
+ */
+ ForUtil(float acceptableOverheadRatio, DataOutput out) throws IOException {
+ out.writeVInt(PackedInts.VERSION_CURRENT);
+ encodedSizes = new int[33];
+ encoders = new PackedInts.Encoder[33];
+ decoders = new PackedInts.Decoder[33];
+ iterations = new int[33];
+
+ for (int bpv = 1; bpv <= 32; ++bpv) {
+ final FormatAndBits formatAndBits = PackedInts.fastestFormatAndBits(
+ BLOCK_SIZE, bpv, acceptableOverheadRatio);
+ assert formatAndBits.format.isSupported(formatAndBits.bitsPerValue);
+ assert formatAndBits.bitsPerValue <= 32;
+ encodedSizes[bpv] = encodedSize(formatAndBits.format, PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue);
+ encoders[bpv] = PackedInts.getEncoder(
+ formatAndBits.format, PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue);
+ decoders[bpv] = PackedInts.getDecoder(
+ formatAndBits.format, PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue);
+ iterations[bpv] = computeIterations(decoders[bpv]);
+
+ out.writeVInt(formatAndBits.format.getId() << 5 | (formatAndBits.bitsPerValue - 1));
+ //System.out.println("bpv=" + bpv + " decoder=" + decoders[bpv]);
+ }
+ }
+
+ /**
+ * Restore a {@link ForUtil} from a {@link DataInput}.
+ */
+ ForUtil(DataInput in) throws IOException {
+ int packedIntsVersion = in.readVInt();
+ PackedInts.checkVersion(packedIntsVersion);
+ encodedSizes = new int[33];
+ encoders = new PackedInts.Encoder[33];
+ decoders = new PackedInts.Decoder[33];
+ iterations = new int[33];
+
+ for (int bpv = 1; bpv <= 32; ++bpv) {
+ final int code = in.readVInt();
+ final int formatId = code >>> 5;
+ final int bitsPerValue = (code & 31) + 1;
+
+ final PackedInts.Format format = PackedInts.Format.byId(formatId);
+ assert format.isSupported(bitsPerValue);
+ encodedSizes[bpv] = encodedSize(format, packedIntsVersion, bitsPerValue);
+ encoders[bpv] = PackedInts.getEncoder(
+ format, packedIntsVersion, bitsPerValue);
+ decoders[bpv] = PackedInts.getDecoder(
+ format, packedIntsVersion, bitsPerValue);
+ iterations[bpv] = computeIterations(decoders[bpv]);
+ //System.out.println("bpv=" + bpv + " iters=" + iterations[bpv] + " decoder=" + decoders[bpv] + " longValueCount=" + decoders[bpv].longValueCount());
+ }
+ }
+
+ /**
+ * Write a block of data (For format).
+ *
+ * @param data the data to write
+ * @param encoded a buffer to use to encode data
+ * @param out the destination output
+ * @throws IOException If there is a low-level I/O error
+ */
+ void writeBlock(int[] data, long[] encoded, IndexOutput out) throws IOException {
+ //System.out.println("ForUtil.writeBlock out=" + out + " fp=" + out.getFilePointer());
+ if (isAllEqual(data)) {
+ //System.out.println(" all equal " + data[0]);
+ out.writeByte((byte) ALL_VALUES_EQUAL);
+ out.writeVInt(data[0]);
+ return;
+ }
+
+ final int numBits = bitsRequired(data);
+ //System.out.println(" bpv=" + numBits);
+ assert numBits > 0 && numBits <= 32 : numBits;
+ final PackedInts.Encoder encoder = encoders[numBits];
+ final int iters = iterations[numBits];
+ assert iters * encoder.longValueCount() >= BLOCK_SIZE;
+ final int encodedSize = encodedSizes[numBits];
+ assert (iters * encoder.longBlockCount()) << 3 >= encodedSize;
+
+ out.writeByte((byte) numBits);
+
+ encoder.encode(data, 0, encoded, 0, iters);
+
+ // nocommit: must write longs to match CPUs endian-ness;
+ // this is hack to match x86 (little endian), opposite
+ // of DataOutput.writeLong. To do this in general we'd
+ // need to know the endianness of the processor
+ for(int i=0;iPackedInts.COMPACT */
+ public NativeMMapPostingsWriter(SegmentWriteState state) throws IOException {
+ this(state, PackedInts.COMPACT);
+ }
+
+ final static class IntBlockTermState extends BlockTermState {
+ long docStartFP = 0;
+ long posStartFP = 0;
+ long payStartFP = 0;
+ long skipOffset = -1;
+ long lastPosBlockOffset = -1;
+ // docid when there is a single pulsed posting, otherwise -1
+ // freq is always implicitly totalTermFreq in this case.
+ int singletonDocID = -1;
+
+ @Override
+ public IntBlockTermState clone() {
+ IntBlockTermState other = new IntBlockTermState();
+ other.copyFrom(this);
+ return other;
+ }
+
+ @Override
+ public void copyFrom(TermState _other) {
+ super.copyFrom(_other);
+ IntBlockTermState other = (IntBlockTermState) _other;
+ docStartFP = other.docStartFP;
+ posStartFP = other.posStartFP;
+ payStartFP = other.payStartFP;
+ lastPosBlockOffset = other.lastPosBlockOffset;
+ skipOffset = other.skipOffset;
+ singletonDocID = other.singletonDocID;
+ }
+
+
+ @Override
+ public String toString() {
+ return super.toString() + " docStartFP=" + docStartFP + " posStartFP=" + posStartFP + " payStartFP=" + payStartFP + " lastPosBlockOffset=" + lastPosBlockOffset + " singletonDocID=" + singletonDocID;
+ }
+ }
+
+ @Override
+ public IntBlockTermState newTermState() {
+ return new IntBlockTermState();
+ }
+
+ @Override
+ public void init(IndexOutput termsOut) throws IOException {
+ CodecUtil.writeHeader(termsOut, TERMS_CODEC, VERSION_CURRENT);
+ termsOut.writeVInt(BLOCK_SIZE);
+ }
+
+ @Override
+ public int setField(FieldInfo fieldInfo) {
+ super.setField(fieldInfo);
+ skipWriter.setField(writePositions, writeOffsets, writePayloads);
+ lastState = emptyState;
+ if (writePositions) {
+ if (writePayloads || writeOffsets) {
+ return 3; // doc + pos + pay FP
+ } else {
+ return 2; // doc + pos FP
+ }
+ } else {
+ return 1; // doc FP
+ }
+ }
+
+ @Override
+ public void startTerm() {
+ docStartFP = docOut.getFilePointer();
+ if (writePositions) {
+ posStartFP = posOut.getFilePointer();
+ if (writePayloads || writeOffsets) {
+ payStartFP = payOut.getFilePointer();
+ }
+ }
+ lastDocID = 0;
+ lastBlockDocID = -1;
+ // if (DEBUG) {
+ // System.out.println("FPW.startTerm startFP=" + docStartFP);
+ // }
+ skipWriter.resetSkip();
+ }
+
+ @Override
+ public void startDoc(int docID, int termDocFreq) throws IOException {
+ // if (DEBUG) {
+ // System.out.println("FPW.startDoc docID["+docBufferUpto+"]=" + docID);
+ // }
+ // Have collected a block of docs, and get a new doc.
+ // Should write skip data as well as postings list for
+ // current block.
+ if (lastBlockDocID != -1 && docBufferUpto == 0) {
+ // if (DEBUG) {
+ // System.out.println(" bufferSkip at writeBlock: lastDocID=" + lastBlockDocID + " docCount=" + (docCount-1));
+ // }
+ skipWriter.bufferSkip(lastBlockDocID, docCount, lastBlockPosFP, lastBlockPayFP, lastBlockPosBufferUpto, lastBlockPayloadByteUpto);
+ }
+
+ final int docDelta = docID - lastDocID;
+
+ if (docID < 0 || (docCount > 0 && docDelta <= 0)) {
+ throw new CorruptIndexException("docs out of order (" + docID + " <= " + lastDocID + " ) (docOut: " + docOut + ")");
+ }
+
+ docDeltaBuffer[docBufferUpto] = docDelta;
+ // if (DEBUG) {
+ // System.out.println(" docDeltaBuffer[" + docBufferUpto + "]=" + docDelta);
+ // }
+ if (writeFreqs) {
+ freqBuffer[docBufferUpto] = termDocFreq;
+ }
+ docBufferUpto++;
+ docCount++;
+
+ if (docBufferUpto == BLOCK_SIZE) {
+ // if (DEBUG) {
+ // System.out.println(" write docDelta block @ fp=" + docOut.getFilePointer());
+ // }
+ forUtil.writeBlock(docDeltaBuffer, encoded, docOut);
+ if (writeFreqs) {
+ // if (DEBUG) {
+ // System.out.println(" write freq block @ fp=" + docOut.getFilePointer());
+ // }
+ forUtil.writeBlock(freqBuffer, encoded, docOut);
+ }
+ // NOTE: don't set docBufferUpto back to 0 here;
+ // finishDoc will do so (because it needs to see that
+ // the block was filled so it can save skip data)
+ }
+
+
+ lastDocID = docID;
+ lastPosition = 0;
+ lastStartOffset = 0;
+ }
+
+ @Override
+ public void addPosition(int position, BytesRef payload, int startOffset, int endOffset) throws IOException {
+ // if (DEBUG) {
+ // System.out.println("FPW.addPosition pos=" + position + " posBufferUpto=" + posBufferUpto + (writePayloads ? " payloadByteUpto=" + payloadByteUpto: ""));
+ // }
+ posDeltaBuffer[posBufferUpto] = position - lastPosition;
+ if (writePayloads) {
+ if (payload == null || payload.length == 0) {
+ // no payload
+ payloadLengthBuffer[posBufferUpto] = 0;
+ } else {
+ payloadLengthBuffer[posBufferUpto] = payload.length;
+ if (payloadByteUpto + payload.length > payloadBytes.length) {
+ payloadBytes = ArrayUtil.grow(payloadBytes, payloadByteUpto + payload.length);
+ }
+ System.arraycopy(payload.bytes, payload.offset, payloadBytes, payloadByteUpto, payload.length);
+ payloadByteUpto += payload.length;
+ }
+ }
+
+ if (writeOffsets) {
+ assert startOffset >= lastStartOffset;
+ assert endOffset >= startOffset;
+ offsetStartDeltaBuffer[posBufferUpto] = startOffset - lastStartOffset;
+ offsetLengthBuffer[posBufferUpto] = endOffset - startOffset;
+ lastStartOffset = startOffset;
+ }
+
+ posBufferUpto++;
+ lastPosition = position;
+ if (posBufferUpto == BLOCK_SIZE) {
+ // if (DEBUG) {
+ // System.out.println(" write pos bulk block @ fp=" + posOut.getFilePointer());
+ // }
+ forUtil.writeBlock(posDeltaBuffer, encoded, posOut);
+
+ if (writePayloads) {
+ forUtil.writeBlock(payloadLengthBuffer, encoded, payOut);
+ payOut.writeVInt(payloadByteUpto);
+ payOut.writeBytes(payloadBytes, 0, payloadByteUpto);
+ payloadByteUpto = 0;
+ }
+ if (writeOffsets) {
+ forUtil.writeBlock(offsetStartDeltaBuffer, encoded, payOut);
+ forUtil.writeBlock(offsetLengthBuffer, encoded, payOut);
+ }
+ posBufferUpto = 0;
+ }
+ }
+
+ @Override
+ public void finishDoc() throws IOException {
+ // Since we don't know df for current term, we had to buffer
+ // those skip data for each block, and when a new doc comes,
+ // write them to skip file.
+ if (docBufferUpto == BLOCK_SIZE) {
+ lastBlockDocID = lastDocID;
+ if (posOut != null) {
+ if (payOut != null) {
+ lastBlockPayFP = payOut.getFilePointer();
+ }
+ lastBlockPosFP = posOut.getFilePointer();
+ lastBlockPosBufferUpto = posBufferUpto;
+ lastBlockPayloadByteUpto = payloadByteUpto;
+ }
+ // if (DEBUG) {
+ // System.out.println(" docBufferUpto="+docBufferUpto+" now get lastBlockDocID="+lastBlockDocID+" lastBlockPosFP=" + lastBlockPosFP + " lastBlockPosBufferUpto=" + lastBlockPosBufferUpto + " lastBlockPayloadByteUpto=" + lastBlockPayloadByteUpto);
+ // }
+ docBufferUpto = 0;
+ }
+ }
+
+ /** Called when we are done adding docs to this term */
+ @Override
+ public void finishTerm(BlockTermState _state) throws IOException {
+ IntBlockTermState state = (IntBlockTermState) _state;
+ assert state.docFreq > 0;
+
+ // TODO: wasteful we are counting this (counting # docs
+ // for this term) in two places?
+ assert state.docFreq == docCount: state.docFreq + " vs " + docCount;
+
+ // if (DEBUG) {
+ // System.out.println("FPW.finishTerm docFreq=" + state.docFreq);
+ // }
+
+ // if (DEBUG) {
+ // if (docBufferUpto > 0) {
+ // System.out.println(" write doc/freq vInt block (count=" + docBufferUpto + ") at fp=" + docOut.getFilePointer() + " docStartFP=" + docStartFP);
+ // }
+ // }
+
+ // docFreq == 1, don't write the single docid/freq to a separate file along with a pointer to it.
+ final int singletonDocID;
+ if (state.docFreq == 1) {
+ // pulse the singleton docid into the term dictionary, freq is implicitly totalTermFreq
+ singletonDocID = docDeltaBuffer[0];
+ } else {
+ singletonDocID = -1;
+ // vInt encode the remaining doc deltas and freqs:
+ for(int i=0;i 0) {
+ // System.out.println(" write pos vInt block (count=" + posBufferUpto + ") at fp=" + posOut.getFilePointer() + " posStartFP=" + posStartFP + " hasPayloads=" + writePayloads + " hasOffsets=" + writeOffsets);
+ // }
+ // }
+
+ // totalTermFreq is just total number of positions(or payloads, or offsets)
+ // associated with current term.
+ assert state.totalTermFreq != -1;
+ if (state.totalTermFreq > BLOCK_SIZE) {
+ // record file offset for last pos in last block
+ lastPosBlockOffset = posOut.getFilePointer() - posStartFP;
+ } else {
+ lastPosBlockOffset = -1;
+ }
+ if (posBufferUpto > 0) {
+ // TODO: should we send offsets/payloads to
+ // .pay...? seems wasteful (have to store extra
+ // vLong for low (< BLOCK_SIZE) DF terms = vast vast
+ // majority)
+
+ // vInt encode the remaining positions/payloads/offsets:
+ int lastPayloadLength = -1; // force first payload length to be written
+ int lastOffsetLength = -1; // force first offset length to be written
+ int payloadBytesReadUpto = 0;
+ for(int i=0;i>> 1;
+ if ((code & 1) != 0) {
+ freqBuffer[i] = 1;
+ } else {
+ freqBuffer[i] = docIn.readVInt();
+ }
+ }
+ } else {
+ for(int i=0;i= 0;
+ final boolean fieldHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+ final boolean fieldHasPayloads = fieldInfo.hasPayloads();
+
+ if (absolute) {
+ termState.docStartFP = 0;
+ termState.posStartFP = 0;
+ termState.payStartFP = 0;
+ }
+ if (version < NativeMMapPostingsWriter.VERSION_META_ARRAY) { // backward compatibility
+ _decodeTerm(in, fieldInfo, termState);
+ return;
+ }
+ termState.docStartFP += longs[0];
+ if (fieldHasPositions) {
+ termState.posStartFP += longs[1];
+ if (fieldHasOffsets || fieldHasPayloads) {
+ termState.payStartFP += longs[2];
+ }
+ }
+ if (termState.docFreq == 1) {
+ termState.singletonDocID = in.readVInt();
+ } else {
+ termState.singletonDocID = -1;
+ }
+ if (fieldHasPositions) {
+ if (termState.totalTermFreq > BLOCK_SIZE) {
+ termState.lastPosBlockOffset = in.readVLong();
+ } else {
+ termState.lastPosBlockOffset = -1;
+ }
+ }
+ if (termState.docFreq > BLOCK_SIZE) {
+ termState.skipOffset = in.readVLong();
+ } else {
+ termState.skipOffset = -1;
+ }
+ }
+ private void _decodeTerm(DataInput in, FieldInfo fieldInfo, IntBlockTermState termState) throws IOException {
+ final boolean fieldHasPositions = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
+ final boolean fieldHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+ final boolean fieldHasPayloads = fieldInfo.hasPayloads();
+ if (termState.docFreq == 1) {
+ termState.singletonDocID = in.readVInt();
+ } else {
+ termState.singletonDocID = -1;
+ termState.docStartFP += in.readVLong();
+ }
+ if (fieldHasPositions) {
+ termState.posStartFP += in.readVLong();
+ if (termState.totalTermFreq > BLOCK_SIZE) {
+ termState.lastPosBlockOffset = in.readVLong();
+ } else {
+ termState.lastPosBlockOffset = -1;
+ }
+ if ((fieldHasPayloads || fieldHasOffsets) && termState.totalTermFreq >= BLOCK_SIZE) {
+ termState.payStartFP += in.readVLong();
+ }
+ }
+ if (termState.docFreq > BLOCK_SIZE) {
+ termState.skipOffset = in.readVLong();
+ } else {
+ termState.skipOffset = -1;
+ }
+ }
+
+ @Override
+ public DocsEnum docs(FieldInfo fieldInfo, BlockTermState termState, Bits liveDocs, DocsEnum reuse, int flags) throws IOException {
+ BlockDocsEnum docsEnum;
+ if (reuse instanceof BlockDocsEnum) {
+ docsEnum = (BlockDocsEnum) reuse;
+ if (!docsEnum.canReuse(docIn, fieldInfo)) {
+ docsEnum = new BlockDocsEnum(fieldInfo);
+ }
+ } else {
+ docsEnum = new BlockDocsEnum(fieldInfo);
+ }
+ return docsEnum.reset(liveDocs, (IntBlockTermState) termState, flags);
+ }
+
+ // TODO: specialize to liveDocs vs not
+
+ @Override
+ public DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, BlockTermState termState, Bits liveDocs,
+ DocsAndPositionsEnum reuse, int flags)
+ throws IOException {
+
+ boolean indexHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+ boolean indexHasPayloads = fieldInfo.hasPayloads();
+
+ if ((!indexHasOffsets || (flags & DocsAndPositionsEnum.FLAG_OFFSETS) == 0) &&
+ (!indexHasPayloads || (flags & DocsAndPositionsEnum.FLAG_PAYLOADS) == 0)) {
+ BlockDocsAndPositionsEnum docsAndPositionsEnum;
+ if (reuse instanceof BlockDocsAndPositionsEnum) {
+ docsAndPositionsEnum = (BlockDocsAndPositionsEnum) reuse;
+ if (!docsAndPositionsEnum.canReuse(docIn, fieldInfo)) {
+ docsAndPositionsEnum = new BlockDocsAndPositionsEnum(fieldInfo);
+ }
+ } else {
+ docsAndPositionsEnum = new BlockDocsAndPositionsEnum(fieldInfo);
+ }
+ return docsAndPositionsEnum.reset(liveDocs, (IntBlockTermState) termState);
+ } else {
+ EverythingEnum everythingEnum;
+ if (reuse instanceof EverythingEnum) {
+ everythingEnum = (EverythingEnum) reuse;
+ if (!everythingEnum.canReuse(docIn, fieldInfo)) {
+ everythingEnum = new EverythingEnum(fieldInfo);
+ }
+ } else {
+ everythingEnum = new EverythingEnum(fieldInfo);
+ }
+ return everythingEnum.reset(liveDocs, (IntBlockTermState) termState, flags);
+ }
+ }
+
+ final class BlockDocsEnum extends DocsEnum {
+
+ private final int[] docDeltaBuffer = new int[MAX_DATA_SIZE];
+ private final int[] freqBuffer = new int[MAX_DATA_SIZE];
+
+ private int docBufferUpto;
+
+ private NativeMMapSkipReader skipper;
+ private boolean skipped;
+
+ final IndexInput startDocIn;
+
+ NativeMMapIndexInput docIn;
+ final boolean indexHasFreq;
+ final boolean indexHasPos;
+ final boolean indexHasOffsets;
+ final boolean indexHasPayloads;
+
+ private int docFreq; // number of docs in this posting list
+ private long totalTermFreq; // sum of freqs in this posting list (or docFreq when omitted)
+ private int docUpto; // how many docs we've read
+ private int doc; // doc we last read
+ private int accum; // accumulator for doc deltas
+ private int freq; // freq we last read
+
+ // Where this term's postings start in the .doc file:
+ private long docTermStartFP;
+
+ // Where this term's skip data starts (after
+ // docTermStartFP) in the .doc file (or -1 if there is
+ // no skip data for this term):
+ private long skipOffset;
+
+ // docID for next skip point, we won't use skipper if
+ // target docID is not larger than this
+ private int nextSkipDoc;
+
+ private Bits liveDocs;
+
+ private boolean needsFreq; // true if the caller actually needs frequencies
+ private int singletonDocID; // docid when there is a single pulsed posting, otherwise -1
+
+ public BlockDocsEnum(FieldInfo fieldInfo) throws IOException {
+ this.startDocIn = NativeMMapPostingsReader.this.docIn;
+ this.docIn = null;
+ indexHasFreq = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) >= 0;
+ indexHasPos = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
+ indexHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+ indexHasPayloads = fieldInfo.hasPayloads();
+ }
+
+ public boolean canReuse(IndexInput docIn, FieldInfo fieldInfo) {
+ return docIn == startDocIn &&
+ indexHasFreq == (fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) >= 0) &&
+ indexHasPos == (fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0) &&
+ indexHasPayloads == fieldInfo.hasPayloads();
+ }
+
+ public DocsEnum reset(Bits liveDocs, IntBlockTermState termState, int flags) throws IOException {
+ this.liveDocs = liveDocs;
+ // if (DEBUG) {
+ // System.out.println(" FPR.reset: termState=" + termState);
+ // }
+ docFreq = termState.docFreq;
+ totalTermFreq = indexHasFreq ? termState.totalTermFreq : docFreq;
+ docTermStartFP = termState.docStartFP;
+ skipOffset = termState.skipOffset;
+ singletonDocID = termState.singletonDocID;
+ if (docFreq > 1) {
+ if (docIn == null) {
+ // lazy init
+ docIn = (NativeMMapIndexInput) startDocIn.clone();
+ }
+ docIn.seek(docTermStartFP);
+ }
+
+ doc = -1;
+ this.needsFreq = (flags & DocsEnum.FLAG_FREQS) != 0;
+ if (!indexHasFreq) {
+ Arrays.fill(freqBuffer, 1);
+ }
+ accum = 0;
+ docUpto = 0;
+ nextSkipDoc = BLOCK_SIZE - 1; // we won't skip if target is found in first block
+ docBufferUpto = BLOCK_SIZE;
+ skipped = false;
+ return this;
+ }
+
+ @Override
+ public int freq() throws IOException {
+ return freq;
+ }
+
+ @Override
+ public int docID() {
+ return doc;
+ }
+
+ private void refillDocs() throws IOException {
+ final int left = docFreq - docUpto;
+ assert left > 0;
+
+ if (left >= BLOCK_SIZE) {
+ // if (DEBUG) {
+ // System.out.println(" fill doc block from fp=" + docIn.getFilePointer());
+ // }
+ forUtil.readBlock(docIn, docDeltaBuffer);
+
+ if (indexHasFreq) {
+ // if (DEBUG) {
+ // System.out.println(" fill freq block from fp=" + docIn.getFilePointer());
+ // }
+ if (needsFreq) {
+ forUtil.readBlock(docIn, freqBuffer);
+ } else {
+ forUtil.skipBlock(docIn); // skip over freqs
+ }
+ }
+ } else if (docFreq == 1) {
+ docDeltaBuffer[0] = singletonDocID;
+ freqBuffer[0] = (int) totalTermFreq;
+ } else {
+ // Read vInts:
+ // if (DEBUG) {
+ // System.out.println(" fill last vInt block from fp=" + docIn.getFilePointer());
+ // }
+ readVIntBlock(docIn, docDeltaBuffer, freqBuffer, left, indexHasFreq);
+ }
+ docBufferUpto = 0;
+ }
+
+ @Override
+ public int nextDoc() throws IOException {
+ // if (DEBUG) {
+ // System.out.println("\nFPR.nextDoc");
+ // }
+ while (true) {
+ // if (DEBUG) {
+ // System.out.println(" docUpto=" + docUpto + " (of df=" + docFreq + ") docBufferUpto=" + docBufferUpto);
+ // }
+
+ if (docUpto == docFreq) {
+ // if (DEBUG) {
+ // System.out.println(" return doc=END");
+ // }
+ return doc = NO_MORE_DOCS;
+ }
+ if (docBufferUpto == BLOCK_SIZE) {
+ refillDocs();
+ }
+
+ // if (DEBUG) {
+ // System.out.println(" accum=" + accum + " docDeltaBuffer[" + docBufferUpto + "]=" + docDeltaBuffer[docBufferUpto]);
+ // }
+ accum += docDeltaBuffer[docBufferUpto];
+ docUpto++;
+
+ if (liveDocs == null || liveDocs.get(accum)) {
+ doc = accum;
+ freq = freqBuffer[docBufferUpto];
+ docBufferUpto++;
+ // if (DEBUG) {
+ // System.out.println(" return doc=" + doc + " freq=" + freq);
+ // }
+ return doc;
+ }
+ // if (DEBUG) {
+ // System.out.println(" doc=" + accum + " is deleted; try next doc");
+ // }
+ docBufferUpto++;
+ }
+ }
+
+ @Override
+ public int advance(int target) throws IOException {
+ // TODO: make frq block load lazy/skippable
+ // if (DEBUG) {
+ // System.out.println(" FPR.advance target=" + target);
+ // }
+
+ // current skip docID < docIDs generated from current buffer <= next skip docID
+ // we don't need to skip if target is buffered already
+ if (docFreq > BLOCK_SIZE && target > nextSkipDoc) {
+
+ // if (DEBUG) {
+ // System.out.println("load skipper");
+ // }
+
+ if (skipper == null) {
+ // Lazy init: first time this enum has ever been used for skipping
+ skipper = new NativeMMapSkipReader(docIn.clone(),
+ NativeMMapPostingsWriter.maxSkipLevels,
+ BLOCK_SIZE,
+ indexHasPos,
+ indexHasOffsets,
+ indexHasPayloads);
+ }
+
+ if (!skipped) {
+ assert skipOffset != -1;
+ // This is the first time this enum has skipped
+ // since reset() was called; load the skip data:
+ skipper.init(docTermStartFP+skipOffset, docTermStartFP, 0, 0, docFreq);
+ skipped = true;
+ }
+
+ // always plus one to fix the result, since skip position in NativeMMapSkipReader
+ // is a little different from MultiLevelSkipListReader
+ final int newDocUpto = skipper.skipTo(target) + 1;
+
+ if (newDocUpto > docUpto) {
+ // Skipper moved
+ // if (DEBUG) {
+ // System.out.println("skipper moved to docUpto=" + newDocUpto + " vs current=" + docUpto + "; docID=" + skipper.getDoc() + " fp=" + skipper.getDocPointer());
+ // }
+ assert newDocUpto % BLOCK_SIZE == 0 : "got " + newDocUpto;
+ docUpto = newDocUpto;
+
+ // Force to read next block
+ docBufferUpto = BLOCK_SIZE;
+ accum = skipper.getDoc(); // actually, this is just lastSkipEntry
+ docIn.seek(skipper.getDocPointer()); // now point to the block we want to search
+ }
+ // next time we call advance, this is used to
+ // foresee whether skipper is necessary.
+ nextSkipDoc = skipper.getNextSkipDoc();
+ }
+ if (docUpto == docFreq) {
+ return doc = NO_MORE_DOCS;
+ }
+ if (docBufferUpto == BLOCK_SIZE) {
+ refillDocs();
+ }
+
+ // Now scan... this is an inlined/pared down version
+ // of nextDoc():
+ while (true) {
+ // if (DEBUG) {
+ // System.out.println(" scan doc=" + accum + " docBufferUpto=" + docBufferUpto);
+ // }
+ accum += docDeltaBuffer[docBufferUpto];
+ docUpto++;
+
+ if (accum >= target) {
+ break;
+ }
+ docBufferUpto++;
+ if (docUpto == docFreq) {
+ return doc = NO_MORE_DOCS;
+ }
+ }
+
+ if (liveDocs == null || liveDocs.get(accum)) {
+ // if (DEBUG) {
+ // System.out.println(" return doc=" + accum);
+ // }
+ freq = freqBuffer[docBufferUpto];
+ docBufferUpto++;
+ return doc = accum;
+ } else {
+ // if (DEBUG) {
+ // System.out.println(" now do nextDoc()");
+ // }
+ docBufferUpto++;
+ return nextDoc();
+ }
+ }
+
+ @Override
+ public long cost() {
+ return docFreq;
+ }
+ }
+
+
+ final class BlockDocsAndPositionsEnum extends DocsAndPositionsEnum {
+
+ private final int[] docDeltaBuffer = new int[MAX_DATA_SIZE];
+ private final int[] freqBuffer = new int[MAX_DATA_SIZE];
+ private final int[] posDeltaBuffer = new int[MAX_DATA_SIZE];
+
+ private int docBufferUpto;
+ private int posBufferUpto;
+
+ private NativeMMapSkipReader skipper;
+ private boolean skipped;
+
+ final IndexInput startDocIn;
+
+ NativeMMapIndexInput docIn;
+ final NativeMMapIndexInput posIn;
+
+ final boolean indexHasOffsets;
+ final boolean indexHasPayloads;
+
+ private int docFreq; // number of docs in this posting list
+ private long totalTermFreq; // number of positions in this posting list
+ private int docUpto; // how many docs we've read
+ private int doc; // doc we last read
+ private int accum; // accumulator for doc deltas
+ private int freq; // freq we last read
+ private int position; // current position
+
+ // how many positions "behind" we are; nextPosition must
+ // skip these to "catch up":
+ private int posPendingCount;
+
+ // Lazy pos seek: if != -1 then we must seek to this FP
+ // before reading positions:
+ private long posPendingFP;
+
+ // Where this term's postings start in the .doc file:
+ private long docTermStartFP;
+
+ // Where this term's postings start in the .pos file:
+ private long posTermStartFP;
+
+ // Where this term's payloads/offsets start in the .pay
+ // file:
+ private long payTermStartFP;
+
+ // File pointer where the last (vInt encoded) pos delta
+ // block is. We need this to know whether to bulk
+ // decode vs vInt decode the block:
+ private long lastPosBlockFP;
+
+ // Where this term's skip data starts (after
+ // docTermStartFP) in the .doc file (or -1 if there is
+ // no skip data for this term):
+ private long skipOffset;
+
+ private int nextSkipDoc;
+
+ private Bits liveDocs;
+ private int singletonDocID; // docid when there is a single pulsed posting, otherwise -1
+
+ public BlockDocsAndPositionsEnum(FieldInfo fieldInfo) throws IOException {
+ this.startDocIn = NativeMMapPostingsReader.this.docIn;
+ this.docIn = null;
+ this.posIn = (NativeMMapIndexInput) NativeMMapPostingsReader.this.posIn.clone();
+ indexHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+ indexHasPayloads = fieldInfo.hasPayloads();
+ }
+
+ public boolean canReuse(IndexInput docIn, FieldInfo fieldInfo) {
+ return docIn == startDocIn &&
+ indexHasOffsets == (fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0) &&
+ indexHasPayloads == fieldInfo.hasPayloads();
+ }
+
+ public DocsAndPositionsEnum reset(Bits liveDocs, IntBlockTermState termState) throws IOException {
+ this.liveDocs = liveDocs;
+ // if (DEBUG) {
+ // System.out.println(" FPR.reset: termState=" + termState);
+ // }
+ docFreq = termState.docFreq;
+ docTermStartFP = termState.docStartFP;
+ posTermStartFP = termState.posStartFP;
+ payTermStartFP = termState.payStartFP;
+ skipOffset = termState.skipOffset;
+ totalTermFreq = termState.totalTermFreq;
+ singletonDocID = termState.singletonDocID;
+ if (docFreq > 1) {
+ if (docIn == null) {
+ // lazy init
+ docIn = (NativeMMapIndexInput) startDocIn.clone();
+ }
+ docIn.seek(docTermStartFP);
+ }
+ posPendingFP = posTermStartFP;
+ posPendingCount = 0;
+ if (termState.totalTermFreq < BLOCK_SIZE) {
+ lastPosBlockFP = posTermStartFP;
+ } else if (termState.totalTermFreq == BLOCK_SIZE) {
+ lastPosBlockFP = -1;
+ } else {
+ lastPosBlockFP = posTermStartFP + termState.lastPosBlockOffset;
+ }
+
+ doc = -1;
+ accum = 0;
+ docUpto = 0;
+ nextSkipDoc = BLOCK_SIZE - 1;
+ docBufferUpto = BLOCK_SIZE;
+ skipped = false;
+ return this;
+ }
+
+ @Override
+ public int freq() throws IOException {
+ return freq;
+ }
+
+ @Override
+ public int docID() {
+ return doc;
+ }
+
+ private void refillDocs() throws IOException {
+ final int left = docFreq - docUpto;
+ assert left > 0;
+
+ if (left >= BLOCK_SIZE) {
+ // if (DEBUG) {
+ // System.out.println(" fill doc block from fp=" + docIn.getFilePointer());
+ // }
+ forUtil.readBlock(docIn, docDeltaBuffer);
+ // if (DEBUG) {
+ // System.out.println(" fill freq block from fp=" + docIn.getFilePointer());
+ // }
+ forUtil.readBlock(docIn, freqBuffer);
+ } else if (docFreq == 1) {
+ docDeltaBuffer[0] = singletonDocID;
+ freqBuffer[0] = (int) totalTermFreq;
+ } else {
+ // Read vInts:
+ // if (DEBUG) {
+ // System.out.println(" fill last vInt doc block from fp=" + docIn.getFilePointer());
+ // }
+ readVIntBlock(docIn, docDeltaBuffer, freqBuffer, left, true);
+ }
+ docBufferUpto = 0;
+ }
+
+ private void refillPositions() throws IOException {
+ // if (DEBUG) {
+ // System.out.println(" refillPositions");
+ // }
+ if (posIn.getFilePointer() == lastPosBlockFP) {
+ // if (DEBUG) {
+ // System.out.println(" vInt pos block @ fp=" + posIn.getFilePointer() + " hasPayloads=" + indexHasPayloads + " hasOffsets=" + indexHasOffsets);
+ // }
+ final int count = (int) (totalTermFreq % BLOCK_SIZE);
+ int payloadLength = 0;
+ for(int i=0;i>> 1;
+ if (payloadLength != 0) {
+ posIn.seek(posIn.getFilePointer() + payloadLength);
+ }
+ } else {
+ posDeltaBuffer[i] = code;
+ }
+ if (indexHasOffsets) {
+ if ((posIn.readVInt() & 1) != 0) {
+ // offset length changed
+ posIn.readVInt();
+ }
+ }
+ }
+ } else {
+ // if (DEBUG) {
+ // System.out.println(" bulk pos block @ fp=" + posIn.getFilePointer());
+ // }
+ forUtil.readBlock(posIn, posDeltaBuffer);
+ }
+ }
+
+ @Override
+ public int nextDoc() throws IOException {
+ // if (DEBUG) {
+ // System.out.println(" FPR.nextDoc");
+ // }
+ while (true) {
+ // if (DEBUG) {
+ // System.out.println(" docUpto=" + docUpto + " (of df=" + docFreq + ") docBufferUpto=" + docBufferUpto);
+ // }
+ if (docUpto == docFreq) {
+ return doc = NO_MORE_DOCS;
+ }
+ if (docBufferUpto == BLOCK_SIZE) {
+ refillDocs();
+ }
+ // if (DEBUG) {
+ // System.out.println(" accum=" + accum + " docDeltaBuffer[" + docBufferUpto + "]=" + docDeltaBuffer[docBufferUpto]);
+ // }
+ accum += docDeltaBuffer[docBufferUpto];
+ freq = freqBuffer[docBufferUpto];
+ posPendingCount += freq;
+ docBufferUpto++;
+ docUpto++;
+
+ if (liveDocs == null || liveDocs.get(accum)) {
+ doc = accum;
+ position = 0;
+ // if (DEBUG) {
+ // System.out.println(" return doc=" + doc + " freq=" + freq + " posPendingCount=" + posPendingCount);
+ // }
+ return doc;
+ }
+ // if (DEBUG) {
+ // System.out.println(" doc=" + accum + " is deleted; try next doc");
+ // }
+ }
+ }
+
+ @Override
+ public int advance(int target) throws IOException {
+ // TODO: make frq block load lazy/skippable
+ // if (DEBUG) {
+ // System.out.println(" FPR.advance target=" + target);
+ // }
+
+ if (docFreq > BLOCK_SIZE && target > nextSkipDoc) {
+ // if (DEBUG) {
+ // System.out.println(" try skipper");
+ // }
+ if (skipper == null) {
+ // Lazy init: first time this enum has ever been used for skipping
+ // if (DEBUG) {
+ // System.out.println(" create skipper");
+ // }
+ skipper = new NativeMMapSkipReader(docIn.clone(),
+ NativeMMapPostingsWriter.maxSkipLevels,
+ BLOCK_SIZE,
+ true,
+ indexHasOffsets,
+ indexHasPayloads);
+ }
+
+ if (!skipped) {
+ assert skipOffset != -1;
+ // This is the first time this enum has skipped
+ // since reset() was called; load the skip data:
+ // if (DEBUG) {
+ // System.out.println(" init skipper");
+ // }
+ skipper.init(docTermStartFP+skipOffset, docTermStartFP, posTermStartFP, payTermStartFP, docFreq);
+ skipped = true;
+ }
+
+ final int newDocUpto = skipper.skipTo(target) + 1;
+
+ if (newDocUpto > docUpto) {
+ // Skipper moved
+ // if (DEBUG) {
+ // System.out.println(" skipper moved to docUpto=" + newDocUpto + " vs current=" + docUpto + "; docID=" + skipper.getDoc() + " fp=" + skipper.getDocPointer() + " pos.fp=" + skipper.getPosPointer() + " pos.bufferUpto=" + skipper.getPosBufferUpto());
+ // }
+
+ assert newDocUpto % BLOCK_SIZE == 0 : "got " + newDocUpto;
+ docUpto = newDocUpto;
+
+ // Force to read next block
+ docBufferUpto = BLOCK_SIZE;
+ accum = skipper.getDoc();
+ docIn.seek(skipper.getDocPointer());
+ posPendingFP = skipper.getPosPointer();
+ posPendingCount = skipper.getPosBufferUpto();
+ }
+ nextSkipDoc = skipper.getNextSkipDoc();
+ }
+ if (docUpto == docFreq) {
+ return doc = NO_MORE_DOCS;
+ }
+ if (docBufferUpto == BLOCK_SIZE) {
+ refillDocs();
+ }
+
+ // Now scan... this is an inlined/pared down version
+ // of nextDoc():
+ while (true) {
+ // if (DEBUG) {
+ // System.out.println(" scan doc=" + accum + " docBufferUpto=" + docBufferUpto);
+ // }
+ accum += docDeltaBuffer[docBufferUpto];
+ freq = freqBuffer[docBufferUpto];
+ posPendingCount += freq;
+ docBufferUpto++;
+ docUpto++;
+
+ if (accum >= target) {
+ break;
+ }
+ if (docUpto == docFreq) {
+ return doc = NO_MORE_DOCS;
+ }
+ }
+
+ if (liveDocs == null || liveDocs.get(accum)) {
+ // if (DEBUG) {
+ // System.out.println(" return doc=" + accum);
+ // }
+ position = 0;
+ return doc = accum;
+ } else {
+ // if (DEBUG) {
+ // System.out.println(" now do nextDoc()");
+ // }
+ return nextDoc();
+ }
+ }
+
+ // TODO: in theory we could avoid loading frq block
+ // when not needed, ie, use skip data to load how far to
+ // seek the pos pointer ... instead of having to load frq
+ // blocks only to sum up how many positions to skip
+ private void skipPositions() throws IOException {
+ // Skip positions now:
+ int toSkip = posPendingCount - freq;
+ // if (DEBUG) {
+ // System.out.println(" FPR.skipPositions: toSkip=" + toSkip);
+ // }
+
+ final int leftInBlock = BLOCK_SIZE - posBufferUpto;
+ if (toSkip < leftInBlock) {
+ posBufferUpto += toSkip;
+ // if (DEBUG) {
+ // System.out.println(" skip w/in block to posBufferUpto=" + posBufferUpto);
+ // }
+ } else {
+ toSkip -= leftInBlock;
+ while(toSkip >= BLOCK_SIZE) {
+ // if (DEBUG) {
+ // System.out.println(" skip whole block @ fp=" + posIn.getFilePointer());
+ // }
+ assert posIn.getFilePointer() != lastPosBlockFP;
+ forUtil.skipBlock(posIn);
+ toSkip -= BLOCK_SIZE;
+ }
+ refillPositions();
+ posBufferUpto = toSkip;
+ // if (DEBUG) {
+ // System.out.println(" skip w/in block to posBufferUpto=" + posBufferUpto);
+ // }
+ }
+
+ position = 0;
+ }
+
+ @Override
+ public int nextPosition() throws IOException {
+ // if (DEBUG) {
+ // System.out.println(" FPR.nextPosition posPendingCount=" + posPendingCount + " posBufferUpto=" + posBufferUpto);
+ // }
+ if (posPendingFP != -1) {
+ // if (DEBUG) {
+ // System.out.println(" seek to pendingFP=" + posPendingFP);
+ // }
+ posIn.seek(posPendingFP);
+ posPendingFP = -1;
+
+ // Force buffer refill:
+ posBufferUpto = BLOCK_SIZE;
+ }
+
+ if (posPendingCount > freq) {
+ skipPositions();
+ posPendingCount = freq;
+ }
+
+ if (posBufferUpto == BLOCK_SIZE) {
+ refillPositions();
+ posBufferUpto = 0;
+ }
+ position += posDeltaBuffer[posBufferUpto++];
+ posPendingCount--;
+ // if (DEBUG) {
+ // System.out.println(" return pos=" + position);
+ // }
+ return position;
+ }
+
+ @Override
+ public int startOffset() {
+ return -1;
+ }
+
+ @Override
+ public int endOffset() {
+ return -1;
+ }
+
+ @Override
+ public BytesRef getPayload() {
+ return null;
+ }
+
+ @Override
+ public long cost() {
+ return docFreq;
+ }
+ }
+
+ // Also handles payloads + offsets
+ final class EverythingEnum extends DocsAndPositionsEnum {
+
+ private final int[] docDeltaBuffer = new int[MAX_DATA_SIZE];
+ private final int[] freqBuffer = new int[MAX_DATA_SIZE];
+ private final int[] posDeltaBuffer = new int[MAX_DATA_SIZE];
+
+ private final int[] payloadLengthBuffer;
+ private final int[] offsetStartDeltaBuffer;
+ private final int[] offsetLengthBuffer;
+
+ private byte[] payloadBytes;
+ private int payloadByteUpto;
+ private int payloadLength;
+
+ private int lastStartOffset;
+ private int startOffset;
+ private int endOffset;
+
+ private int docBufferUpto;
+ private int posBufferUpto;
+
+ private NativeMMapSkipReader skipper;
+ private boolean skipped;
+
+ final IndexInput startDocIn;
+
+ NativeMMapIndexInput docIn;
+ final NativeMMapIndexInput posIn;
+ final NativeMMapIndexInput payIn;
+ final BytesRef payload;
+
+ final boolean indexHasOffsets;
+ final boolean indexHasPayloads;
+
+ private int docFreq; // number of docs in this posting list
+ private long totalTermFreq; // number of positions in this posting list
+ private int docUpto; // how many docs we've read
+ private int doc; // doc we last read
+ private int accum; // accumulator for doc deltas
+ private int freq; // freq we last read
+ private int position; // current position
+
+ // how many positions "behind" we are; nextPosition must
+ // skip these to "catch up":
+ private int posPendingCount;
+
+ // Lazy pos seek: if != -1 then we must seek to this FP
+ // before reading positions:
+ private long posPendingFP;
+
+ // Lazy pay seek: if != -1 then we must seek to this FP
+ // before reading payloads/offsets:
+ private long payPendingFP;
+
+ // Where this term's postings start in the .doc file:
+ private long docTermStartFP;
+
+ // Where this term's postings start in the .pos file:
+ private long posTermStartFP;
+
+ // Where this term's payloads/offsets start in the .pay
+ // file:
+ private long payTermStartFP;
+
+ // File pointer where the last (vInt encoded) pos delta
+ // block is. We need this to know whether to bulk
+ // decode vs vInt decode the block:
+ private long lastPosBlockFP;
+
+ // Where this term's skip data starts (after
+ // docTermStartFP) in the .doc file (or -1 if there is
+ // no skip data for this term):
+ private long skipOffset;
+
+ private int nextSkipDoc;
+
+ private Bits liveDocs;
+
+ private boolean needsOffsets; // true if we actually need offsets
+ private boolean needsPayloads; // true if we actually need payloads
+ private int singletonDocID; // docid when there is a single pulsed posting, otherwise -1
+
+ public EverythingEnum(FieldInfo fieldInfo) throws IOException {
+ this.startDocIn = NativeMMapPostingsReader.this.docIn;
+ this.docIn = null;
+ this.posIn = (NativeMMapIndexInput) NativeMMapPostingsReader.this.posIn.clone();
+ this.payIn = (NativeMMapIndexInput) NativeMMapPostingsReader.this.payIn.clone();
+ indexHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+ if (indexHasOffsets) {
+ offsetStartDeltaBuffer = new int[MAX_DATA_SIZE];
+ offsetLengthBuffer = new int[MAX_DATA_SIZE];
+ } else {
+ offsetStartDeltaBuffer = null;
+ offsetLengthBuffer = null;
+ startOffset = -1;
+ endOffset = -1;
+ }
+
+ indexHasPayloads = fieldInfo.hasPayloads();
+ if (indexHasPayloads) {
+ payloadLengthBuffer = new int[MAX_DATA_SIZE];
+ payloadBytes = new byte[128];
+ payload = new BytesRef();
+ } else {
+ payloadLengthBuffer = null;
+ payloadBytes = null;
+ payload = null;
+ }
+ }
+
+ public boolean canReuse(IndexInput docIn, FieldInfo fieldInfo) {
+ return docIn == startDocIn &&
+ indexHasOffsets == (fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0) &&
+ indexHasPayloads == fieldInfo.hasPayloads();
+ }
+
+ public EverythingEnum reset(Bits liveDocs, IntBlockTermState termState, int flags) throws IOException {
+ this.liveDocs = liveDocs;
+ // if (DEBUG) {
+ // System.out.println(" FPR.reset: termState=" + termState);
+ // }
+ docFreq = termState.docFreq;
+ docTermStartFP = termState.docStartFP;
+ posTermStartFP = termState.posStartFP;
+ payTermStartFP = termState.payStartFP;
+ skipOffset = termState.skipOffset;
+ totalTermFreq = termState.totalTermFreq;
+ singletonDocID = termState.singletonDocID;
+ if (docFreq > 1) {
+ if (docIn == null) {
+ // lazy init
+ docIn = (NativeMMapIndexInput) startDocIn.clone();
+ }
+ docIn.seek(docTermStartFP);
+ }
+ posPendingFP = posTermStartFP;
+ payPendingFP = payTermStartFP;
+ posPendingCount = 0;
+ if (termState.totalTermFreq < BLOCK_SIZE) {
+ lastPosBlockFP = posTermStartFP;
+ } else if (termState.totalTermFreq == BLOCK_SIZE) {
+ lastPosBlockFP = -1;
+ } else {
+ lastPosBlockFP = posTermStartFP + termState.lastPosBlockOffset;
+ }
+
+ this.needsOffsets = (flags & DocsAndPositionsEnum.FLAG_OFFSETS) != 0;
+ this.needsPayloads = (flags & DocsAndPositionsEnum.FLAG_PAYLOADS) != 0;
+
+ doc = -1;
+ accum = 0;
+ docUpto = 0;
+ nextSkipDoc = BLOCK_SIZE - 1;
+ docBufferUpto = BLOCK_SIZE;
+ skipped = false;
+ return this;
+ }
+
+ @Override
+ public int freq() throws IOException {
+ return freq;
+ }
+
+ @Override
+ public int docID() {
+ return doc;
+ }
+
+ private void refillDocs() throws IOException {
+ final int left = docFreq - docUpto;
+ assert left > 0;
+
+ if (left >= BLOCK_SIZE) {
+ // if (DEBUG) {
+ // System.out.println(" fill doc block from fp=" + docIn.getFilePointer());
+ // }
+ forUtil.readBlock(docIn, docDeltaBuffer);
+ // if (DEBUG) {
+ // System.out.println(" fill freq block from fp=" + docIn.getFilePointer());
+ // }
+ forUtil.readBlock(docIn, freqBuffer);
+ } else if (docFreq == 1) {
+ docDeltaBuffer[0] = singletonDocID;
+ freqBuffer[0] = (int) totalTermFreq;
+ } else {
+ // if (DEBUG) {
+ // System.out.println(" fill last vInt doc block from fp=" + docIn.getFilePointer());
+ // }
+ readVIntBlock(docIn, docDeltaBuffer, freqBuffer, left, true);
+ }
+ docBufferUpto = 0;
+ }
+
+ private void refillPositions() throws IOException {
+ // if (DEBUG) {
+ // System.out.println(" refillPositions");
+ // }
+ if (posIn.getFilePointer() == lastPosBlockFP) {
+ // if (DEBUG) {
+ // System.out.println(" vInt pos block @ fp=" + posIn.getFilePointer() + " hasPayloads=" + indexHasPayloads + " hasOffsets=" + indexHasOffsets);
+ // }
+ final int count = (int) (totalTermFreq % BLOCK_SIZE);
+ int payloadLength = 0;
+ int offsetLength = 0;
+ payloadByteUpto = 0;
+ for(int i=0;i docUpto) {
+ // Skipper moved
+ // if (DEBUG) {
+ // System.out.println(" skipper moved to docUpto=" + newDocUpto + " vs current=" + docUpto + "; docID=" + skipper.getDoc() + " fp=" + skipper.getDocPointer() + " pos.fp=" + skipper.getPosPointer() + " pos.bufferUpto=" + skipper.getPosBufferUpto() + " pay.fp=" + skipper.getPayPointer() + " lastStartOffset=" + lastStartOffset);
+ // }
+ assert newDocUpto % BLOCK_SIZE == 0 : "got " + newDocUpto;
+ docUpto = newDocUpto;
+
+ // Force to read next block
+ docBufferUpto = BLOCK_SIZE;
+ accum = skipper.getDoc();
+ docIn.seek(skipper.getDocPointer());
+ posPendingFP = skipper.getPosPointer();
+ payPendingFP = skipper.getPayPointer();
+ posPendingCount = skipper.getPosBufferUpto();
+ lastStartOffset = 0; // new document
+ payloadByteUpto = skipper.getPayloadByteUpto();
+ }
+ nextSkipDoc = skipper.getNextSkipDoc();
+ }
+ if (docUpto == docFreq) {
+ return doc = NO_MORE_DOCS;
+ }
+ if (docBufferUpto == BLOCK_SIZE) {
+ refillDocs();
+ }
+
+ // Now scan:
+ while (true) {
+ // if (DEBUG) {
+ // System.out.println(" scan doc=" + accum + " docBufferUpto=" + docBufferUpto);
+ // }
+ accum += docDeltaBuffer[docBufferUpto];
+ freq = freqBuffer[docBufferUpto];
+ posPendingCount += freq;
+ docBufferUpto++;
+ docUpto++;
+
+ if (accum >= target) {
+ break;
+ }
+ if (docUpto == docFreq) {
+ return doc = NO_MORE_DOCS;
+ }
+ }
+
+ if (liveDocs == null || liveDocs.get(accum)) {
+ // if (DEBUG) {
+ // System.out.println(" return doc=" + accum);
+ // }
+ position = 0;
+ lastStartOffset = 0;
+ return doc = accum;
+ } else {
+ // if (DEBUG) {
+ // System.out.println(" now do nextDoc()");
+ // }
+ return nextDoc();
+ }
+ }
+
+ // TODO: in theory we could avoid loading frq block
+ // when not needed, ie, use skip data to load how far to
+ // seek the pos pointer ... instead of having to load frq
+ // blocks only to sum up how many positions to skip
+ private void skipPositions() throws IOException {
+ // Skip positions now:
+ int toSkip = posPendingCount - freq;
+ // if (DEBUG) {
+ // System.out.println(" FPR.skipPositions: toSkip=" + toSkip);
+ // }
+
+ final int leftInBlock = BLOCK_SIZE - posBufferUpto;
+ if (toSkip < leftInBlock) {
+ int end = posBufferUpto + toSkip;
+ while(posBufferUpto < end) {
+ if (indexHasPayloads) {
+ payloadByteUpto += payloadLengthBuffer[posBufferUpto];
+ }
+ posBufferUpto++;
+ }
+ // if (DEBUG) {
+ // System.out.println(" skip w/in block to posBufferUpto=" + posBufferUpto);
+ // }
+ } else {
+ toSkip -= leftInBlock;
+ while(toSkip >= BLOCK_SIZE) {
+ // if (DEBUG) {
+ // System.out.println(" skip whole block @ fp=" + posIn.getFilePointer());
+ // }
+ assert posIn.getFilePointer() != lastPosBlockFP;
+ forUtil.skipBlock(posIn);
+
+ if (indexHasPayloads) {
+ // Skip payloadLength block:
+ forUtil.skipBlock(payIn);
+
+ // Skip payloadBytes block:
+ int numBytes = payIn.readVInt();
+ payIn.seek(payIn.getFilePointer() + numBytes);
+ }
+
+ if (indexHasOffsets) {
+ forUtil.skipBlock(payIn);
+ forUtil.skipBlock(payIn);
+ }
+ toSkip -= BLOCK_SIZE;
+ }
+ refillPositions();
+ payloadByteUpto = 0;
+ posBufferUpto = 0;
+ while(posBufferUpto < toSkip) {
+ if (indexHasPayloads) {
+ payloadByteUpto += payloadLengthBuffer[posBufferUpto];
+ }
+ posBufferUpto++;
+ }
+ // if (DEBUG) {
+ // System.out.println(" skip w/in block to posBufferUpto=" + posBufferUpto);
+ // }
+ }
+
+ position = 0;
+ lastStartOffset = 0;
+ }
+
+ @Override
+ public int nextPosition() throws IOException {
+ // if (DEBUG) {
+ // System.out.println(" FPR.nextPosition posPendingCount=" + posPendingCount + " posBufferUpto=" + posBufferUpto + " payloadByteUpto=" + payloadByteUpto)// ;
+ // }
+ if (posPendingFP != -1) {
+ // if (DEBUG) {
+ // System.out.println(" seek pos to pendingFP=" + posPendingFP);
+ // }
+ posIn.seek(posPendingFP);
+ posPendingFP = -1;
+
+ if (payPendingFP != -1) {
+ // if (DEBUG) {
+ // System.out.println(" seek pay to pendingFP=" + payPendingFP);
+ // }
+ payIn.seek(payPendingFP);
+ payPendingFP = -1;
+ }
+
+ // Force buffer refill:
+ posBufferUpto = BLOCK_SIZE;
+ }
+
+ if (posPendingCount > freq) {
+ skipPositions();
+ posPendingCount = freq;
+ }
+
+ if (posBufferUpto == BLOCK_SIZE) {
+ refillPositions();
+ posBufferUpto = 0;
+ }
+ position += posDeltaBuffer[posBufferUpto];
+
+ if (indexHasPayloads) {
+ payloadLength = payloadLengthBuffer[posBufferUpto];
+ payload.bytes = payloadBytes;
+ payload.offset = payloadByteUpto;
+ payload.length = payloadLength;
+ payloadByteUpto += payloadLength;
+ }
+
+ if (indexHasOffsets) {
+ startOffset = lastStartOffset + offsetStartDeltaBuffer[posBufferUpto];
+ endOffset = startOffset + offsetLengthBuffer[posBufferUpto];
+ lastStartOffset = startOffset;
+ }
+
+ posBufferUpto++;
+ posPendingCount--;
+ // if (DEBUG) {
+ // System.out.println(" return pos=" + position);
+ // }
+ return position;
+ }
+
+ @Override
+ public int startOffset() {
+ return startOffset;
+ }
+
+ @Override
+ public int endOffset() {
+ return endOffset;
+ }
+
+ @Override
+ public BytesRef getPayload() {
+ // if (DEBUG) {
+ // System.out.println(" FPR.getPayload payloadLength=" + payloadLength + " payloadByteUpto=" + payloadByteUpto);
+ // }
+ if (payloadLength == 0) {
+ return null;
+ } else {
+ return payload;
+ }
+ }
+
+ @Override
+ public long cost() {
+ return docFreq;
+ }
+ }
+
+ @Override
+ public long ramBytesUsed() {
+ return 0;
+ }
+
+}
Property changes on: lucene/core/src/java/org/apache/lucene/codecs/nativemmap/NativeMMapPostingsReader.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property