Redis學習筆記二 (BitMap算法分析與BitCount語法)


Redis學習筆記二

一、BitMap是什么

 

就是通過一個bit位來表示某個元素對應的值或者狀態,其中的key就是對應元素本身。我們知道8個bit可以組成一個Byte,所以bitmap本身會極大的節省儲存空間。

二、BitMap算法基本描述

BitMap 是使用 bit位來標記某個元素對應的value,而key 即是該元素,因此對於之前位數存儲換成bit位存儲數據能大大的節省存儲空間。

三、BitMap的實現思想

假設我們要對於0-7內的5個元素(4,7,2,5,3)進行排序(假設元素沒有重復),我們可以利用bitmap達到該目的,要表示8個數,我們需要8bit,每個bit相當於一個標志位,我們可以通過標志位(0,1)去標識本次這個元素是否存在(0,標識不存在;1,標識存在,1Byte=8bit)

首先先開辟1byte的空間,將8個bit位設為0.如這張圖 

0

0

0

0

0

0

0

0

 

然后遍歷這幾個元素,4為第一個元素,所以把4對應的位置變為1.如下圖

0

0

0

0

1

0

0

0

 

接下去遍歷可以得到:

0

0

1

1

1

1

0

1

然后我們通過GETBIT這個命令可以遍歷bit區域,將標識為1的遍歷出來,得到(2,3,4,5,7)序列,這樣子就得到了排序的結果。

GETBIT key offset

 

四、BitMap 40億數據處理題目

   給你一個文件,里面包含40億個整數,如何利用bitMap思想找出該文件中不包含的一個整數, 假設你有1GB內存可用。

  我們用1Byte代替一個整數,那40億數據大概要40*10^8*bit = 0.5GB,滿足內存要求。

  用int來表示:Int  bmap[1+sum/32]; //N是總數,sum=40*(10^8),一個int=32Bit=4Byte

  然后我們插入一個整數ze,要先計算整數ze位於數組Bitmap中的索引:index = ze/32;(除以32是得到整數位於第幾個Byte,也就是第幾位)

  比如整數35,index=35/32=1, 35%32=3(取余) 第35位於數組中的index=1(位於數組BitMap[1]中標識等於3的位置),然后就是標識這個位置為1。

  知道了這些,我們就可以檢測哪個整數不在數據里面了。

  如:檢測35,先計算index,在數組BitMap的標識位置

  35: index = 1, 在BitMap[1]中的位置為 1,只需要檢測這個位置是否為1

  BitMap[1] &(1<<1),這樣是1返回true,否側返回false 

五、Bit-Map的應用

      1)可進行數據的快速查找,判重,刪除,一般來說數據范圍是int的10倍以下。

       2)去重數據而達到壓縮數據

 

BitCount

 

一、bitcount.語法

BitCount:計算key 所儲存的字符串值中,被設置為 1 的比特位的數量。

BITCOUNT key

 

BITCOUNT key start end

計算key 所儲存的字符串值中,指定字節區間[start,end]被設置為 1 的比特位的數量。
注意:redis的setbit設置或清除的是bit位置,而bitcount計算的是byte位置,1byte=8bit。
start 和 end 參數的設置和 GETRANGE 命令類似,都可以使用負數值:比如 -1 表示最后一個字節,而 -2 表示倒數第二個字節,以此類推。

 

二、使用bitcount統計瀏覽數量

如記錄網站上的用戶的上線頻率,例如計算用戶A上線了多少天,用戶B上線了多少天,以此作為數據,這可以用SETBIT和BITCOUNT來實現。

每當用戶在某一天上線的時候,通過SETBIT命令,以用戶名作為key,將那天所代表的網站的上線日作為offset (標識偏移數)參數,並將這個offset 上的為設置為1。

舉個例子,如果今天是網站上線的第66天,而用戶(user=Y)在今天閱覽過網站,那么執行命令SETBIT person:Y 66 1;如果88號那天用戶(user=Y)也繼續閱覽網站,那么執行命令SETBIT person:Y 88 1,

使用BITCOUNT命令:計算用戶(user=Y)總共上線次數時

執行BITCOUNT person:Y,得出用戶(person=Y)上線的總天數。

三、Python-redis-Bitcount 代碼

import redis

r = redis.Redis(host='127.0.0.1', port=6379, db=0)


#模擬A用戶 ,一年中 每三天登錄一次。  
for i in range(3, 365, 3):
    r.setbit('ua', i, 1)

#模擬B用戶,一年中 每60天登錄一次。
for i in range(1, 365, 60):
    r.setbit('ub', i, 1)

userList = r.keys('u*')
#用戶列表
print userList

#存放活躍用戶列表
Au = []
#存放非活躍用戶列表
Nau = []

for u in userList :
    # 計算登錄次數
    loginCount = r.bitcount(u)
    if loginCount > 100 :
        # 列表添加元組 ()對象
        Au.append((u, loginCount))
    else :
        Nau.append((u, loginCount))

for l in Au :
    print l[0] + ' 是活躍用戶. 登陸' + str(l[1]) + ''

for l in Nau :
    print l[0] + ' 是非活躍用戶. 登陸' + str(l[1]) + ''

結果:
['ub', 'ua']
ua 是活躍用戶. 登陸121天
ub 是非活躍用戶. 登陸7天

 

 

Bittop命令

處理不同長度的字符串

當 BITOP 處理不同長度的字符串時,較短的那個字符串所缺少的部分會被看作 0 。

空的 key 也被看作是包含 0 的字符串序列

 

      

 

    

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM