命令簡(jiǎn)介:
1)setbit:設(shè)置字符串指定偏移量bit
2)getbit:獲取字符串指定偏移量bit
3)bitcount:獲取字符串位中為1的數(shù)量
4)bitpos:獲取指定范圍的位圖中第一個(gè)值為bit的二進(jìn)制位的位置
5)bitop:對(duì)一個(gè)或者多個(gè)保存二進(jìn)制位的字符串key進(jìn)行位元操作,并且將結(jié)果保存到destkey上
6)bitfield
命令詳解:
1.setbit
可用版本: >=2.2.0
時(shí)間復(fù)雜度: O(1)
命令格式: setbit key offset value
作用:
對(duì)key存儲(chǔ)的字符串值,設(shè)置或者清除指定偏移量上的位Bit。
返回值:
指定偏移量原本存儲(chǔ)的位。
注意:
位的設(shè)置或者清除取決于value參數(shù),可以是0與1。
當(dāng)key不存在時(shí),會(huì)自動(dòng)生成。
字符串會(huì)自動(dòng)進(jìn)行伸縮以確保它可以將value保存在指定的偏移量上。當(dāng)字符串進(jìn)行伸縮時(shí),空白位置以0填充。
offset參數(shù)必須大于等于0,小于2^32。
2.getbit
可用版本: >=2.2.0
時(shí)間復(fù)雜度: O(1)
命令格式: getbit key offset
作用:
獲取key存儲(chǔ)字符串值,指定偏移量上的位。
返回值:
指定偏移量原本存儲(chǔ)的位。
注意:
當(dāng)offset大于字符串長(zhǎng)度,或者key不存在時(shí)返回0。
3.bitcount
可用版本: >=2.6.0
時(shí)間復(fù)雜度: O(N)
命令格式: bitcount key [start] [end]
作用:
獲取key存儲(chǔ)字符串值,一定范圍內(nèi),位值為1的數(shù)量。
返回值:
位值為1的數(shù)量。
注意:
start與end可以是負(fù)數(shù)。
不存在的key當(dāng)作空字符串處理,返回0。
4.bitpos
可用版本: >=2.8.7
時(shí)間復(fù)雜度: O(N)
命令格式: bitpos key bit [start] [end]
作用:
獲取指定范圍的位圖中第一個(gè)值為bit的二進(jìn)制位的位置。
返回值:
整數(shù)位置。
注意:
默認(rèn)情況下,檢測(cè)整個(gè)位圖。也可以使用start end參數(shù),指定檢測(cè)的范圍。
5.bitop
可用版本: >=2.6.0
時(shí)間復(fù)雜度: O(N)
命令格式: bitop operation destkey key [key...]
作用:
對(duì)一個(gè)或多個(gè)保存二進(jìn)制位的字符串 key 進(jìn)行位元操作,并將結(jié)果保存到 destkey 上。
返回值:
保存到 destkey 的字符串的長(zhǎng)度,和輸入 key 中最長(zhǎng)的字符串長(zhǎng)度相等。
注意:
operation之內(nèi)是以下幾個(gè)選項(xiàng):
1)AND-對(duì)一個(gè)或者多個(gè)key求邏輯并,并將結(jié)果保存到destkey上。
2)OR-對(duì)一個(gè)或者多個(gè)key求邏輯或,并將結(jié)果保存到destkey上。
3)XOR-對(duì)一個(gè)或者多個(gè)key求邏輯異或,并將結(jié)果保存到destkey上。
4)NOT-對(duì)一個(gè)或者多個(gè)key求邏輯非,并將結(jié)果保存到destkey上,not只支持一個(gè)key。
字符串長(zhǎng)度不一時(shí),短的字符串將會(huì)使用0自動(dòng)填充。
6.bitfield
可用版本: >=3.2.0
時(shí)間復(fù)雜度: O(1)
命令格式: bitfield key [GET type offset] [set type offset value] [incrby type offset increment] [overflow wrap|sat|fail]
作用:
bitfield命令將一個(gè)redis字符串看作是一個(gè)由二進(jìn)制位組成的數(shù)組,并對(duì)這個(gè)數(shù)組中存儲(chǔ)的長(zhǎng)度不同的整數(shù)進(jìn)行訪問(wèn)。
bitfield命令可以在一次調(diào)用中同時(shí)對(duì)多個(gè)位范圍進(jìn)行操作,它接受一系列待執(zhí)行的操作作為參數(shù),并返回一個(gè)數(shù)組作為回復(fù),數(shù)組中每一個(gè)元素就是對(duì)應(yīng)操作的執(zhí)行結(jié)果。
BITFIELD 命令的作用在于它能夠?qū)⒑芏嘈〉恼麛?shù)儲(chǔ)存到一個(gè)長(zhǎng)度較大的位圖中, 又或者將一個(gè)非常龐大的鍵分割為多個(gè)較小的鍵來(lái)進(jìn)行儲(chǔ)存, 從而非常高效地使用內(nèi)存, 使得 Redis 能夠得到更多不同的應(yīng)用 —— 特別是在實(shí)時(shí)分析領(lǐng)域: BITFIELD 能夠以指定的方式對(duì)計(jì)算溢出進(jìn)行控制的能力, 使得它可以被應(yīng)用于這一領(lǐng)域。
返回值:
BITFIELD 命令的返回值是一個(gè)數(shù)組, 數(shù)組中的每個(gè)元素對(duì)應(yīng)一個(gè)被執(zhí)行的子命令。 需要注意的是, OVERFLOW 子命令本身并不產(chǎn)生任何回復(fù)。
注意:
使用 GET 子命令對(duì)超出字符串當(dāng)前范圍的二進(jìn)制位進(jìn)行訪問(wèn)(包括鍵不存在的情況), 超出部分的二進(jìn)制位的值將被當(dāng)做是 0 。
使用 SET 子命令或者 INCRBY 子命令對(duì)超出字符串當(dāng)前范圍的二進(jìn)制位進(jìn)行訪問(wèn)將導(dǎo)致字符串被擴(kuò)大, 被擴(kuò)大的部分會(huì)使用值為 0 的二進(jìn)制位進(jìn)行填充。 在對(duì)字符串進(jìn)行擴(kuò)展時(shí), 命令會(huì)根據(jù)字符串目前已有的最遠(yuǎn)端二進(jìn)制位, 計(jì)算出執(zhí)行操作所需的最小長(zhǎng)度。
子命令支持:
GET —— 返回指定的二進(jìn)制位范圍。
SET —— 對(duì)指定的二進(jìn)制位范圍進(jìn)行設(shè)置,并返回它的舊值。
INCRBY —— 對(duì)指定的二進(jìn)制位范圍執(zhí)行加法操作,并返回它的舊值。用戶可以通過(guò)向 increment 參數(shù)傳入負(fù)值來(lái)實(shí)現(xiàn)相應(yīng)的減法操作。
OVERFLOW [WRAP|SAT|FAIL]——改變之后執(zhí)行的 INCRBY 子命令在發(fā)生溢出情況時(shí)的行為。
偏移量:
在二進(jìn)制位范圍命令中, 用戶有兩種方法來(lái)設(shè)置偏移量:
如果用戶給定的是一個(gè)沒(méi)有任何前綴的數(shù)字, 那么這個(gè)數(shù)字指示的就是字符串以零為開(kāi)始(zero-base)的偏移量。
另一方面, 如果用戶給定的是一個(gè)帶有 # 前綴的偏移量, 那么命令將使用這個(gè)偏移量與被設(shè)置的數(shù)字類(lèi)型的位長(zhǎng)度相乘, 從而計(jì)算出真正的偏移量。
比如說(shuō), 對(duì)于以下這個(gè)命令來(lái)說(shuō):
BITFIELD mystring SET i8 #0 100 i8 #1 200
命令會(huì)把 mystring 鍵里面, 第一個(gè) i8 長(zhǎng)度的二進(jìn)制位的值設(shè)置為 100 , 并把第二個(gè) i8 長(zhǎng)度的二進(jìn)制位的值設(shè)置為 200 。 當(dāng)我們把一個(gè)字符串鍵當(dāng)成數(shù)組來(lái)使用, 并且數(shù)組中儲(chǔ)存的都是同等長(zhǎng)度的整數(shù)時(shí), 使用 # 前綴可以讓我們免去手動(dòng)計(jì)算被設(shè)置二進(jìn)制位所在位置的麻煩。
溢出控制:
用戶可以通過(guò) OVERFLOW 命令以及以下展示的三個(gè)參數(shù), 指定 BITFIELD 命令在執(zhí)行自增或者自減操作時(shí), 碰上向上溢出(overflow)或者向下溢出(underflow)情況時(shí)的行為:
WRAP : 使用回繞(wrap around)方法處理有符號(hào)整數(shù)和無(wú)符號(hào)整數(shù)的溢出情況。 對(duì)于無(wú)符號(hào)整數(shù)來(lái)說(shuō), 回繞就像使用數(shù)值本身與能夠被儲(chǔ)存的最大無(wú)符號(hào)整數(shù)執(zhí)行取模計(jì)算, 這也是 C 語(yǔ)言的標(biāo)準(zhǔn)行為。 對(duì)于有符號(hào)整數(shù)來(lái)說(shuō), 上溢將導(dǎo)致數(shù)字重新從最小的負(fù)數(shù)開(kāi)始計(jì)算, 而下溢將導(dǎo)致數(shù)字重新從最大的正數(shù)開(kāi)始計(jì)算。 比如說(shuō), 如果我們對(duì)一個(gè)值為 127 的 i8 整數(shù)執(zhí)行加一操作, 那么將得到結(jié)果 -128 。
SAT : 使用飽和計(jì)算(saturation arithmetic)方法處理溢出, 也即是說(shuō), 下溢計(jì)算的結(jié)果為最小的整數(shù)值, 而上溢計(jì)算的結(jié)果為最大的整數(shù)值。 舉個(gè)例子, 如果我們對(duì)一個(gè)值為 120 的 i8 整數(shù)執(zhí)行加 10 計(jì)算, 那么命令的結(jié)果將為 i8 類(lèi)型所能儲(chǔ)存的最大整數(shù)值 127 。 與此相反, 如果一個(gè)針對(duì) i8 值的計(jì)算造成了下溢, 那么這個(gè) i8 值將被設(shè)置為 -127 。
FAIL : 在這一模式下, 命令將拒絕執(zhí)行那些會(huì)導(dǎo)致上溢或者下溢情況出現(xiàn)的計(jì)算, 并向用戶返回空值表示計(jì)算未被執(zhí)行。
需要注意的是, OVERFLOW 子命令只會(huì)對(duì)緊隨著它之后被執(zhí)行的 INCRBY 命令產(chǎn)生效果, 這一效果將一直持續(xù)到與它一同被執(zhí)行的下一個(gè) OVERFLOW 命令為止。 在默認(rèn)情況下, INCRBY 命令使用 WRAP 方式來(lái)處理溢出計(jì)算。
以下是一個(gè)使用 OVERFLOW 子命令來(lái)控制溢出行為的例子:
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 1
2) (integer) 1
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 2
2) (integer) 2
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 3
2) (integer) 3
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 0 -- 使用默認(rèn)的 WRAP 方式處理溢出
2) (integer) 3 -- 使用 SAT 方式處理溢出
而以下則是一個(gè)因?yàn)?OVERFLOW FAIL 行為而導(dǎo)致子命令返回空值的例子:
> BITFIELD mykey OVERFLOW FAIL incrby u2 102 1
1) (nil)
性能注意事項(xiàng):
BITFIELD 在一般情況下都是一個(gè)快速的命令, 需要注意的是, 訪問(wèn)一個(gè)長(zhǎng)度較短的字符串的遠(yuǎn)端二進(jìn)制位將引發(fā)一次內(nèi)存分配操作, 這一操作花費(fèi)的時(shí)間可能會(huì)比命令訪問(wèn)已有的字符串花費(fèi)的時(shí)間要長(zhǎng)。
二進(jìn)制位的排列:
BITFIELD 把位圖第一個(gè)字節(jié)偏移量 0 上的二進(jìn)制位看作是 most significant 位, 以此類(lèi)推。 舉個(gè)例子, 如果我們對(duì)一個(gè)已經(jīng)預(yù)先被全部設(shè)置為 0 的位圖進(jìn)行設(shè)置, 將它在偏移量 7 的值設(shè)置為 5 位無(wú)符號(hào)整數(shù)值 23 (二進(jìn)制位為 10111 ), 那么命令將生產(chǎn)出以下這個(gè)位圖表示:
+--------+--------+
|00000001|01110000|
+--------+--------+
當(dāng)偏移量和整數(shù)長(zhǎng)度與字節(jié)邊界進(jìn)行對(duì)齊時(shí), BITFIELD 表示二進(jìn)制位的方式跟大端表示法(big endian)一致, 但是在沒(méi)有對(duì)齊的情況下, 理解這些二進(jìn)制位是如何進(jìn)行排列也是非常重要的。
|