今天5.1第二天,来讲讲redis当中的bit操作,首先,先简单介绍以下redis当中的位操作的命令
命令
|
解释
|
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);
-
}
其余的操作就非常类似了,就不再贴出来了~
阅读(2143) | 评论(0) | 转发(0) |