177 lines
7.7 KiB
Java
177 lines
7.7 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* org.apache.commons.lang3.Validate
|
|
* org.jspecify.annotations.Nullable
|
|
*/
|
|
package net.minecraft.util;
|
|
|
|
import java.util.function.IntConsumer;
|
|
import net.minecraft.util.BitStorage;
|
|
import org.apache.commons.lang3.Validate;
|
|
import org.jspecify.annotations.Nullable;
|
|
|
|
public class SimpleBitStorage
|
|
implements BitStorage {
|
|
private static final int[] MAGIC = new int[]{-1, -1, 0, Integer.MIN_VALUE, 0, 0, 0x55555555, 0x55555555, 0, Integer.MIN_VALUE, 0, 1, 0x33333333, 0x33333333, 0, 0x2AAAAAAA, 0x2AAAAAAA, 0, 0x24924924, 0x24924924, 0, Integer.MIN_VALUE, 0, 2, 0x1C71C71C, 0x1C71C71C, 0, 0x19999999, 0x19999999, 0, 390451572, 390451572, 0, 0x15555555, 0x15555555, 0, 0x13B13B13, 0x13B13B13, 0, 306783378, 306783378, 0, 0x11111111, 0x11111111, 0, Integer.MIN_VALUE, 0, 3, 0xF0F0F0F, 0xF0F0F0F, 0, 0xE38E38E, 0xE38E38E, 0, 226050910, 226050910, 0, 0xCCCCCCC, 0xCCCCCCC, 0, 0xC30C30C, 0xC30C30C, 0, 195225786, 195225786, 0, 186737708, 186737708, 0, 0xAAAAAAA, 0xAAAAAAA, 0, 171798691, 171798691, 0, 0x9D89D89, 0x9D89D89, 0, 159072862, 159072862, 0, 0x9249249, 0x9249249, 0, 148102320, 148102320, 0, 0x8888888, 0x8888888, 0, 138547332, 138547332, 0, Integer.MIN_VALUE, 0, 4, 130150524, 130150524, 0, 0x7878787, 0x7878787, 0, 0x7507507, 0x7507507, 0, 0x71C71C7, 0x71C71C7, 0, 116080197, 116080197, 0, 113025455, 113025455, 0, 0x6906906, 0x6906906, 0, 0x6666666, 0x6666666, 0, 104755299, 104755299, 0, 0x6186186, 0x6186186, 0, 99882960, 99882960, 0, 97612893, 97612893, 0, 0x5B05B05, 0x5B05B05, 0, 93368854, 93368854, 0, 91382282, 91382282, 0, 0x5555555, 0x5555555, 0, 87652393, 87652393, 0, 85899345, 85899345, 0, 0x5050505, 0x5050505, 0, 0x4EC4EC4, 0x4EC4EC4, 0, 81037118, 81037118, 0, 79536431, 79536431, 0, 78090314, 78090314, 0, 0x4924924, 0x4924924, 0, 75350303, 75350303, 0, 74051160, 74051160, 0, 72796055, 72796055, 0, 0x4444444, 0x4444444, 0, 70409299, 70409299, 0, 69273666, 69273666, 0, 0x4104104, 0x4104104, 0, Integer.MIN_VALUE, 0, 5};
|
|
private final long[] data;
|
|
private final int bits;
|
|
private final long mask;
|
|
private final int size;
|
|
private final int valuesPerLong;
|
|
private final int divideMul;
|
|
private final int divideAdd;
|
|
private final int divideShift;
|
|
|
|
public SimpleBitStorage(int bits, int size, int[] values) {
|
|
this(bits, size);
|
|
int inputOffset;
|
|
int outputIndex = 0;
|
|
for (inputOffset = 0; inputOffset <= size - this.valuesPerLong; inputOffset += this.valuesPerLong) {
|
|
long packedValue = 0L;
|
|
for (int indexInLong = this.valuesPerLong - 1; indexInLong >= 0; --indexInLong) {
|
|
packedValue <<= bits;
|
|
packedValue |= (long)values[inputOffset + indexInLong] & this.mask;
|
|
}
|
|
this.data[outputIndex++] = packedValue;
|
|
}
|
|
int remainderCount = size - inputOffset;
|
|
if (remainderCount > 0) {
|
|
long lastPackedValue = 0L;
|
|
for (int indexInLong = remainderCount - 1; indexInLong >= 0; --indexInLong) {
|
|
lastPackedValue <<= bits;
|
|
lastPackedValue |= (long)values[inputOffset + indexInLong] & this.mask;
|
|
}
|
|
this.data[outputIndex] = lastPackedValue;
|
|
}
|
|
}
|
|
|
|
public SimpleBitStorage(int bits, int size) {
|
|
this(bits, size, (long[])null);
|
|
}
|
|
|
|
public SimpleBitStorage(int bits, int size, long @Nullable [] data) {
|
|
Validate.inclusiveBetween((long)1L, (long)32L, (long)bits);
|
|
this.size = size;
|
|
this.bits = bits;
|
|
this.mask = (1L << bits) - 1L;
|
|
this.valuesPerLong = (char)(64 / bits);
|
|
int row = 3 * (this.valuesPerLong - 1);
|
|
this.divideMul = MAGIC[row + 0];
|
|
this.divideAdd = MAGIC[row + 1];
|
|
this.divideShift = MAGIC[row + 2];
|
|
int requiredLength = (size + this.valuesPerLong - 1) / this.valuesPerLong;
|
|
if (data != null) {
|
|
if (data.length != requiredLength) {
|
|
throw new InitializationException("Invalid length given for storage, got: " + data.length + " but expected: " + requiredLength);
|
|
}
|
|
this.data = data;
|
|
} else {
|
|
this.data = new long[requiredLength];
|
|
}
|
|
}
|
|
|
|
private int cellIndex(int bitIndex) {
|
|
long mul = Integer.toUnsignedLong(this.divideMul);
|
|
long add = Integer.toUnsignedLong(this.divideAdd);
|
|
return (int)((long)bitIndex * mul + add >> 32 >> this.divideShift);
|
|
}
|
|
|
|
@Override
|
|
public int getAndSet(int index, int value) {
|
|
Validate.inclusiveBetween((long)0L, (long)(this.size - 1), (long)index);
|
|
Validate.inclusiveBetween((long)0L, (long)this.mask, (long)value);
|
|
int cellIndex = this.cellIndex(index);
|
|
long cellValue = this.data[cellIndex];
|
|
int bitIndex = (index - cellIndex * this.valuesPerLong) * this.bits;
|
|
int oldValue = (int)(cellValue >> bitIndex & this.mask);
|
|
this.data[cellIndex] = cellValue & (this.mask << bitIndex ^ 0xFFFFFFFFFFFFFFFFL) | ((long)value & this.mask) << bitIndex;
|
|
return oldValue;
|
|
}
|
|
|
|
@Override
|
|
public void set(int index, int value) {
|
|
Validate.inclusiveBetween((long)0L, (long)(this.size - 1), (long)index);
|
|
Validate.inclusiveBetween((long)0L, (long)this.mask, (long)value);
|
|
int cellIndex = this.cellIndex(index);
|
|
long cellValue = this.data[cellIndex];
|
|
int bitIndex = (index - cellIndex * this.valuesPerLong) * this.bits;
|
|
this.data[cellIndex] = cellValue & (this.mask << bitIndex ^ 0xFFFFFFFFFFFFFFFFL) | ((long)value & this.mask) << bitIndex;
|
|
}
|
|
|
|
@Override
|
|
public int get(int index) {
|
|
Validate.inclusiveBetween((long)0L, (long)(this.size - 1), (long)index);
|
|
int cellIndex = this.cellIndex(index);
|
|
long cellValue = this.data[cellIndex];
|
|
int bitIndex = (index - cellIndex * this.valuesPerLong) * this.bits;
|
|
return (int)(cellValue >> bitIndex & this.mask);
|
|
}
|
|
|
|
@Override
|
|
public long[] getRaw() {
|
|
return this.data;
|
|
}
|
|
|
|
@Override
|
|
public int getSize() {
|
|
return this.size;
|
|
}
|
|
|
|
@Override
|
|
public int getBits() {
|
|
return this.bits;
|
|
}
|
|
|
|
@Override
|
|
public void getAll(IntConsumer output) {
|
|
int count = 0;
|
|
for (long cellValue : this.data) {
|
|
for (int value = 0; value < this.valuesPerLong; ++value) {
|
|
output.accept((int)(cellValue & this.mask));
|
|
cellValue >>= this.bits;
|
|
if (++count < this.size) continue;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void unpack(int[] output) {
|
|
int indexInLong;
|
|
long cellValue;
|
|
int dataLength = this.data.length;
|
|
int outputOffset = 0;
|
|
for (int i = 0; i < dataLength - 1; ++i) {
|
|
cellValue = this.data[i];
|
|
for (indexInLong = 0; indexInLong < this.valuesPerLong; ++indexInLong) {
|
|
output[outputOffset + indexInLong] = (int)(cellValue & this.mask);
|
|
cellValue >>= this.bits;
|
|
}
|
|
outputOffset += this.valuesPerLong;
|
|
}
|
|
int remainder = this.size - outputOffset;
|
|
if (remainder > 0) {
|
|
cellValue = this.data[dataLength - 1];
|
|
for (indexInLong = 0; indexInLong < remainder; ++indexInLong) {
|
|
output[outputOffset + indexInLong] = (int)(cellValue & this.mask);
|
|
cellValue >>= this.bits;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public BitStorage copy() {
|
|
return new SimpleBitStorage(this.bits, this.size, (long[])this.data.clone());
|
|
}
|
|
|
|
public static class InitializationException
|
|
extends RuntimeException {
|
|
private InitializationException(String message) {
|
|
super(message);
|
|
}
|
|
}
|
|
}
|
|
|