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
hiredis
Commits
3f0394b8
Commit
3f0394b8
authored
Oct 31, 2010
by
Pieter Noordhuis
Browse files
Use a fixed size stack instead of a dynamic list for read tasks
parent
8a80b892
Changes
2
Show whitespace changes
Inline
Side-by-side
hiredis.c
View file @
3f0394b8
...
@@ -47,9 +47,8 @@ typedef struct redisReader {
...
@@ -47,9 +47,8 @@ typedef struct redisReader {
sds
buf
;
/* read buffer */
sds
buf
;
/* read buffer */
unsigned
int
pos
;
/* buffer cursor */
unsigned
int
pos
;
/* buffer cursor */
redisReadTask
*
rlist
;
/* list of items to process */
redisReadTask
rstack
[
3
];
/* stack of read tasks */
unsigned
int
rlen
;
/* list length */
int
ridx
;
/* index of stack */
unsigned
int
rpos
;
/* list cursor */
}
redisReader
;
}
redisReader
;
static
redisReply
*
createReplyObject
(
int
type
);
static
redisReply
*
createReplyObject
(
int
type
);
...
@@ -183,8 +182,33 @@ static char *readLine(redisReader *r, int *_len) {
...
@@ -183,8 +182,33 @@ static char *readLine(redisReader *r, int *_len) {
return
NULL
;
return
NULL
;
}
}
static
void
moveToNextTask
(
redisReader
*
r
)
{
redisReadTask
*
cur
,
*
prv
;
assert
(
r
->
ridx
>=
0
);
/* Return a.s.a.p. when the stack is now empty. */
if
(
r
->
ridx
==
0
)
{
r
->
ridx
--
;
return
;
}
cur
=
&
(
r
->
rstack
[
r
->
ridx
]);
prv
=
&
(
r
->
rstack
[
r
->
ridx
-
1
]);
assert
(
prv
->
type
==
REDIS_REPLY_ARRAY
);
if
(
cur
->
idx
==
prv
->
elements
-
1
)
{
r
->
ridx
--
;
moveToNextTask
(
r
);
}
else
{
/* Reset the type because the next item can be anything */
assert
(
cur
->
idx
<
prv
->
elements
);
cur
->
type
=
-
1
;
cur
->
elements
=
-
1
;
cur
->
idx
++
;
}
}
static
int
processLineItem
(
redisReader
*
r
)
{
static
int
processLineItem
(
redisReader
*
r
)
{
redisReadTask
*
cur
=
&
(
r
->
r
li
st
[
r
->
r
pos
]);
redisReadTask
*
cur
=
&
(
r
->
rst
ack
[
r
->
r
idx
]);
void
*
obj
;
void
*
obj
;
char
*
p
;
char
*
p
;
int
len
;
int
len
;
...
@@ -199,14 +223,14 @@ static int processLineItem(redisReader *r) {
...
@@ -199,14 +223,14 @@ static int processLineItem(redisReader *r) {
/* If there is no root yet, register this object as root. */
/* If there is no root yet, register this object as root. */
if
(
r
->
reply
==
NULL
)
if
(
r
->
reply
==
NULL
)
r
->
reply
=
obj
;
r
->
reply
=
obj
;
r
->
rpos
++
;
moveToNextTask
(
r
)
;
return
0
;
return
0
;
}
}
return
-
1
;
return
-
1
;
}
}
static
int
processBulkItem
(
redisReader
*
r
)
{
static
int
processBulkItem
(
redisReader
*
r
)
{
redisReadTask
*
cur
=
&
(
r
->
r
li
st
[
r
->
r
pos
]);
redisReadTask
*
cur
=
&
(
r
->
rst
ack
[
r
->
r
idx
]);
void
*
obj
=
NULL
;
void
*
obj
=
NULL
;
char
*
p
,
*
s
;
char
*
p
,
*
s
;
long
len
;
long
len
;
...
@@ -235,7 +259,7 @@ static int processBulkItem(redisReader *r) {
...
@@ -235,7 +259,7 @@ static int processBulkItem(redisReader *r) {
r
->
pos
+=
bytelen
;
r
->
pos
+=
bytelen
;
if
(
r
->
reply
==
NULL
)
if
(
r
->
reply
==
NULL
)
r
->
reply
=
obj
;
r
->
reply
=
obj
;
r
->
rpos
++
;
moveToNextTask
(
r
)
;
return
0
;
return
0
;
}
}
}
}
...
@@ -243,53 +267,42 @@ static int processBulkItem(redisReader *r) {
...
@@ -243,53 +267,42 @@ static int processBulkItem(redisReader *r) {
}
}
static
int
processMultiBulkItem
(
redisReader
*
r
)
{
static
int
processMultiBulkItem
(
redisReader
*
r
)
{
redisReadTask
*
cur
=
&
(
r
->
r
li
st
[
r
->
r
pos
]);
redisReadTask
*
cur
=
&
(
r
->
rst
ack
[
r
->
r
idx
]);
void
*
obj
;
void
*
obj
;
char
*
p
;
char
*
p
;
long
elements
,
j
;
long
elements
;
if
((
p
=
readLine
(
r
,
NULL
))
!=
NULL
)
{
if
((
p
=
readLine
(
r
,
NULL
))
!=
NULL
)
{
elements
=
strtol
(
p
,
NULL
,
10
);
elements
=
strtol
(
p
,
NULL
,
10
);
if
(
elements
==
-
1
)
{
if
(
elements
==
-
1
)
{
obj
=
r
->
fn
->
createNil
(
cur
);
obj
=
r
->
fn
->
createNil
(
cur
);
moveToNextTask
(
r
);
}
else
{
}
else
{
obj
=
r
->
fn
->
createArray
(
cur
,
elements
);
obj
=
r
->
fn
->
createArray
(
cur
,
elements
);
/* Modify
read list
when there are more than 0 elements. */
/* Modify
task stack
when there are more than 0 elements. */
if
(
elements
>
0
)
{
if
(
elements
>
0
)
{
/* Append elements to the read list. */
cur
->
elements
=
elements
;
r
->
rlen
+=
elements
;
r
->
ridx
++
;
if
((
r
->
rlist
=
realloc
(
r
->
rlist
,
sizeof
(
redisReadTask
)
*
r
->
rlen
))
==
NULL
)
r
->
rstack
[
r
->
ridx
].
type
=
-
1
;
redisOOM
();
r
->
rstack
[
r
->
ridx
].
elements
=
-
1
;
r
->
rstack
[
r
->
ridx
].
parent
=
obj
;
/* Move existing items backwards. */
r
->
rstack
[
r
->
ridx
].
idx
=
0
;
memmove
(
&
(
r
->
rlist
[
r
->
rpos
+
1
+
elements
]),
}
else
{
&
(
r
->
rlist
[
r
->
rpos
+
1
]),
moveToNextTask
(
r
);
(
r
->
rlen
-
(
r
->
rpos
+
1
+
elements
))
*
sizeof
(
redisReadTask
));
/* Populate new read items. */
redisReadTask
*
t
;
for
(
j
=
0
;
j
<
elements
;
j
++
)
{
t
=
&
(
r
->
rlist
[
r
->
rpos
+
1
+
j
]);
t
->
type
=
-
1
;
t
->
parent
=
obj
;
t
->
idx
=
j
;
}
}
}
}
}
if
(
obj
!=
NULL
)
{
/* Object was created, so we can always continue. */
if
(
r
->
reply
==
NULL
)
if
(
r
->
reply
==
NULL
)
r
->
reply
=
obj
;
r
->
reply
=
obj
;
r
->
rpos
++
;
return
0
;
return
0
;
}
}
}
return
-
1
;
return
-
1
;
}
}
static
int
processItem
(
redisReader
*
r
)
{
static
int
processItem
(
redisReader
*
r
)
{
redisReadTask
*
cur
=
&
(
r
->
r
li
st
[
r
->
r
pos
]);
redisReadTask
*
cur
=
&
(
r
->
rst
ack
[
r
->
r
idx
]);
char
*
p
;
char
*
p
;
sds
byte
;
sds
byte
;
...
@@ -347,7 +360,7 @@ void *redisReplyReaderCreate(redisReplyObjectFunctions *fn) {
...
@@ -347,7 +360,7 @@ void *redisReplyReaderCreate(redisReplyObjectFunctions *fn) {
r
->
error
=
NULL
;
r
->
error
=
NULL
;
r
->
fn
=
fn
==
NULL
?
&
defaultFunctions
:
fn
;
r
->
fn
=
fn
==
NULL
?
&
defaultFunctions
:
fn
;
r
->
buf
=
sdsempty
();
r
->
buf
=
sdsempty
();
r
->
r
list
=
malloc
(
sizeof
(
redisReadTask
)
*
1
)
;
r
->
r
idx
=
-
1
;
return
r
;
return
r
;
}
}
...
@@ -368,8 +381,6 @@ void redisReplyReaderFree(void *reader) {
...
@@ -368,8 +381,6 @@ void redisReplyReaderFree(void *reader) {
r
->
fn
->
freeObject
(
r
->
reply
);
r
->
fn
->
freeObject
(
r
->
reply
);
if
(
r
->
buf
!=
NULL
)
if
(
r
->
buf
!=
NULL
)
sdsfree
(
r
->
buf
);
sdsfree
(
r
->
buf
);
if
(
r
->
rlist
!=
NULL
)
free
(
r
->
rlist
);
free
(
r
);
free
(
r
);
}
}
...
@@ -383,7 +394,7 @@ static void redisSetReplyReaderError(redisReader *r, sds err) {
...
@@ -383,7 +394,7 @@ static void redisSetReplyReaderError(redisReader *r, sds err) {
r
->
buf
=
sdsempty
();
r
->
buf
=
sdsempty
();
r
->
pos
=
0
;
r
->
pos
=
0
;
}
}
r
->
r
len
=
r
->
rpos
=
0
;
r
->
r
idx
=
-
1
;
r
->
error
=
err
;
r
->
error
=
err
;
}
}
...
@@ -408,18 +419,17 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
...
@@ -408,18 +419,17 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
if
(
sdslen
(
r
->
buf
)
==
0
)
if
(
sdslen
(
r
->
buf
)
==
0
)
return
REDIS_OK
;
return
REDIS_OK
;
/* Create first item to process when the item list is empty. */
/* Set first item to process when the stack is empty. */
if
(
r
->
rlen
==
0
)
{
if
(
r
->
ridx
==
-
1
)
{
r
->
rlist
=
realloc
(
r
->
rlist
,
sizeof
(
redisReadTask
)
*
1
);
r
->
rstack
[
0
].
type
=
-
1
;
r
->
rlist
[
0
].
type
=
-
1
;
r
->
rstack
[
0
].
elements
=
-
1
;
r
->
rlist
[
0
].
parent
=
NULL
;
r
->
rstack
[
0
].
parent
=
NULL
;
r
->
rlist
[
0
].
idx
=
-
1
;
r
->
rstack
[
0
].
idx
=
-
1
;
r
->
rlen
=
1
;
r
->
ridx
=
0
;
r
->
rpos
=
0
;
}
}
/* Process items in reply. */
/* Process items in reply. */
while
(
r
->
r
pos
<
r
->
rlen
)
while
(
r
->
r
idx
>=
0
)
if
(
processItem
(
r
)
<
0
)
if
(
processItem
(
r
)
<
0
)
break
;
break
;
...
@@ -436,7 +446,7 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
...
@@ -436,7 +446,7 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
}
}
/* Emit a reply when there is one. */
/* Emit a reply when there is one. */
if
(
r
->
r
pos
==
r
->
rlen
)
{
if
(
r
->
r
idx
==
-
1
)
{
void
*
aux
=
r
->
reply
;
void
*
aux
=
r
->
reply
;
r
->
reply
=
NULL
;
r
->
reply
=
NULL
;
...
@@ -447,9 +457,6 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
...
@@ -447,9 +457,6 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
r
->
pos
=
0
;
r
->
pos
=
0
;
}
}
/* Set list of items to read to be empty. */
r
->
rlen
=
r
->
rpos
=
0
;
/* Check if there actually *is* a reply. */
/* Check if there actually *is* a reply. */
if
(
r
->
error
!=
NULL
)
{
if
(
r
->
error
!=
NULL
)
{
return
REDIS_ERR
;
return
REDIS_ERR
;
...
...
hiredis.h
View file @
3f0394b8
...
@@ -61,6 +61,7 @@ typedef struct redisReply {
...
@@ -61,6 +61,7 @@ typedef struct redisReply {
typedef
struct
redisReadTask
{
typedef
struct
redisReadTask
{
int
type
;
int
type
;
int
elements
;
/* number of elements in multibulk container */
void
*
parent
;
/* optional pointer to parent object */
void
*
parent
;
/* optional pointer to parent object */
int
idx
;
/* index in parent (array) object */
int
idx
;
/* index in parent (array) object */
}
redisReadTask
;
}
redisReadTask
;
...
...
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