BitMap的小实践

一、需求场景

        每天大量数据入库,但是90%以上的数据都是主键冲突的,如果主键冲突则跳过,如果不冲突则写入。

        比较简单的逻辑是,每来一条数据就在表里查询一下主键是否已经存在,如果存在跳过,如果不存在写入。但是这样的情况会导致大量的数据库查询操作,因此采用在内存中构建一个bitmap,通过bitmap判断数据是否需要写入,从而避免大量的低价值的查询操作。

二、BitMap代码

class BitMap(object):
    def __init__(self,max_value):
        self._bitmap_max_value = max_value
        self.bitmap = [0 for i in range(int((max_value + 31 - 1) / 31))]

    def set(self,num):
        element_index = self.__get_element_index(num)
        bit_index = self.__get_bit_index(num)
        self.bitmap[element_index] = self.bitmap[element_index] | (1 << bit_index)

    def find(self,num):
        element_index = self.__get_element_index(num)
        bit_index = self.__get_bit_index(num)
        if self.bitmap[element_index] & (1 << bit_index):
            return True
        return False
        
    def __get_element_index(self,value):
        """
        获取该数即将储存的字节在数组中下标
        """
        return value // 31

    def __get_bit_index(self,value):
        """
        获取该数在元素中的位下标
        """
        return value % 31

三、BitMap原理

        bitmap的思想就是将所有的int类型的key转化成一个对应的bit位,并由一个int类型的列表来存储。从而大大降低内存占用并提高查询、写入的性能。

        一个int类型的数据占32个bit。也就是说int类型的列表中的每一个值都可以表示32个key。

        因此n个key只需要 n // 31 + 1 长度的int类型列表即可标识。但是由于int类型需要一个标识位来表示正负,因此需要 (n - 1) // 31 + 1 长度的int类型列表。

        同理对于一个key,其可以通过int类型列表的第m个int,的第n位来表示。

                m = key // 31

                n = key % 31

四、BitMap的读取和写入

1、读取

        我们已经知道了,对于一个key,其可以通过int类型列表的第m个int,的第n位来表示。

                m = key // 31

                n = key % 31

        因此我们需要先计算出,这个key存储的位置,即m、n的值。获取int类型列表m位置的值,之后将1无符号左移n位,将对应的值进行与运算即可。

2、写入

        我们已经知道了,对于一个key,其可以通过int类型列表的第m个int,的第n位来表示。

                m = key // 31

                n = key % 31

        因此我们需要先计算出,这个key存储的位置,即m、n的值。获取int类型列表m位置的值,之后将1无符号左移n位,将对应的值进行或运算即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值