mirror of https://github.com/apache/lucene.git
LUCENE-4062: PackedInts improvements.
* Direct64 now uses System.arraycopy for its bulk operations, * Packed64SingleBlock unnecessary optimizations have been removed. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1351682 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5f97ec3a7e
commit
831c0648f9
|
@ -24,10 +24,9 @@ import java.io.IOException;
|
|||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Direct wrapping of 32 bit values to a backing array of ints.
|
||||
* Direct wrapping of 64 bit values to a backing array of longs.
|
||||
* @lucene.internal
|
||||
*/
|
||||
|
||||
class Direct64 extends PackedInts.MutableImpl {
|
||||
private final long[] values;
|
||||
private static final int BITS_PER_VALUE = 64;
|
||||
|
@ -64,10 +63,28 @@ class Direct64 extends PackedInts.MutableImpl {
|
|||
return values[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get(int index, long[] arr, int off, int len) {
|
||||
assert index >= 0 && index < valueCount;
|
||||
assert off + len <= arr.length;
|
||||
final int gets = Math.min(valueCount - index, len);
|
||||
System.arraycopy(values, index, arr, off, gets);
|
||||
return gets;
|
||||
}
|
||||
|
||||
public void set(final int index, final long value) {
|
||||
values[index] = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int set(int index, long[] arr, int off, int len) {
|
||||
assert index >= 0 && index < valueCount;
|
||||
assert off + len <= arr.length;
|
||||
final int sets = Math.min(valueCount - index, len);
|
||||
System.arraycopy(arr, off, values, index, sets);
|
||||
return sets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(int fromIndex, int toIndex, long val) {
|
||||
Arrays.fill(values, fromIndex, toIndex, val);
|
||||
|
@ -90,4 +107,5 @@ class Direct64 extends PackedInts.MutableImpl {
|
|||
public boolean hasArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,12 +28,13 @@ import org.apache.lucene.util.RamUsageEstimator;
|
|||
* speed by ensuring that a single block needs to be read/written in order to
|
||||
* read/write a value.
|
||||
*/
|
||||
abstract class Packed64SingleBlock extends PackedInts.MutableImpl {
|
||||
final class Packed64SingleBlock extends PackedInts.MutableImpl {
|
||||
|
||||
private static final int[] SUPPORTED_BITS_PER_VALUE = new int[] {1, 2, 3, 4,
|
||||
5, 6, 7, 9, 10, 12, 21};
|
||||
private static final long[][] WRITE_MASKS = new long[22][];
|
||||
private static final int[][] SHIFTS = new int[22][];
|
||||
5, 6, 7, 8, 9, 10, 12, 16, 21, 32};
|
||||
static final int MAX_SUPPORTED_BITS_PER_VALUE = 32;
|
||||
private static final long[][] WRITE_MASKS = new long[MAX_SUPPORTED_BITS_PER_VALUE+1][];
|
||||
private static final int[][] SHIFTS = new int[MAX_SUPPORTED_BITS_PER_VALUE+1][];
|
||||
static {
|
||||
for (int bpv : SUPPORTED_BITS_PER_VALUE) {
|
||||
initMasks(bpv);
|
||||
|
@ -54,33 +55,10 @@ abstract class Packed64SingleBlock extends PackedInts.MutableImpl {
|
|||
}
|
||||
|
||||
public static Packed64SingleBlock create(int valueCount, int bitsPerValue) {
|
||||
switch (bitsPerValue) {
|
||||
case 1:
|
||||
return new Packed64SingleBlock1(valueCount);
|
||||
case 2:
|
||||
return new Packed64SingleBlock2(valueCount);
|
||||
case 3:
|
||||
return new Packed64SingleBlock3(valueCount);
|
||||
case 4:
|
||||
return new Packed64SingleBlock4(valueCount);
|
||||
case 5:
|
||||
return new Packed64SingleBlock5(valueCount);
|
||||
case 6:
|
||||
return new Packed64SingleBlock6(valueCount);
|
||||
case 7:
|
||||
return new Packed64SingleBlock7(valueCount);
|
||||
case 9:
|
||||
return new Packed64SingleBlock9(valueCount);
|
||||
case 10:
|
||||
return new Packed64SingleBlock10(valueCount);
|
||||
case 12:
|
||||
return new Packed64SingleBlock12(valueCount);
|
||||
case 21:
|
||||
return new Packed64SingleBlock21(valueCount);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported bitsPerValue: "
|
||||
+ bitsPerValue);
|
||||
if (isSupported(bitsPerValue)) {
|
||||
return new Packed64SingleBlock(valueCount, bitsPerValue);
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported bitsPerValue: " + bitsPerValue);
|
||||
}
|
||||
|
||||
public static Packed64SingleBlock create(DataInput in,
|
||||
|
@ -102,14 +80,15 @@ abstract class Packed64SingleBlock extends PackedInts.MutableImpl {
|
|||
return (float) overhead / valuesPerBlock;
|
||||
}
|
||||
|
||||
protected final long[] blocks;
|
||||
protected final int valuesPerBlock;
|
||||
protected final int[] shifts;
|
||||
protected final long[] writeMasks;
|
||||
protected final long readMask;
|
||||
final long[] blocks;
|
||||
final int valuesPerBlock;
|
||||
final int[] shifts;
|
||||
final long[] writeMasks;
|
||||
final long readMask;
|
||||
|
||||
Packed64SingleBlock(int valueCount, int bitsPerValue) {
|
||||
super(valueCount, bitsPerValue);
|
||||
assert isSupported(bitsPerValue);
|
||||
valuesPerBlock = Long.SIZE / bitsPerValue;
|
||||
blocks = new long[requiredCapacity(valueCount, valuesPerBlock)];
|
||||
shifts = SHIFTS[bitsPerValue];
|
||||
|
@ -122,11 +101,11 @@ abstract class Packed64SingleBlock extends PackedInts.MutableImpl {
|
|||
+ (valueCount % valuesPerBlock == 0 ? 0 : 1);
|
||||
}
|
||||
|
||||
protected int blockOffset(int offset) {
|
||||
private int blockOffset(int offset) {
|
||||
return offset / valuesPerBlock;
|
||||
}
|
||||
|
||||
protected int offsetInBlock(int offset) {
|
||||
private int offsetInBlock(int offset) {
|
||||
return offset % valuesPerBlock;
|
||||
}
|
||||
|
||||
|
@ -135,7 +114,7 @@ abstract class Packed64SingleBlock extends PackedInts.MutableImpl {
|
|||
final int o = blockOffset(index);
|
||||
final int b = offsetInBlock(index);
|
||||
|
||||
return (blocks[o] >> shifts[b]) & readMask;
|
||||
return (blocks[o] >>> shifts[b]) & readMask;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -295,204 +274,4 @@ abstract class Packed64SingleBlock extends PackedInts.MutableImpl {
|
|||
+ ", size=" + size() + ", elements.length=" + blocks.length + ")";
|
||||
}
|
||||
|
||||
// Specialisations that allow the JVM to optimize computation of the block
|
||||
// offset as well as the offset in block
|
||||
|
||||
static final class Packed64SingleBlock21 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock21(int valueCount) {
|
||||
super(valueCount, 21);
|
||||
assert valuesPerBlock == 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset / 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset % 3;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock12 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock12(int valueCount) {
|
||||
super(valueCount, 12);
|
||||
assert valuesPerBlock == 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset / 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset % 5;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock10 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock10(int valueCount) {
|
||||
super(valueCount, 10);
|
||||
assert valuesPerBlock == 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset / 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset % 6;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock9 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock9(int valueCount) {
|
||||
super(valueCount, 9);
|
||||
assert valuesPerBlock == 7;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset / 7;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset % 7;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock7 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock7(int valueCount) {
|
||||
super(valueCount, 7);
|
||||
assert valuesPerBlock == 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset / 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset % 9;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock6 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock6(int valueCount) {
|
||||
super(valueCount, 6);
|
||||
assert valuesPerBlock == 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset / 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset % 10;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock5 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock5(int valueCount) {
|
||||
super(valueCount, 5);
|
||||
assert valuesPerBlock == 12;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset / 12;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset % 12;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock4 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock4(int valueCount) {
|
||||
super(valueCount, 4);
|
||||
assert valuesPerBlock == 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset >> 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset & 15;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock3 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock3(int valueCount) {
|
||||
super(valueCount, 3);
|
||||
assert valuesPerBlock == 21;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset / 21;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset % 21;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock2 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock2(int valueCount) {
|
||||
super(valueCount, 2);
|
||||
assert valuesPerBlock == 32;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset >> 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset & 31;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Packed64SingleBlock1 extends Packed64SingleBlock {
|
||||
|
||||
Packed64SingleBlock1(int valueCount) {
|
||||
super(valueCount, 1);
|
||||
assert valuesPerBlock == 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int blockOffset(int offset) {
|
||||
return offset >> 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int offsetInBlock(int offset) {
|
||||
return offset & 63;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -268,7 +268,7 @@ public class TestPackedInts extends LuceneTestCase {
|
|||
packedInts.add(new Packed64(valueCount, bitsPerValue));
|
||||
}
|
||||
packedInts.add(new Direct64(valueCount));
|
||||
for (int bpv = bitsPerValue; bpv <= 64; ++bpv) {
|
||||
for (int bpv = bitsPerValue; bpv <= Packed64SingleBlock.MAX_SUPPORTED_BITS_PER_VALUE; ++bpv) {
|
||||
if (Packed64SingleBlock.isSupported(bpv)) {
|
||||
packedInts.add(Packed64SingleBlock.create(valueCount, bpv));
|
||||
}
|
||||
|
@ -463,6 +463,7 @@ public class TestPackedInts extends LuceneTestCase {
|
|||
final int gets = ints.get(index, arr, off, len);
|
||||
assertTrue(msg, gets > 0);
|
||||
assertTrue(msg, gets <= len);
|
||||
assertTrue(msg, gets <= ints.size() - index);
|
||||
|
||||
for (int i = 0; i < arr.length; ++i) {
|
||||
String m = msg + ", i=" + i;
|
||||
|
|
Loading…
Reference in New Issue