命令 | 解释 |
SETBIT key offset 0|1 | 将key存储的值的对应的二进制位设置为0或者1 |
GETBIT key offset | 将key存储的值的对应的二进制位的值返回 |
BITCOUNT key | 统计key存储的值当中,二进制位当中1的个数 |
BITOP AND|OR|XOR|NOT destkey srckey1 srckey2 ... srckeyn | 将多组key中存储的值按照选项操作,操作的结果存储在destkey当中 |
其中key对应的值的存储方式是redis当中的sds字符串
在实际操作当中,redis会把存储的sds字符串当做二进制数组,但是实际保存位数组的顺序和书写数组的顺序是相反的,如下

所以根据输入的offset在相应的sds当中找到对应的位的计算方式也就出来了
idx_of_byte = [offset / 8]
idx_of_bit = [offset mod 8] + 1
这里仅列出set操作的代码:
点击(此处)折叠或打开
- /* SETBIT key offset bitvalue */
- void setbitCommand(client *c) {
- robj *o;
- char *err = "bit is not an integer or out of range";
- size_t bitoffset;
- ssize_t byte, bit;
- int byteval, bitval;
- long on;
- if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset,0,0) != C_OK)
- return;
- if (getLongFromObjectOrReply(c,c->argv[3],&on,err) != C_OK)
- return;
- /* Bits can only be set or cleared... */
- if (on & ~1) {
- addReplyError(c,err);
- return;
- }
- if ((o = lookupStringForBitCommand(c,bitoffset)) == NULL) return;
- /* Get current values */
- byte = bitoffset >> 3;
- byteval = ((uint8_t*)o->ptr)[byte];
- bit = 7 - (bitoffset & 0x7);
- bitval = byteval & (1 << bit);
- /* Update byte with new bit value and return original value */
- byteval &= ~(1 << bit);
- byteval |= ((on & 0x1) << bit);
- ((uint8_t*)o->ptr)[byte] = byteval;
- signalModifiedKey(c->db,c->argv[1]);
- notifyKeyspaceEvent(NOTIFY_STRING,"setbit",c->argv[1],c->db->id);
- server.dirty++;
- addReply(c, bitval ? shared.cone : shared.czero);
- }
其余的操作就非常类似了,就不再贴出来了~