面试杀手锏:Redis源码之BitMap

本文在最后讲解了BitMap对腾讯面试题的解决方案,并基于BitMap实现了仿GitHub提交次数的日历图,希望各位看官看的开心😄

1.位图简介

如果我们需要记录某一用户在一年中每天是否有登录我们的系统这一需求该如何完成呢?如果使用KV存储,每个用户需要记录365个,当用户量上亿时,这所需要的存储空间是惊人的。

Redis 为我们提供了位图这一数据结构,每个用户每天的登录记录只占据一位,365天就是365位,仅仅需要46字节就可存储,极大地节约了存储空间。

15cff097252fc7e0570efa9121f011c6.png

位图数据结构其实并不是一个全新的玩意,我们可以简单的认为就是个数组,只是里面的内容只能为0或1而已(二进制位数组)。

2.命令实战

Redis提供了SETBITGETBITBITCOUNTBITOP四个常用命令用于处理二进制位数组。

  • SETBIT:为位数组指定偏移量上的二进制位设置值,偏移量从0开始计数,二进制位的值只能为0或1。返回原位置值。

  • GETBIT:获取指定偏移量上二进制位的值。

  • BITCOUNT:统计位数组中值为1的二进制位数量。

  • BITOP:对多个位数组进行按位与、或、异或运算。

127.0.0.1:6379> SETBIT first 0 1    # 0000 0001
(integer) 0
127.0.0.1:6379> SETBIT first 3 1    # 0000 1001
(integer) 0
127.0.0.1:6379> SETBIT first 0 0    # 0000 1000
(integer) 1

127.0.0.1:6379> GETBIT first 0
(integer) 0
127.0.0.1:6379> GETBIT first 3
(integer) 1

127.0.0.1:6379> BITCOUNT first      # 0000 1000
(integer) 1
127.0.0.1:6379> SETBIT first 0 1    # 0000 1001
(integer) 0
127.0.0.1:6379> BITCOUNT first      # 0000 1001
(integer) 2
127.0.0.1:6379> SETBIT first 1 1    # 0000 1011
(integer) 0
127.0.0.1:6379> BITCOUNT first      # 0000 1011
(integer) 3

127.0.0.1:6379> SETBIT x 3 1        
(integer) 0
127.0.0.1:6379> SETBIT x 1 1        
(integer) 0
127.0.0.1:6379> SETBIT x 0 1        # 0000 1011
(integer) 0
127.0.0.1:6379> SETBIT y 2 1        
(integer) 0
127.0.0.1:6379> SETBIT y 1 1        # 0000 0110
(integer) 0
127.0.0.1:6379> SETBIT z 2 1        
(integer) 0
127.0.0.1:6379> SETBIT z 0 1        # 0000 0101
(integer) 0

127.0.0.1:6379> BITOP AND andRes x y z    #0000 0000
(integer) 1
127.0.0.1:6379> BITOP OR orRes x y z      #0000 1111
(integer) 1
127.0.0.1:6379> BITOP XOR x y z           #0000 1000
(integer) 1

# 对给定的位数组进行按位取反
127.0.0.1:6379> SETBIT value 0 1
(integer) 0
127.0.0.1:6379> SETBIT value 3 1            #0000 1001
(integer) 0
127.0.0.1:6379> BITOP NOT notValue value    #1111 0110
(integer) 1

3.BitMap源码分析

3.1 数据结构

如下展示了一个用 SDS 表示的一字节(8位)长的位图:

4c0853d9c643bd2180a36e94a223a5e0.png

bc8677d5255baf75a9276246026be3cc.png

13956c50e1a56684e681e603f774eb7b.png

9d368423aa4698b462412d85cb07be1d.png

a8dbaa55b1ca5024d01b41d87c5988f5.png

4444a55331f9208957421f7030c18706.png

bf3149ab84558e10eb33f636bdc4a678.png

5fcb0f1125ef8f5b42a4fb7178516771.png

8525e4d35afc194125d4b140c670b29d.png

860e5c5508549c41079a17cfbc14394f.png

4da2ea69df56a2fc4e99cd4f70b0615b.png

63f4013941c41991bdc0de8cefdb31a5.png

89878c10cdf3fefc47abad3d353df344.gif

309d5a0d5ed7af16ab3d6e734fe738da.png

76ca9b316e57e43982234f1c6319cad1.png

95eed829b38c0a30f7b975bc4c487f38.png

b46f83453287e27e37f278e67c3b8d7d.png

d6afebdaf7a87b8139a3a54ed4692a0c.png

16971aa258ef2916ed8aa025d381a02e.png

06bb6fdf18a560d634e2f63652d71785.png

1893f26636b582c3d7f2f0d2afd9228e.png

b91240e8199418e3d1503995380957b0.png

fb10ca4c3714f8d10dfaaf47dfea21f5.png

fca308c1e829d330336c5d7c822b81b6.png

778f2514f97070414a31c4ddc5478611.png

041d8bc0440a9590ffc70101cbddda41.png

1fa303101753c56e9584071dcd4a96aa.png

195617a2d2e449a68356c1633a7188c1.png

967d791f46703fc52f93c215812aa5d8.png

46a68e234f15438ac4696e11fc64c8ad.png

441bfb5d49b35cea7f62cb0763c93f83.png

99d58715f62be3af4cd2dddc32a74000.png

26a7b574cdff272ac3bd17810ec87d02.png

9cd43db4e9545b21b604e87bd8f5d2ee.png

3a7dc95db65721645c3625810ec6297b.png

0abc17c26f48c9dff256d97700706219.png

777b923c9a4b48e55ba3edef317568f4.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值