hex.genmodel.utils.GenmodelBitSet Maven / Gradle / Ivy
package hex.genmodel.utils;
/**
* GenmodelBitSet - bitset that "lives" on top of an external byte array. It does not necessarily span the entire
* byte array, and thus essentially provides a "bitset-view" on the underlying data stream.
*
* This is a bastardized copy of water.utils.IcedBitSet
*/
public class GenmodelBitSet {
private byte[] _val; // Holder of the bits, perhaps also holding other unrelated data
private int _byteoff; // Number of bytes skipped before starting to count bits
private int _nbits; // Number of bits in this bitset
private int _bitoff; // Number of bits discarded from beginning (inclusive min)
public GenmodelBitSet(int nbits) {
this(nbits, 0);
}
public GenmodelBitSet(int nbits, int bitoff) {
// For small bitsets, just use a no-offset fixed-length format
if (bitoff + nbits <= 32) {
bitoff = 0;
nbits = 32;
}
fill(nbits <= 0 ? null : new byte[bytes(nbits)], 0, nbits, bitoff);
}
public int getNBits() {
return _nbits;
}
// Fill in fields, with the bytes coming from some other large backing byte
// array, which also contains other unrelated bits.
public void fill(byte[] v, int byteoff, int nbits, int bitoff) {
if (nbits < 0) throw new NegativeArraySizeException("nbits < 0: " + nbits);
if (byteoff < 0) throw new IndexOutOfBoundsException("byteoff < 0: "+ byteoff);
if (bitoff < 0) throw new IndexOutOfBoundsException("bitoff < 0: " + bitoff);
assert v == null || byteoff + bytes(nbits) <= v.length;
_val = v;
_nbits = nbits;
_bitoff = bitoff;
_byteoff = byteoff;
}
public boolean isInRange(int b) {
b -= _bitoff;
return b >= 0 && b < _nbits;
}
public boolean contains(int idx) {
idx -= _bitoff;
assert (idx >= 0 && idx < _nbits): "Must have "+_bitoff+" <= idx <= " + (_bitoff+_nbits-1) + ": " + idx;
return (_val[_byteoff + (idx >> 3)] & ((byte)1 << (idx & 7))) != 0;
}
public void fill2(byte[] bits, ByteBufferWrapper ab) {
fill(bits, ab.position(), 32, 0);
ab.skip(4); // Skip inline bitset
}
// Reload IcedBitSet from AutoBuffer
public void fill3(byte[] bits, ByteBufferWrapper ab) {
int bitoff = ab.get2();
int nbits = ab.get4();
fill(bits, ab.position(), nbits, bitoff);
ab.skip(bytes(nbits)); // Skip inline bitset
}
private static int bytes(int nbits) {
return ((nbits-1) >> 3) + 1;
}
/* SET IN STONE FOR MOJO VERSION "1.00" - DO NOT CHANGE */
public boolean contains0(int idx) {
if (idx < 0) throw new IndexOutOfBoundsException("idx < 0: " + idx);
idx -= _bitoff;
return (idx >= 0) && (idx < _nbits) &&
(_val[_byteoff + (idx >> 3)] & ((byte)1 << (idx & 7))) != 0;
}
/* SET IN STONE FOR MOJO VERSION "1.10" AND OLDER - DO NOT CHANGE */
public void fill3_1(byte[] bits, ByteBufferWrapper ab) {
int bitoff = ab.get2();
int nbytes = ab.get2();
fill_1(bits, ab.position(), nbytes<<3, bitoff);
ab.skip(nbytes); // Skip inline bitset
}
/* SET IN STONE FOR MOJO VERSION "1.10" AND OLDER - DO NOT CHANGE */
public void fill_1(byte[] v, int byteoff, int nbits, int bitoff) {
if (nbits < 0) throw new NegativeArraySizeException("nbits < 0: " + nbits);
if (byteoff < 0) throw new IndexOutOfBoundsException("byteoff < 0: "+ byteoff);
if (bitoff < 0) throw new IndexOutOfBoundsException("bitoff < 0: " + bitoff);
assert v == null || byteoff + ((nbits-1) >> 3) + 1 <= v.length;
_val = v;
_nbits = nbits;
_bitoff = bitoff;
_byteoff = byteoff;
}
}