Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
570e43c8
Commit
570e43c8
authored
Mar 26, 2010
by
antirez
Browse files
Merge branch 'hincrby' of
git://github.com/pietern/redis
parents
168ac5c6
53476b82
Changes
3
Hide whitespace changes
Inline
Side-by-side
redis-cli.c
View file @
570e43c8
...
@@ -150,6 +150,7 @@ static struct redisCommand cmdTable[] = {
...
@@ -150,6 +150,7 @@ static struct redisCommand cmdTable[] = {
{
"exec"
,
1
,
REDIS_CMD_INLINE
},
{
"exec"
,
1
,
REDIS_CMD_INLINE
},
{
"discard"
,
1
,
REDIS_CMD_INLINE
},
{
"discard"
,
1
,
REDIS_CMD_INLINE
},
{
"hset"
,
4
,
REDIS_CMD_MULTIBULK
},
{
"hset"
,
4
,
REDIS_CMD_MULTIBULK
},
{
"hincrby"
,
4
,
REDIS_CMD_INLINE
},
{
"hget"
,
3
,
REDIS_CMD_BULK
},
{
"hget"
,
3
,
REDIS_CMD_BULK
},
{
"hdel"
,
3
,
REDIS_CMD_BULK
},
{
"hdel"
,
3
,
REDIS_CMD_BULK
},
{
"hlen"
,
2
,
REDIS_CMD_INLINE
},
{
"hlen"
,
2
,
REDIS_CMD_INLINE
},
...
...
redis.c
View file @
570e43c8
...
@@ -697,6 +697,7 @@ static void hvalsCommand(redisClient *c);
...
@@ -697,6 +697,7 @@ static void hvalsCommand(redisClient *c);
static void hgetallCommand(redisClient *c);
static void hgetallCommand(redisClient *c);
static void hexistsCommand(redisClient *c);
static void hexistsCommand(redisClient *c);
static void configCommand(redisClient *c);
static void configCommand(redisClient *c);
static void hincrbyCommand(redisClient *c);
/*================================= Globals ================================= */
/*================================= Globals ================================= */
...
@@ -756,6 +757,7 @@ static struct redisCommand cmdTable[] = {
...
@@ -756,6 +757,7 @@ static struct redisCommand cmdTable[] = {
{"zrank",zrankCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"zrank",zrankCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"zrevrank",zrevrankCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"zrevrank",zrevrankCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hset",hsetCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,1,1,1},
{"hset",hsetCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,1,1,1},
{"hincrby",hincrbyCommand,4,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,NULL,1,1,1},
{"hget",hgetCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hget",hgetCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hdel",hdelCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hdel",hdelCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hlen",hlenCommand,2,REDIS_CMD_INLINE,NULL,1,1,1},
{"hlen",hlenCommand,2,REDIS_CMD_INLINE,NULL,1,1,1},
...
@@ -5955,6 +5957,80 @@ static void hsetCommand(redisClient *c) {
...
@@ -5955,6 +5957,80 @@ static void hsetCommand(redisClient *c) {
addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",update == 0));
addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",update == 0));
}
}
static void hincrbyCommand(redisClient *c) {
int update = 0;
long long value = 0, incr = 0;
robj *o = lookupKeyWrite(c->db,c->argv[1]);
if (o == NULL) {
o = createHashObject();
dictAdd(c->db->dict,c->argv[1],o);
incrRefCount(c->argv[1]);
} else {
if (o->type != REDIS_HASH) {
addReply(c,shared.wrongtypeerr);
return;
}
}
robj *o_incr = getDecodedObject(c->argv[3]);
incr = strtoll(o_incr->ptr, NULL, 10);
decrRefCount(o_incr);
if (o->encoding == REDIS_ENCODING_ZIPMAP) {
unsigned char *zm = o->ptr;
unsigned char *zval;
unsigned int zvlen;
/* Find value if already present in hash */
if (zipmapGet(zm,c->argv[2]->ptr,sdslen(c->argv[2]->ptr),
&zval,&zvlen)) {
/* strtoll needs the char* to have a trailing \0, but
* the zipmap doesn't include them. */
sds szval = sdsnewlen(zval, zvlen);
value = strtoll(szval,NULL,10);
sdsfree(szval);
}
value += incr;
sds svalue = sdscatprintf(sdsempty(),"%lld",value);
zm = zipmapSet(zm,c->argv[2]->ptr,sdslen(c->argv[2]->ptr),
(unsigned char*)svalue,sdslen(svalue),&update);
sdsfree(svalue);
o->ptr = zm;
/* Check if the zipmap needs to be converted
* if this was not an update. */
if (!update && zipmapLen(zm) > server.hash_max_zipmap_entries)
convertToRealHash(o);
} else {
robj *hval;
dictEntry *de;
/* Find value if already present in hash */
de = dictFind(o->ptr,c->argv[2]);
if (de != NULL) {
hval = dictGetEntryVal(de);
if (hval->encoding == REDIS_ENCODING_RAW)
value = strtoll(hval->ptr,NULL,10);
else if (hval->encoding == REDIS_ENCODING_INT)
value = (long)hval->ptr;
else
redisAssert(1 != 1);
}
value += incr;
hval = createObject(REDIS_STRING,sdscatprintf(sdsempty(),"%lld",value));
tryObjectEncoding(hval);
if (dictReplace(o->ptr,c->argv[2],hval)) {
incrRefCount(c->argv[2]);
}
}
server.dirty++;
addReplyLong(c, value);
}
static void hgetCommand(redisClient *c) {
static void hgetCommand(redisClient *c) {
robj *o;
robj *o;
...
...
test-redis.tcl
View file @
570e43c8
...
@@ -1697,6 +1697,53 @@ proc main {server port} {
...
@@ -1697,6 +1697,53 @@ proc main {server port} {
$r debug object smallhash
$r debug object smallhash
}
{
*hashtable*
}
}
{
*hashtable*
}
test
{
HINCRBY against non existing database key
}
{
$r del htest
list
[
$r
hincrby htest foo 2
]
}
{
2
}
test
{
HINCRBY against non existing hash key
}
{
set rv
{}
$r hdel smallhash tmp
$r hdel bighash tmp
lappend rv
[
$r
hincrby smallhash tmp 2
]
lappend rv
[
$r
hget smallhash tmp
]
lappend rv
[
$r
hincrby bighash tmp 2
]
lappend rv
[
$r
hget bighash tmp
]
}
{
2 2 2 2
}
test
{
HINCRBY against hash key created by hincrby itself
}
{
set rv
{}
lappend rv
[
$r
hincrby smallhash tmp 3
]
lappend rv
[
$r
hget smallhash tmp
]
lappend rv
[
$r
hincrby bighash tmp 3
]
lappend rv
[
$r
hget bighash tmp
]
}
{
5 5 5 5
}
test
{
HINCRBY against hash key originally set with HSET
}
{
$r hset smallhash tmp 100
$r hset bighash tmp 100
list
[
$r
hincrby smallhash tmp 2
]
[
$r
hincrby bighash tmp 2
]
}
{
102 102
}
test
{
HINCRBY over 32bit value
}
{
$r hset smallhash tmp 17179869184
$r hset bighash tmp 17179869184
list
[
$r
hincrby smallhash tmp 1
]
[
$r
hincrby bighash tmp 1
]
}
{
17179869185 17179869185
}
test
{
HINCRBY over 32bit value with over 32bit increment
}
{
$r hset smallhash tmp 17179869184
$r hset bighash tmp 17179869184
list
[
$r
hincrby smallhash tmp 17179869184
]
[
$r
hincrby bighash tmp 17179869184
]
}
{
34359738368 34359738368
}
test
{
HINCRBY against key with spaces
(
no integer encoded
)}
{
$r hset smallhash tmp
" 11 "
$r hset bighash tmp
" 11 "
list
[
$r
hincrby smallhash tmp 1
]
[
$r
hincrby bighash tmp 1
]
}
{
12 12
}
# TODO:
# TODO:
# Randomized test, small and big
# Randomized test, small and big
# .rdb / AOF consistency test should include hashes
# .rdb / AOF consistency test should include hashes
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment