提交 ef11bccc 编写于 作者: P Pieter Noordhuis

Refactor and rename SUBSTR to GETRANGE

SUBSTR is renamed to GETRANGE to have better consistency between command
names (with SETRANGE as its dual). GETRANGE is still aliased as SUBSTR.
上级 9f9e1cea
......@@ -74,13 +74,14 @@ struct redisCommand readonlyCommandTable[] = {
{"setnx",setnxCommand,3,REDIS_CMD_DENYOOM,NULL,0,0,0},
{"setex",setexCommand,4,REDIS_CMD_DENYOOM,NULL,0,0,0},
{"append",appendCommand,3,REDIS_CMD_DENYOOM,NULL,1,1,1},
{"substr",substrCommand,4,0,NULL,1,1,1},
{"strlen",strlenCommand,2,0,NULL,1,1,1},
{"del",delCommand,-2,0,NULL,0,0,0},
{"exists",existsCommand,2,0,NULL,1,1,1},
{"setbit",setbitCommand,4,REDIS_CMD_DENYOOM,NULL,1,1,1},
{"getbit",getbitCommand,3,0,NULL,1,1,1},
{"setrange",setrangeCommand,4,REDIS_CMD_DENYOOM,NULL,1,1,1},
{"getrange",getrangeCommand,4,0,NULL,1,1,1},
{"substr",getrangeCommand,4,0,NULL,1,1,1},
{"incr",incrCommand,2,REDIS_CMD_DENYOOM,NULL,1,1,1},
{"decr",decrCommand,2,REDIS_CMD_DENYOOM,NULL,1,1,1},
{"mget",mgetCommand,-2,0,NULL,1,-1,1},
......
......@@ -890,6 +890,7 @@ void existsCommand(redisClient *c);
void setbitCommand(redisClient *c);
void getbitCommand(redisClient *c);
void setrangeCommand(redisClient *c);
void getrangeCommand(redisClient *c);
void incrCommand(redisClient *c);
void decrCommand(redisClient *c);
void incrbyCommand(redisClient *c);
......@@ -967,7 +968,6 @@ void discardCommand(redisClient *c);
void blpopCommand(redisClient *c);
void brpopCommand(redisClient *c);
void appendCommand(redisClient *c);
void substrCommand(redisClient *c);
void strlenCommand(redisClient *c);
void zrankCommand(redisClient *c);
void zrevrankCommand(redisClient *c);
......
......@@ -257,6 +257,43 @@ void setrangeCommand(redisClient *c) {
addReplyLongLong(c,sdslen(o->ptr));
}
void getrangeCommand(redisClient *c) {
robj *o;
long start, end;
char *str, llbuf[32];
size_t strlen;
if (getLongFromObjectOrReply(c,c->argv[2],&start,NULL) != REDIS_OK)
return;
if (getLongFromObjectOrReply(c,c->argv[3],&end,NULL) != REDIS_OK)
return;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,o,REDIS_STRING)) return;
if (o->encoding == REDIS_ENCODING_INT) {
str = llbuf;
strlen = ll2string(llbuf,sizeof(llbuf),(long)o->ptr);
} else {
str = o->ptr;
strlen = sdslen(str);
}
/* Convert negative indexes */
if (start < 0) start = strlen+start;
if (end < 0) end = strlen+end;
if (start < 0) start = 0;
if (end < 0) end = 0;
if ((unsigned)end >= strlen) end = strlen-1;
/* Precondition: end >= 0 && end < strlen, so the only condition where
* nothing can be returned is: start > end. */
if (start > end) {
addReply(c,shared.nullbulk);
} else {
addReplyBulkCBuffer(c,(char*)str+start,end-start+1);
}
}
void mgetCommand(redisClient *c) {
int j;
......@@ -400,43 +437,6 @@ void appendCommand(redisClient *c) {
addReplyLongLong(c,totlen);
}
void substrCommand(redisClient *c) {
robj *o;
long start = atoi(c->argv[2]->ptr);
long end = atoi(c->argv[3]->ptr);
size_t rangelen, strlen;
sds range;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,o,REDIS_STRING)) return;
o = getDecodedObject(o);
strlen = sdslen(o->ptr);
/* convert negative indexes */
if (start < 0) start = strlen+start;
if (end < 0) end = strlen+end;
if (start < 0) start = 0;
if (end < 0) end = 0;
/* indexes sanity checks */
if (start > end || (size_t)start >= strlen) {
/* Out of range start or start > end result in null reply */
addReply(c,shared.nullbulk);
decrRefCount(o);
return;
}
if ((size_t)end >= strlen) end = strlen-1;
rangelen = (end-start)+1;
/* Return the result */
addReplySds(c,sdscatprintf(sdsempty(),"$%zu\r\n",rangelen));
range = sdsnewlen((char*)o->ptr+start,rangelen);
addReplySds(c,range);
addReply(c,shared.crlf);
decrRefCount(o);
}
void strlenCommand(redisClient *c) {
robj *o;
......
......@@ -562,4 +562,40 @@ start_server {tags {"basic"}} {
r set mykey "hello"
assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
}
test {SUBSTR basics} {
set res {}
r set foo "Hello World"
lappend res [r substr foo 0 3]
lappend res [r substr foo 0 -1]
lappend res [r substr foo -4 -1]
lappend res [r substr foo 5 3]
lappend res [r substr foo 5 5000]
lappend res [r substr foo -5000 10000]
set _ $res
} {Hell {Hello World} orld {} { World} {Hello World}}
test {SUBSTR against integer encoded values} {
r set foo 123
r substr foo 0 -2
} {12}
test {SUBSTR fuzzing} {
set err {}
for {set i 0} {$i < 1000} {incr i} {
set bin [randstring 0 1024 binary]
set _start [set start [randomInt 1500]]
set _end [set end [randomInt 1500]]
if {$_start < 0} {set _start "end-[abs($_start)-1]"}
if {$_end < 0} {set _end "end-[abs($_end)-1]"}
set s1 [string range $bin $_start $_end]
r set bin $bin
set s2 [r substr bin $start $end]
if {$s1 != $s2} {
set err "String mismatch"
break
}
}
set _ $err
} {}
}
......@@ -216,42 +216,6 @@ start_server {tags {"other"}} {
set _ $err
} {}
test {SUBSTR basics} {
set res {}
r set foo "Hello World"
lappend res [r substr foo 0 3]
lappend res [r substr foo 0 -1]
lappend res [r substr foo -4 -1]
lappend res [r substr foo 5 3]
lappend res [r substr foo 5 5000]
lappend res [r substr foo -5000 10000]
set _ $res
} {Hell {Hello World} orld {} { World} {Hello World}}
test {SUBSTR against integer encoded values} {
r set foo 123
r substr foo 0 -2
} {12}
test {SUBSTR fuzzing} {
set err {}
for {set i 0} {$i < 1000} {incr i} {
set bin [randstring 0 1024 binary]
set _start [set start [randomInt 1500]]
set _end [set end [randomInt 1500]]
if {$_start < 0} {set _start "end-[abs($_start)-1]"}
if {$_end < 0} {set _end "end-[abs($_end)-1]"}
set s1 [string range $bin $_start $_end]
r set bin $bin
set s2 [r substr bin $start $end]
if {$s1 != $s2} {
set err "String mismatch"
break
}
}
set _ $err
} {}
# Leave the user with a clean DB before to exit
test {FLUSHDB} {
set aux {}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册