第十三 C#中的bitmap运算

在我们日常工作中,有时候可能遇到大数据的查询判断是否存在,比如前段时间我遇到的一个优化问题,1.2亿数据中判断用户id是否存在,
如果在数据库建立索引,而且用UserId做集聚索引的话,查询速度还可以,但是如果是大并发查询怎么办,每次查询链接和打开数据库是很耗费资源的,这个时候我们要怎么做
,当时想到放到redis里面,这个的确可以,而且数据很快,但是放到redis里面同样有网络IO,而且1.2亿数据放到redis中,占用的空间也不小,
这个时候就想到了bitmap的位运算(原理就不详细说了),用数组的bit位来标识数据是否存在,大家知道一个 long是64位,那我们就可以表示64个基本数据,每一位,存在的话设置为1,不存在的话就是0,
下面是我用long数组实现的一个bitmap,测试了一下,1.2亿数据,占用内存是24M,比redis小了很多,而且没有网络IO的开销,速度很快,
而且这样做成了位,我们在做比较比如交集,并集也很方便
 
 
 
---
 
/// <summary>
    /// BitMap数据处理类
    /// </summary>
    public class MyBitMap
    {
        /// <summary>
        /// 文档大小
        /// </summary>
        private int size;
        private long[] words;
 
        /// <summary>
        /// 初始化BitMap
        /// </summary>
        /// <param name="size"></param>
        public MyBitMap(int size)
        {
            this.size = size;
            this.words = new long[GetWordIndex(size - 1) + 1];
        }
        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="bitindex"></param>
        public void AddWord(int bitindex)
        {
            if(bitindex<0 || bitindex>this.size-1)
            {
                return;
            }
            int wordIndex = GetWordIndex(bitindex);
            this.words[wordIndex] |= (1L << bitindex);
        }
 
        /// <summary>
        /// 获取一个数据是否在BitMap中
        /// </summary>
        /// <param name="bitindex"></param>
        /// <returns></returns>
        public bool GetWordIsTrue(int bitindex)
        {
            if (bitindex<0 || bitindex>this.size-1)
            {
                return false;
            }
            int wordIndex = GetWordIndex(bitindex);
            return (this.words[wordIndex] & (1L << bitindex)) != 0;
        }
 
        /// <summary>
        /// 把一个数据从bitmap中清理掉
        /// </summary>
        /// <param name="bitindex"></param>
        public void ClearWord(int bitindex)
        {
            if(bitindex<0 || bitindex>this.size-1)
            {
                return;
            }
            int wordIndex = GetWordIndex(bitindex);
            this.words[wordIndex] ^= (1L << bitindex);
        }
 
        /// <summary>
        /// 获取一个数字在word中的位置
        /// </summary>
        /// <param name="bitindex"></param>
        /// <returns></returns>
        private int GetWordIndex(int bitindex)
        {
            return bitindex >> 6;
        }
 
    }
posted @ 2019-10-16 11:15  瀚海行舟  阅读(1045)  评论(0编辑  收藏  举报