Bucket--提供偏移索引方法的位集实现
作者:互联网
/**
* Bitset implementation that provides methods to offset indices.
**/
static class Bucket {
//每个data最大长度为Long的长度64
static final int BITS_PER_WORD = Long.SIZE;
//最前面的bit位
static final long LAST_BIT = 1L << (Long.SIZE - 1);
//存储数据
long mData = 0;
//下一个桶
Bucket mNext;
//判断位置是否为当前桶,如果是则设置指定位置为1,否则创建下一个桶再设置
void set(int index) {
if (index >= BITS_PER_WORD) {
ensureNext();
mNext.set(index - BITS_PER_WORD);
} else {
mData |= 1L << index;
}
}
//创建下一个桶
private void ensureNext() {
if (mNext == null) {
mNext = new Bucket();
}
}
//将指定位置bit置0
void clear(int index) {
if (index >= BITS_PER_WORD) {
if (mNext != null) {
mNext.clear(index - BITS_PER_WORD);
}
} else {
mData &= ~(1L << index);
}
}
//获取指定bit位置的值
boolean get(int index) {
if (index >= BITS_PER_WORD) {
ensureNext();
return mNext.get(index - BITS_PER_WORD);
} else {
return (mData & (1L << index)) != 0;
}
}
//清空重置桶
void reset() {
mData = 0;
if (mNext != null) {
mNext.reset();
}
}
//往指定bit位置插入bit,位置左侧(after)向左移动1位,
void insert(int index, boolean value) {
if (index >= BITS_PER_WORD) {
ensureNext();
mNext.insert(index - BITS_PER_WORD, value);
} else {
final boolean lastBit = (mData & LAST_BIT) != 0;
long mask = (1L << index) - 1;
final long before = mData & mask;
final long after = ((mData & ~mask)) << 1;
mData = before | after;
if (value) {
set(index);
} else {
clear(index);
}
if (lastBit || mNext != null) {
ensureNext();
mNext.insert(0, lastBit);
}
}
}
//移除指定bit位置的bit
boolean remove(int index) {
if (index >= BITS_PER_WORD) {
ensureNext();
return mNext.remove(index - BITS_PER_WORD);
} else {
long mask = (1L << index);
final boolean value = (mData & mask) != 0;
mData &= ~mask;
mask = mask - 1;
final long before = mData & mask;
// 调用Long的循环右移方法,右移1
// cannot use >> because it adds one.
final long after = Long.rotateRight(mData & ~mask, 1);
mData = before | after;
if (mNext != null) {
if (mNext.get(0)) {
set(BITS_PER_WORD - 1);
}
mNext.remove(0);
}
return value;
}
}
//计算指定位置右侧(before)1的个数
int countOnesBefore(int index) {
if (mNext == null) {
if (index >= BITS_PER_WORD) {
return Long.bitCount(mData);
}
return Long.bitCount(mData & ((1L << index) - 1));
}
if (index < BITS_PER_WORD) {
return Long.bitCount(mData & ((1L << index) - 1));
} else {
return mNext.countOnesBefore(index - BITS_PER_WORD) + Long.bitCount(mData);
}
}
@Override
public String toString() {
return mNext == null ? Long.toBinaryString(mData)
: mNext.toString() + "xx" + Long.toBinaryString(mData);
}
}
public class Main{
public static void main(String[] argv){
Bucket bucket = new Bucket();
bucket.set(0); // 1
bucket.set(2); // 101
bucket.set(Bucket.BITS_PER_WORD+5); //100000 101
System.out.println("data = "+bucket.toString()); // data = 100000xx101
}
}
标签:mData,index,位集,WORD,--,Bucket,PER,mNext,BITS 来源: https://blog.csdn.net/u014793472/article/details/123630372