其他分享
首页 > 其他分享> > Bucket--提供偏移索引方法的位集实现

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