All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.nukkit.level.format.anvil.palette.BitArray256 Maven / Gradle / Ivy

There is a newer version: 1.20.40-r1
Show newest version
package cn.nukkit.level.format.anvil.palette;

import cn.nukkit.utils.ThreadCache;

/**
 * @author https://github.com/boy0001/
 */
public final class BitArray256 {
    final long[] data;
    private final int bitsPerEntry;

    public BitArray256(int bitsPerEntry) {
        this.bitsPerEntry = bitsPerEntry;
        int longLen = (this.bitsPerEntry * 256) >> 6;
        this.data = new long[longLen];
    }

    public BitArray256(BitArray256 other) {
        this.bitsPerEntry = other.bitsPerEntry;
        this.data = other.data.clone();
    }

    public void setAt(int index, int value) {
        int bitIndexStart = index * bitsPerEntry;
        int longIndexStart = bitIndexStart >> 6;
        int localBitIndexStart = bitIndexStart & 63;
        this.data[longIndexStart] = this.data[longIndexStart] & ~((long) ((1L << bitsPerEntry) - 1) << localBitIndexStart) | ((long) value) << localBitIndexStart;

        if (localBitIndexStart > 64 - bitsPerEntry) {
            int longIndexEnd = longIndexStart + 1;
            int localShiftStart = 64 - localBitIndexStart;
            int localShiftEnd = bitsPerEntry - localShiftStart;
            this.data[longIndexEnd] = this.data[longIndexEnd] >>> localShiftEnd << localShiftEnd | (((long) value) >> localShiftStart);
        }
    }

    public int getAt(int index) {
        int bitIndexStart = index * bitsPerEntry;

        int longIndexStart = bitIndexStart >> 6;

        int localBitIndexStart = bitIndexStart & 63;
        if (localBitIndexStart <= 64 - bitsPerEntry) {
            return (int) (this.data[longIndexStart] >>> localBitIndexStart & ((1 << bitsPerEntry) - 1));
        } else {
            int localShift = 64 - localBitIndexStart;
            return (int) ((this.data[longIndexStart] >>> localBitIndexStart | this.data[longIndexStart + 1] << localShift) & ((1 << bitsPerEntry) - 1));
        }
    }

    public void fromRaw(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            setAt(i, arr[i]);
        }
    }

    public BitArray256 grow(int newBitsPerEntry) {
        int amtGrow = newBitsPerEntry - this.bitsPerEntry;
        if (amtGrow <= 0) return this;
        BitArray256 newBitArray = new BitArray256(newBitsPerEntry);

        int[] buffer = ThreadCache.intCache256.get();
        toRaw(buffer);
        newBitArray.fromRaw(buffer);

        return newBitArray;
    }

    public BitArray256 growSlow(int bitsPerEntry) {
        BitArray256 newBitArray = new BitArray256(bitsPerEntry);
        for (int i = 0; i < 256; i++) {
            newBitArray.setAt(i, getAt(i));
        }
        return newBitArray;
    }

    public int[] toRaw(int[] buffer) {
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = getAt(i);
        }
        return buffer;
    }

    public int[] toRaw() {
        return toRaw(new int[256]);
    }

    @Override
    public BitArray256 clone() {
        return new BitArray256(this);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy