mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-22 01:55:47 +01:00
Make slightly more sense of CompactArrayUtil
... and make it less vanilla copy pasty The magic array is a reciprocal table of 3-tuples, although 1 and 2 are always the same but for the ones including right shifts
This commit is contained in:
parent
e0cd121a58
commit
9be32ca18b
@ -24,29 +24,28 @@ package com.viaversion.viaversion.util;
|
||||
|
||||
import java.util.function.IntToLongFunction;
|
||||
|
||||
public class CompactArrayUtil {
|
||||
//Oh no
|
||||
private static final int[] MAGIC = {
|
||||
-1, -1, 0, Integer.MIN_VALUE, 0, 0, 1431655765, 1431655765, 0, Integer.MIN_VALUE,
|
||||
0, 1, 858993459, 858993459, 0, 715827882, 715827882, 0, 613566756, 613566756,
|
||||
0, Integer.MIN_VALUE, 0, 2, 477218588, 477218588, 0, 429496729, 429496729, 0,
|
||||
390451572, 390451572, 0, 357913941, 357913941, 0, 330382099, 330382099, 0, 306783378,
|
||||
306783378, 0, 286331153, 286331153, 0, Integer.MIN_VALUE, 0, 3, 252645135, 252645135,
|
||||
0, 238609294, 238609294, 0, 226050910, 226050910, 0, 214748364, 214748364, 0,
|
||||
204522252, 204522252, 0, 195225786, 195225786, 0, 186737708, 186737708, 0, 178956970,
|
||||
178956970, 0, 171798691, 171798691, 0, 165191049, 165191049, 0, 159072862, 159072862,
|
||||
0, 153391689, 153391689, 0, 148102320, 148102320, 0, 143165576, 143165576, 0,
|
||||
138547332, 138547332, 0, Integer.MIN_VALUE, 0, 4, 130150524, 130150524, 0, 126322567,
|
||||
126322567, 0, 122713351, 122713351, 0, 119304647, 119304647, 0, 116080197, 116080197,
|
||||
0, 113025455, 113025455, 0, 110127366, 110127366, 0, 107374182, 107374182, 0,
|
||||
104755299, 104755299, 0, 102261126, 102261126, 0, 99882960, 99882960, 0, 97612893,
|
||||
97612893, 0, 95443717, 95443717, 0, 93368854, 93368854, 0, 91382282, 91382282,
|
||||
0, 89478485, 89478485, 0, 87652393, 87652393, 0, 85899345, 85899345, 0,
|
||||
84215045, 84215045, 0, 82595524, 82595524, 0, 81037118, 81037118, 0, 79536431,
|
||||
79536431, 0, 78090314, 78090314, 0, 76695844, 76695844, 0, 75350303, 75350303,
|
||||
0, 74051160, 74051160, 0, 72796055, 72796055, 0, 71582788, 71582788, 0,
|
||||
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
|
||||
0, 5};
|
||||
public final class CompactArrayUtil {
|
||||
private static final long[] RECIPROCAL_MULT_AND_ADD = {
|
||||
0xffffffffL, 0x00000000, 0x55555555, 0x00000000, 0x33333333, 0x2aaaaaaa, 0x24924924, 0x00000000,
|
||||
0x1c71c71c, 0x19999999, 0x1745d174, 0x15555555, 0x13b13b13, 0x12492492, 0x11111111, 0x00000000,
|
||||
0xf0f0f0f, 0xe38e38e, 0xd79435e, 0xccccccc, 0xc30c30c, 0xba2e8ba, 0xb21642c, 0xaaaaaaa,
|
||||
0xa3d70a3, 0x9d89d89, 0x97b425e, 0x9249249, 0x8d3dcb0, 0x8888888, 0x8421084, 0x00000000,
|
||||
0x7c1f07c, 0x7878787, 0x7507507, 0x71c71c7, 0x6eb3e45, 0x6bca1af, 0x6906906, 0x6666666,
|
||||
0x63e7063, 0x6186186, 0x5f417d0, 0x5d1745d, 0x5b05b05, 0x590b216, 0x572620a, 0x5555555,
|
||||
0x5397829, 0x51eb851, 0x5050505, 0x4ec4ec4, 0x4d4873e, 0x4bda12f, 0x4a7904a, 0x4924924,
|
||||
0x47dc11f, 0x469ee58, 0x456c797, 0x4444444, 0x4325c53, 0x4210842, 0x4104104, 0x00000000
|
||||
};
|
||||
// Incrementally shift with each 0x80000000/0x00000000 tuple
|
||||
private static final int[] RECIPROCAL_RIGHT_SHIFT = {
|
||||
0, 0, 0, 1, 0, 0, 0, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 3,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 4,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 5
|
||||
};
|
||||
|
||||
private CompactArrayUtil() {
|
||||
throw new AssertionError();
|
||||
@ -55,10 +54,10 @@ public class CompactArrayUtil {
|
||||
public static long[] createCompactArrayWithPadding(int bitsPerEntry, int entries, IntToLongFunction valueGetter) {
|
||||
long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
char valuesPerLong = (char) (64 / bitsPerEntry);
|
||||
int magicIndex = 3 * (valuesPerLong - 1);
|
||||
long divideMul = Integer.toUnsignedLong(MAGIC[magicIndex]);
|
||||
long divideAdd = Integer.toUnsignedLong(MAGIC[magicIndex + 1]);
|
||||
int divideShift = MAGIC[magicIndex + 2];
|
||||
int magicIndex = valuesPerLong - 1;
|
||||
long divideAdd = RECIPROCAL_MULT_AND_ADD[magicIndex];
|
||||
long divideMul = divideAdd != 0 ? divideAdd : 0x80000000L; // Special case for the 0x80000000/0x00000000 tuple
|
||||
int divideShift = RECIPROCAL_RIGHT_SHIFT[magicIndex];
|
||||
int size = (entries + valuesPerLong - 1) / valuesPerLong;
|
||||
|
||||
long[] data = new long[size];
|
||||
@ -76,10 +75,10 @@ public class CompactArrayUtil {
|
||||
public static void iterateCompactArrayWithPadding(int bitsPerEntry, int entries, long[] data, BiIntConsumer consumer) {
|
||||
long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
char valuesPerLong = (char) (64 / bitsPerEntry);
|
||||
int magicIndex = 3 * (valuesPerLong - 1);
|
||||
long divideMul = Integer.toUnsignedLong(MAGIC[magicIndex]);
|
||||
long divideAdd = Integer.toUnsignedLong(MAGIC[magicIndex + 1]);
|
||||
int divideShift = MAGIC[magicIndex + 2];
|
||||
int magicIndex = valuesPerLong - 1;
|
||||
long divideAdd = RECIPROCAL_MULT_AND_ADD[magicIndex];
|
||||
long divideMul = divideAdd != 0 ? divideAdd : 0x80000000L;
|
||||
int divideShift = RECIPROCAL_RIGHT_SHIFT[magicIndex];
|
||||
|
||||
for (int i = 0; i < entries; i++) {
|
||||
int cellIndex = (int) (i * divideMul + divideAdd >> 32L >> divideShift);
|
||||
|
Loading…
Reference in New Issue
Block a user