redis之bitpos、bitop、bitfield命令

bitpos命令:
語法:bittops key bit [start] [end]
返回位圖中第一個值爲bit的二進制位的位置
在默認情況下,命令將檢測到的整個位圖,但用戶也可以通過可選的start參數和end參數指定要檢測的範圍
返回值:
整數回覆

setbit m  3 1
bitpos m 0   返回0
bitpos m 1   返回3

bitop命令:
語法:bitop operation destkey key [key...]
對一個或多個保存二進制位的字符串key進行位元操作,並將結果保存到destksy上
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...]對給定key求邏輯菲,並將結果保存到destkey

看到上面除了not操作符外,其他的操作都可以接受一個或多個key作爲輸入。
處理不同長度的字符串:
當bitop處理不同長度的字符串時,較短的那個字符串所缺少的部分會被看做是0
空的key也被看做是包含0的字符串序列
返回值:
保存到destksy的字符串的長度,和輸入key中最長的字符串長度相等

SETBIT bits-1 0 1        # bits-1 = 1001
SETBIT bits-1 3 1
SETBIT bits-2 0 1        # bits-2 = 1011
SETBIT bits-2 1 1
SETBIT bits-2 3 1
BITOP AND and-result bits-1 bits-2
GETBIT and-result 0      # and-result = 1001
(integer) 1
GETBIT and-result 1
(integer) 0
GETBIT and-result 2
(integer) 0
GETBIT and-result 3
(integer) 1

bitfield命令:
bitfield命令可以將一個redis字符串看做是一個由二進制位組成的數組,並對這個數組中儲存的長度
不同的整數進行訪問(被儲存的整數無需對齊).換句話說,通過這個命令,用戶可以執行諸如"對偏移量1234上的5位長有符號整數進行設置",
"獲取偏移量4567上的31位長無符號整數".此外,bitfield命令還可以對指定的整數執行加法和減法操作,
並且將這些操作可以通過設置妥善地處理計算時出現的溢出情況。
bitfield命令可以在一次調用中同時對多個位範圍進行操作,它接受一系列待執行的操作作爲參數,並返回一個數組作爲回覆,
數組中的每個元素就是對應操作執行的結果。

支持子命令以及數字類型:
bitfield命令支持的子命令:
get <type> <offset> 返回指定的二進制範圍
set <type> <offset> <value> 對指定的二進制範圍進行設置 並返回它的舊值
incrby <type> <offset> <increment> 對指定的二進制範圍執行加法操作,並返回它的舊值.用戶可以通過increment參數傳入負值來
進行減法操作。
還有一個子命令,可以改變之後執行的incrby子命令在發生溢出情況時的行爲。
overflow [wrap|sat|fail]
當被設置的二進制範圍值爲整數時,用戶可以在類型參數的前面添加i來表示有符號整數,或者在前面添加u來表示無符號整數。
例如:u8 8位長的無符號整數
      i16 16位長的有符號整數
bitfield命令最大支持64位長有符號整數以及63位長的無符號整數,其中無符號整數的63位長度限制是由於Redis協議目前還無法返回64位長的無符號整數導致。      
SET:
set test a  //01100001
biefield test i8 0 -1  (把無符號設置爲有符號整數)
getbit test 0 -7  //11111111
GET:
獲取偏移量100的4位長有符號整數(有符號):
bitfield m  GET i4 100
解析:
整體原碼:00000……0001
從100開始獲取4位即原碼位1000,有符號轉十進制,要進行補碼(反碼加1),進行反碼0111,然後加1,0111+1=1000,十進制就是8,由於最高位是1,所以是-8

獲取偏移量100的4位長有符號整數(無符號):
bitfield m  GET i4 99
解析:
整體原碼:00000……0001
從99開始獲取4位即原碼位0100,最高位是0(正數無符號),無符號轉十進制,0+2^2+0+0=4

獲取偏移量99的4位長無符號整數:
bitfield m  GET u4 100
解析:
整體原碼:00000……0001
從100開始獲取4位即原碼位1000,無符號轉十進制,2^3+0+0+0=8
使用GET子命令對超出字符串當前範圍的二進制進行訪問(包括鍵不存在的情況下),超出部分的二進制值將被當做是0

INCRBY:
0000……0001
BITFIELD m INCRBY i8 100 1
返回-127
解析:
i8 100  從100開始獲取8位10000000 有符號轉十進制,要進行補碼(反碼加1),進行反碼011111111,01111111+1=10000000 所以2^7+0+0+……=128 最高位是1 所以-128
incrby 和最後面的1 就是給100的8位長有符號整數加1即:10000001 所以是-127
減法的話:BITFIELD m INCRBY i8 100 -2  

二進制位和位置偏移量
在二進制範圍命令中,用戶有兩種方法來設置偏移量:
如果用戶給定的是一個沒有任何前綴的數字,那麼這個數字指示的就是字符串以零開始的偏移量
另一方面,如多用戶給定的是一個帶有#前綴的偏移量,那麼命令將使用這個偏移量與被設置的數字類型的位長度相乘,從而計算出真正的偏移量
舉例:
bitfield m set i8 #0 100 i8 #1 200
解析:
命令會把m鍵裏面,第一個i8長度的二進制位的值設置爲100,第二個i8長度的二進制位設置爲200
當我們把一個字符串鍵當成數組來使用,並且數組中儲存的都是同等長度的整數時.使用#前綴可以讓我們去避免手動計算被設置
二進制位所在位置的麻煩。
getbit m 0-8   //01100100(100的二進制)
getbit m 9-16  //11001000(200的二進制)

溢出控制
用戶可以通過overflow命令以及以下展示的三個參數,指定bitfield命令在執行自增或者自減操作時,
碰上向上溢出或者鄉下溢出情況時的行爲:
wrap:使用迴繞的方法處理有符號整數和無符號整數的溢出情況。
對於無符號的整數來說,迴繞就像使用數值本身與能夠被儲存的最大無符號整數執行取模計算,這也是C語言的標準行爲.
對於有符號整數來說,上溢將導致數字重新從最小的負數開始計算,而下溢將導致數字重新從最大的正數開始計算
比如:127 的i8執行加一操作 那麼得到的結果是-128
sat:使用飽和計算方法處理溢出,也就是說,下溢計算的結果爲最小的整數值,而上溢計算的結果爲最大的整數值
例子:
如果對一個值爲120的i8整數執行加10計算,那麼命令的結果將i8所能存儲的最大整數值爲127
相反,如果針對i8值計算造成了下溢,那麼這個i8值將被設置爲-127.
fail:在這一模式下,命令將拒絕執行那些會導致上溢或者下溢情況出現的計算,並向用戶返回空值表示計算未被執行。
需要注意的是,overflow子命令只會對緊隨着它之後被執行的incrby命令產生效果,
這一效果將一直持續到與它一同執行的下一個overflow命令爲止。
在默認情況下,incrby命令使用warp方式來處理溢出。
一下是overflow子命令控制溢出的例子:
BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1
1
BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
2
2
BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
3
3
BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
0
3
都是2位長無符號,默認使用warp(迴繞) 1(0) 2(1) 3(2) 3之後超出2位,迴繞返回0
第二個使用的是sat(飽和) 1(0) 2(1) 3(2) 3已經飽和2位 從3開始2 1
使用fail:
BITFIELD mykey OVERFLOW FAIL incrby u2 102 1
返回(nli)

發佈了82 篇原創文章 · 獲贊 20 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章