diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java b/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java index a4bbd3fa088..f2014d4213d 100644 --- a/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java +++ b/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java @@ -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; } + } diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java b/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java index 6be5510ebf9..515be19efc8 100644 --- a/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java +++ b/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java @@ -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; - } - } } \ No newline at end of file diff --git a/lucene/core/src/test/org/apache/lucene/util/packed/TestPackedInts.java b/lucene/core/src/test/org/apache/lucene/util/packed/TestPackedInts.java index 6ea803d0a66..e608c2c243b 100644 --- a/lucene/core/src/test/org/apache/lucene/util/packed/TestPackedInts.java +++ b/lucene/core/src/test/org/apache/lucene/util/packed/TestPackedInts.java @@ -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;