位图的索引的一个应用

     bitmap 是索引最长常见的一种实现方式。就是bit位的每一位,来作为表示要索引的对象。通常位图索引通常表达取值维度取值较少的数据.,最好是布尔值 比如

        

        男

1

       婚否

0

       是否有房

0

       是否有车

0

    比如上表中,对一个人描述,就可以用1000  表示在取值较多(高基数)情况,也可以应用位图,一是方便查询,便于应用 OR AND 等操作,而是可以将bit位编成整数,这样大大减少了存贮和传输的空间。
     比如这样讲吧,对于一个广告位来讲吧,可以对应很多个广告合同。如果后端有个rpc服务,可以为广告位选择最合适的合同。如果广告位和广告合同都很多,那么这个数据传输量是很大的。为了解决这个问题就是可以将广告的合同编号,通过位图索引来压缩传输数据。
        对于一个广告位而言。可以我讲他对应所有的广告位放入一个list中。通过遍历list中的每一位,来构建该广告位,对应投放合同的位图索引(bitmap),下面的算法就是如何来够构建这个位图索引
 
bitmap 是可以想象为一串大二级制。从低位到高位的每一个位置表示是表示从1到n的连续十进制数。如果list中最大数为max。那么我们可以用max位的二进制串表示list中所有数。
    java中32 (2的5次方)位表示一个整型。我们可以将这个大二进制串拆散,用多个整型表示。如果list中最大数为max,那么需要整型的数目,就可以用
     int size =  (max >> 5)+1 ;  
    这个公式很好理解,左移5位,是除以2的5次方(32)。
 
   通过size我们就能确定位图的大小,   同理对list 中的一个数我们也可以通过这种方式找到它编码后所在的整型(编码后整型数字都是,按从低位到高排列)
   int buket = bitIndexList.get(i) >>5;
  
   不难想出 这个数字在整型中的位置,就是对32求余,
       int index =  bitIndexList.get(i) & 0x1F;
          
    对32求余,可以用公式 n & (32-1)   表达  ,其实就是对低于32位数,其实低五位中1 保留,高于5位置全部设置为0
     另外一个方法是 2 n - (n>>5)<<5,这里就不做详细解释了
   
     最后将这个广告位设置为1 就可以 int intBitSet = bitList.get(buket) | 1 << index;
 
   遍历list 中所有值,就构建出广告位对应的bitmap,
 这个方法应用很广, 可以用它替代hashmap , 如果数据太大,hashmap 因为频繁冲突,就会向链表退化。使用位图,就不存在,最好最坏的情况。当然你也可以使用布隆过滤器,但是要付出精确率的代价。这个方法也可以用在排序中,也就是《编程珠玑》中前言的内容。

猜你喜欢

转载自kobe00712.iteye.com/blog/2262092