Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
01426b05
Commit
01426b05
authored
Mar 26, 2010
by
Pieter Noordhuis
Browse files
implements HINCRBY and tests (todo: find and fix small memleak)
parent
b61a28fe
Changes
3
Hide whitespace changes
Inline
Side-by-side
redis-cli.c
View file @
01426b05
...
@@ -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 @
01426b05
...
@@ -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
},
...
@@ -5954,6 +5956,82 @@ static void hsetCommand(redisClient *c) {
...
@@ -5954,6 +5956,82 @@ 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
);
incrRefCount
(
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 @
01426b05
...
@@ -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