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
8c304be3
Commit
8c304be3
authored
Dec 14, 2010
by
antirez
Browse files
cow friendly HGETALL and variants
parent
5ce3a24d
Changes
3
Show whitespace changes
Inline
Side-by-side
src/debug.c
View file @
8c304be3
...
...
@@ -152,10 +152,10 @@ void computeDatasetDigest(unsigned char *final) {
unsigned
char
eledigest
[
20
];
memset
(
eledigest
,
0
,
20
);
obj
=
hashTypeCurrent
(
hi
,
REDIS_HASH_KEY
);
obj
=
hashTypeCurrent
Object
(
hi
,
REDIS_HASH_KEY
);
mixObjectDigest
(
eledigest
,
obj
);
decrRefCount
(
obj
);
obj
=
hashTypeCurrent
(
hi
,
REDIS_HASH_VALUE
);
obj
=
hashTypeCurrent
Object
(
hi
,
REDIS_HASH_VALUE
);
mixObjectDigest
(
eledigest
,
obj
);
decrRefCount
(
obj
);
xorDigest
(
digest
,
eledigest
,
20
);
...
...
src/redis.h
View file @
8c304be3
...
...
@@ -832,7 +832,8 @@ unsigned long hashTypeLength(robj *o);
hashTypeIterator
*
hashTypeInitIterator
(
robj
*
subject
);
void
hashTypeReleaseIterator
(
hashTypeIterator
*
hi
);
int
hashTypeNext
(
hashTypeIterator
*
hi
);
robj
*
hashTypeCurrent
(
hashTypeIterator
*
hi
,
int
what
);
int
hashTypeCurrent
(
hashTypeIterator
*
hi
,
int
what
,
robj
**
objval
,
unsigned
char
**
v
,
unsigned
int
*
vlen
);
robj
*
hashTypeCurrentObject
(
hashTypeIterator
*
hi
,
int
what
);
robj
*
hashTypeLookupWriteOrCreate
(
redisClient
*
c
,
robj
*
key
);
/* Pub / Sub */
...
...
src/t_hash.c
View file @
8c304be3
...
...
@@ -185,24 +185,50 @@ int hashTypeNext(hashTypeIterator *hi) {
}
/* Get key or value object at current iteration position.
* This increases the refcount of the field object by 1. */
robj
*
hashTypeCurrent
(
hashTypeIterator
*
hi
,
int
what
)
{
robj
*
o
;
* The returned item differs with the hash object encoding:
* - When encoding is REDIS_ENCODING_HT, the objval pointer is populated
* with the original object.
* - When encoding is REDIS_ENCODING_ZIPMAP, a pointer to the string and
* its length is retunred populating the v and vlen pointers.
* This function is copy on write friendly as accessing objects in read only
* does not require writing to any memory page.
*
* The function returns the encoding of the object, so that the caller
* can underestand if the key or value was returned as object or C string. */
int
hashTypeCurrent
(
hashTypeIterator
*
hi
,
int
what
,
robj
**
objval
,
unsigned
char
**
v
,
unsigned
int
*
vlen
)
{
if
(
hi
->
encoding
==
REDIS_ENCODING_ZIPMAP
)
{
if
(
what
&
REDIS_HASH_KEY
)
{
o
=
createStringObject
((
char
*
)
hi
->
zk
,
hi
->
zklen
);
*
v
=
hi
->
zk
;
*
vlen
=
hi
->
zklen
;
}
else
{
o
=
createStringObject
((
char
*
)
hi
->
zv
,
hi
->
zvlen
);
*
v
=
hi
->
zv
;
*
vlen
=
hi
->
zvlen
;
}
}
else
{
if
(
what
&
REDIS_HASH_KEY
)
{
o
=
dictGetEntryKey
(
hi
->
de
);
}
else
{
o
=
dictGetEntryVal
(
hi
->
de
);
if
(
what
&
REDIS_HASH_KEY
)
*
objval
=
dictGetEntryKey
(
hi
->
de
);
else
*
objval
=
dictGetEntryVal
(
hi
->
de
);
}
incrRefCount
(
o
);
return
hi
->
encoding
;
}
/* A non copy-on-write friendly but higher level version of hashTypeCurrent()
* that always returns an object with refcount incremented by one (or a new
* object), so it's up to the caller to decrRefCount() the object if no
* reference is retained. */
robj
*
hashTypeCurrentObject
(
hashTypeIterator
*
hi
,
int
what
)
{
robj
*
obj
;
unsigned
char
*
v
;
unsigned
int
vlen
;
int
encoding
=
hashTypeCurrent
(
hi
,
what
,
&
obj
,
&
v
,
&
vlen
);
if
(
encoding
==
REDIS_ENCODING_HT
)
{
incrRefCount
(
obj
);
return
obj
;
}
else
{
return
createStringObject
((
char
*
)
v
,
vlen
);
}
return
o
;
}
robj
*
hashTypeLookupWriteOrCreate
(
redisClient
*
c
,
robj
*
key
)
{
...
...
@@ -392,7 +418,7 @@ void hlenCommand(redisClient *c) {
}
void
genericHgetallCommand
(
redisClient
*
c
,
int
flags
)
{
robj
*
o
,
*
obj
;
robj
*
o
;
unsigned
long
count
=
0
;
hashTypeIterator
*
hi
;
void
*
replylen
=
NULL
;
...
...
@@ -403,16 +429,25 @@ void genericHgetallCommand(redisClient *c, int flags) {
replylen
=
addDeferredMultiBulkLength
(
c
);
hi
=
hashTypeInitIterator
(
o
);
while
(
hashTypeNext
(
hi
)
!=
REDIS_ERR
)
{
robj
*
obj
;
unsigned
char
*
v
;
unsigned
int
vlen
;
int
encoding
;
if
(
flags
&
REDIS_HASH_KEY
)
{
obj
=
hashTypeCurrent
(
hi
,
REDIS_HASH_KEY
);
encoding
=
hashTypeCurrent
(
hi
,
REDIS_HASH_KEY
,
&
obj
,
&
v
,
&
vlen
);
if
(
encoding
==
REDIS_ENCODING_HT
)
addReplyBulk
(
c
,
obj
);
decrRefCount
(
obj
);
else
addReplyBulkCBuffer
(
c
,
v
,
vlen
);
count
++
;
}
if
(
flags
&
REDIS_HASH_VALUE
)
{
obj
=
hashTypeCurrent
(
hi
,
REDIS_HASH_VALUE
);
encoding
=
hashTypeCurrent
(
hi
,
REDIS_HASH_VALUE
,
&
obj
,
&
v
,
&
vlen
);
if
(
encoding
==
REDIS_ENCODING_HT
)
addReplyBulk
(
c
,
obj
);
decrRefCount
(
obj
);
else
addReplyBulkCBuffer
(
c
,
v
,
vlen
);
count
++
;
}
}
...
...
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