天天看點

Bitmaps-位圖

目錄

1、簡介

2 、基本操作

2.1 SETBIT key offset value

2.2 GETBIT key offset

2.3 BITCOUNT key [start] [end]

2.4 BITPOS key bit [start] [end]

2.5 BITOP operation destkey key [key …]

2.6 BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]

Bitmaps 稱為位圖,它不是一種資料類型。網上很多視訊教程把Bitmaps稱為資料類型,應該是不正确的。Bitmaps 是Redis提供給使用者用于操作位的“資料類型”。它主要有如下的基本特性:

Bitmaps 不是資料類型,底層就是字元串(key-value),byte數組。我們可以使用普通的get/set直接擷取和設值位圖的内容,也可以通過Redis提供的位圖操作getbit/setbit等将byte數組看成“位數組”來處理

Bitmaps 的“位數組”每個單元格隻能存儲0和1,數組的下标在Bitmaps中稱為偏移量

Bitmaps設定時key不存在會自動生成一個新的字元串,如果設定的偏移量超出了現有内容的範圍,就會自動将位數組進行零擴充

Bitmaps-位圖

對key存儲的字元串,設定或者清除指定偏移量上的位(bit),位的設定或者清除取決于value參數,0/1;當key不存在時,自動生成一個新的字元串。字元串會進行伸展確定value儲存在指定的偏移量上。字元串進行伸展時,空白位置以0填充。

時間複雜度 :

O(1)

offset 範圍:

0~2^32

傳回值:

指定偏移量原來存儲的位

案例:

使用Bitmaps來存儲使用者是否打卡,打卡記做1,未打卡為0,使用者的id作為偏移量 假設存在10個使用者,此時使用者1、3、5、9、10打了卡,其他人未打卡,Bitmaps的初始化結果如下所示: clock:20210806代表2021/08/06的打卡記錄

Bitmaps-位圖

注意事項:

正式系統中,id肯定不會是0、1、2這種,而是以某一個數組開頭,比如1000000000000001、1000000000000002這個時候非常容易導緻偏移量的浪費,是以我們可以考慮通過計算減去一個合适的值後再設定偏移量,如果設定的Bitmaps偏移量過大,容易造成配置設定記憶體時間過長,Redis伺服器被阻塞。

Bitmaps-位圖

計算給定字元串中,被設定為1的bit位的數量。start和end參數可以指定查詢的範圍,可以使用負數值。-1代表最後一個位元組,-2代表倒是第二個位元組。

注意:start和end是位元組索引,是以每增加1 代表的是增加一個字元,也就是8位,是以位的查詢範圍必須是8的倍數。

時間複雜度:

O(N)

被設定為1的位的數量

clock:20210806代表2021/08/06的打卡記錄,此時一共11位,前8位置3個1,後3位中2個1

Bitmaps-位圖

傳回第一個置為bit的二進制位的位置,預設檢測整個Bitmaps,也可以通過start和end參數指定查詢範圍

整數回複

bitpos clock:20210806 0 表示第一個0的位置

bitpos clock:20210806 1 表示第一個1的位置

bitpos clock:20210806 1 0 0 表示第一個字元中,第一個1的位置

bitpos clock:20210806 1 1 1 表示第二個字元中,第一個1的位置

bitpos clock:20210806 1 0 1 表示第一個和第二個字元中,第一個1的位置

Bitmaps-位圖

Redis的Bitmaps提供BITOP指令來對一個或多個(除了NOT操作)二進制位的字元串key進行位元操作,操作的結果儲存到destkey上,operation是操作類型,有四種分别是:AND、OR、NOT、XOR

BITOP AND destkey key [key ...] ,對一個或多個 key 求邏輯并,并将結果儲存到 destkey

BITOP OR destkey key [key ...] ,對一個或多個 key 求邏輯或,并将結果儲存到 destkey

BITOP XOR destkey key [key ...] ,對一個或多個 key 求邏輯異或,并将結果儲存到 destkey

BITOP NOT destkey key ,對給定 key 求邏輯非,并将結果儲存到 destkey

當字元串長度不一緻是,較短的那個字元串所缺失的部分會被看作0,空的key也會被看作是包含0的字元串序列

位運算的結果(儲存到destkey的字元串的長度和輸入key中的最長的字元串的長度相等)

這裡使用key1 1001和key2 1011進行上述四種操作

Bitmaps-位圖
Bitmaps-位圖

2.1和2.2中的setbit和getbit都是對指定key的單個位的操作,如果需要對多個位同時操作,那麼可以使用bitfield指令,bitfield有三個子指令,分别是get、set、incrby,它們可以對指定的片段進行讀寫,但是最多處理64個連續的位,超過64個連續的位,需要使用多個子指令,bitfield可以同時執行多個子指令(無符号整數隻能傳回63位)。

注意:

使用 GET 子指令對超出字元串目前範圍的二進制位進行通路(包括鍵不存在的情況), 超出部分的二進制位的值将被當做是 0 。

使用 SET 子指令或者 INCRBY 子指令對超出字元串目前範圍的二進制位進行通路将導緻字元串被擴大, 被擴大的部分會使用值為 0 的二進制位進行填充。 在對字元串進行擴充時, 指令會根據字元串目前已有的最遠端二進制位, 計算出執行操作所需的最小長度。

值操作子指令:

GET <type> <offset> —— 傳回指定的二進制位範圍

SET <type> <offset> <value> —— 對指定的二進制位範圍進行設定,并傳回它的舊值

INCRBY <type> <offset> <increment> —— 對指定的二進制位範圍執行加法操作,并傳回它的舊值。使用者可以通過向 increment 參數傳入負值來實作相應的減法操作

溢出政策子指令:

WRAP:回繞/折返(wrap around)-預設溢出政策,對于無符号整數來說, 回繞就像使用數值本身與能夠被儲存的最大無符号整數執行取模計算, 這也是 C 語言的标準行為。 對于有符号整數來說, 上溢将導緻數字重新從最小的負數開始計算, 而下溢将導緻數字重新從最大的正數開始計算。

SAT:飽和計算(saturation arithmetic),也可以了解為飽和截斷,這種模式下下溢計算的結果為最小的整數值, 而上溢計算的結果為最大的整數值

FAIL:失敗不執行,這種模式會拒絕執行那些導緻上溢或者下溢的計算情況,傳回nil表示計算未被執行。

需要注意的是, OVERFLOW 子指令隻會對緊随着它之後被執行的 INCRBY 指令産生效果, 這一效果将一直持續到與它一同被執行的下一個 OVERFLOW 指令為止。 在預設情況下, INCRBY 指令使用 WRAP 方式來處理溢出計算。 i與u: i表示有符号整數,u表示無符号整數。u4代表4位長的無符号整數,i8代表8位長的有符号整數。

測試數字為10100111

Bitmaps-位圖

繼續閱讀