blob: 92c0d40b130f9955bf3d3df9e19542ce43e5d633 [file] [log] [blame] [raw]
package us.myles.ViaVersion.util;
import java.util.function.IntToLongFunction;
public class CompactArrayUtil {
private CompactArrayUtil() {
throw new AssertionError();
}
public static long[] createCompactArray(int bitsPerEntry, int entries, IntToLongFunction valueGetter) {
long maxEntryValue = (1L << bitsPerEntry) - 1;
long[] data = new long[(int) Math.ceil(entries * bitsPerEntry / 64.0)];
for (int index = 0; index < entries; index++) {
long value = valueGetter.applyAsLong(index);
int bitIndex = index * bitsPerEntry;
int startIndex = bitIndex / 64;
int endIndex = ((index + 1) * bitsPerEntry - 1) / 64;
int startBitSubIndex = bitIndex % 64;
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | (value & maxEntryValue) << startBitSubIndex;
if (startIndex != endIndex) {
int endBitSubIndex = 64 - startBitSubIndex;
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | (value & maxEntryValue) >> endBitSubIndex;
}
}
return data;
}
public static void iterateCompactArray(int bitsPerEntry, int entries, long[] data, BiIntConsumer consumer) {
long maxEntryValue = (1L << bitsPerEntry) - 1;
for (int i = 0; i < entries; i++) {
int bitIndex = i * bitsPerEntry;
int startIndex = bitIndex / 64;
int endIndex = ((i + 1) * bitsPerEntry - 1) / 64;
int startBitSubIndex = bitIndex % 64;
int val;
if (startIndex == endIndex) {
val = (int) (data[startIndex] >>> startBitSubIndex & maxEntryValue);
} else {
int endBitSubIndex = 64 - startBitSubIndex;
val = (int) ((data[startIndex] >>> startBitSubIndex | data[endIndex] << endBitSubIndex) & maxEntryValue);
}
consumer.consume(i, val);
}
}
}