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
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