位圖,這塊怎麼理解呢?其實我個人也沒怎麼用過,只是從公衆號、博客上多多少少瞭解到一點信息。
我對位圖的理解,可以從字面意思去理解,這裏強調“位”,感覺就是用來存儲0/1的數組。看看了官方介紹,位圖其實就是普通的字符串,也就是byte數組。
位數數組是自動擴展的,如果設置了某個偏移位置超出了現有的內容範圍,就會自動將位數組進行擴充並全部填充0
位圖其實就是把字符轉成byte格式,而1B=8b,正好是0/1方式,然後把1填充到數組中(該數組默認所有值都是0)。
常用指令:
①getbit/setbit
②bitcount:統計指定位置範圍內1的個數
③bitpos:查找指定範圍內出現的第一個0或1。
④注意事項:bitcount和bitpos都可以指定範圍參數[start, end],start和end參數是字節索引,也就是說指定的位範圍必須是8的倍數,即start和end指定的範圍是:8 * 指定的數字。
⑤bitfield:由於getbit/setbit一次性只能操作一個位,因此爲了方便一次性批量操作多個位,Redis3.2版本新增bitfield,其最多也就處理64個連續位,如果超過64位,就得使用多個子指令,bitfield可以一次執行多個子指令。
bitfield有三個子指令:get/set/incrby。
get指令,需要指明無符號數u還是有符號數i,所謂有符號數是指獲取的位數組中第一個位是符號位,剩下的纔是值。如果第一位是 1,那就是負數。無符號數表示非負數,沒有符號位,獲取的位數組全部都是值。有符號數最多可以獲取 64 位,無符號數只能獲取63位。如果超出位數限制,Redis拋出參數錯誤。
incrby指令,它用來對指定範圍的位進行自增/自減。自增就有可能出現溢出,如果增加正數會出現上溢,如果增加負數就會出現下溢出。Redis默認的處理方式是:如果出現了溢出,就將溢出的符號位丟掉。如果是8位無符號數255加1後就會溢出則全部變零。如果是 8位有符號數127加1後就會溢出變成-128。
針對這種溢出情況,bitfield指令另外提供溢出策略子指令overflow,可以選擇自己想要的溢出行爲:默認是折返(wrap)、失敗(fail) 報錯不執行、飽和截斷 (sat)超過了範圍就停留在最大最小值。只不過overflow 指令隻影響接下來的第一條指令,這條指令執行完後溢出策略會變成默認值折返 (wrap)。