mirror of
http://github.com/valkey-io/valkey
synced 2024-11-22 00:52:38 +00:00
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.
This commit is contained in:
parent
9f9e1ceaa0
commit
ef11bcccca
@ -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 {}
|
||||
|
Loading…
Reference in New Issue
Block a user