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
8596d483
Unverified
Commit
8596d483
authored
Jul 16, 2020
by
杨博东
Committed by
GitHub
Jul 16, 2020
Browse files
Stream avoid duplicate parse id (#7450)
parent
5f716ea4
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/t_stream.c
View file @
8596d483
...
@@ -40,6 +40,11 @@
...
@@ -40,6 +40,11 @@
#define STREAM_ITEM_FLAG_DELETED (1<<0)
/* Entry is deleted. Skip it. */
#define STREAM_ITEM_FLAG_DELETED (1<<0)
/* Entry is deleted. Skip it. */
#define STREAM_ITEM_FLAG_SAMEFIELDS (1<<1)
/* Same fields as master entry. */
#define STREAM_ITEM_FLAG_SAMEFIELDS (1<<1)
/* Same fields as master entry. */
/* For stream commands that require multiple IDs
* when the number of IDs is less than 'STREAMID_STATIC_VECTOR_LEN',
* avoid malloc allocation.*/
#define STREAMID_STATIC_VECTOR_LEN 8
void
streamFreeCG
(
streamCG
*
cg
);
void
streamFreeCG
(
streamCG
*
cg
);
void
streamFreeNACK
(
streamNACK
*
na
);
void
streamFreeNACK
(
streamNACK
*
na
);
size_t
streamReplyWithRangeFromConsumerPEL
(
client
*
c
,
stream
*
s
,
streamID
*
start
,
streamID
*
end
,
size_t
count
,
streamConsumer
*
consumer
);
size_t
streamReplyWithRangeFromConsumerPEL
(
client
*
c
,
stream
*
s
,
streamID
*
start
,
streamID
*
end
,
size_t
count
,
streamConsumer
*
consumer
);
...
@@ -1375,7 +1380,6 @@ void xreadCommand(client *c) {
...
@@ -1375,7 +1380,6 @@ void xreadCommand(client *c) {
int
streams_count
=
0
;
int
streams_count
=
0
;
int
streams_arg
=
0
;
int
streams_arg
=
0
;
int
noack
=
0
;
/* True if NOACK option was specified. */
int
noack
=
0
;
/* True if NOACK option was specified. */
#define STREAMID_STATIC_VECTOR_LEN 8
streamID
static_ids
[
STREAMID_STATIC_VECTOR_LEN
];
streamID
static_ids
[
STREAMID_STATIC_VECTOR_LEN
];
streamID
*
ids
=
static_ids
;
streamID
*
ids
=
static_ids
;
streamCG
**
groups
=
NULL
;
streamCG
**
groups
=
NULL
;
...
@@ -1949,18 +1953,19 @@ void xackCommand(client *c) {
...
@@ -1949,18 +1953,19 @@ void xackCommand(client *c) {
* error: the return value of this command cannot be an error in case
* error: the return value of this command cannot be an error in case
* the client successfully acknowledged some messages, so it should be
* the client successfully acknowledged some messages, so it should be
* executed in a "all or nothing" fashion. */
* executed in a "all or nothing" fashion. */
streamID
static_ids
[
STREAMID_STATIC_VECTOR_LEN
];
streamID
*
ids
=
static_ids
;
int
id_count
=
c
->
argc
-
3
;
if
(
id_count
>
STREAMID_STATIC_VECTOR_LEN
)
ids
=
zmalloc
(
sizeof
(
streamID
)
*
id_count
);
for
(
int
j
=
3
;
j
<
c
->
argc
;
j
++
)
{
for
(
int
j
=
3
;
j
<
c
->
argc
;
j
++
)
{
streamID
id
;
if
(
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
ids
[
j
-
3
],
0
)
!=
C_OK
)
goto
cleanup
;
if
(
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
id
,
0
)
!=
C_OK
)
return
;
}
}
int
acknowledged
=
0
;
int
acknowledged
=
0
;
for
(
int
j
=
3
;
j
<
c
->
argc
;
j
++
)
{
for
(
int
j
=
3
;
j
<
c
->
argc
;
j
++
)
{
streamID
id
;
unsigned
char
buf
[
sizeof
(
streamID
)];
unsigned
char
buf
[
sizeof
(
streamID
)];
if
(
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
id
,
0
)
!=
C_OK
)
streamEncodeID
(
buf
,
&
ids
[
j
-
3
]);
serverPanic
(
"StreamID invalid after check. Should not be possible."
);
streamEncodeID
(
buf
,
&
id
);
/* Lookup the ID in the group PEL: it will have a reference to the
/* Lookup the ID in the group PEL: it will have a reference to the
* NACK structure that will have a reference to the consumer, so that
* NACK structure that will have a reference to the consumer, so that
...
@@ -1975,6 +1980,8 @@ void xackCommand(client *c) {
...
@@ -1975,6 +1980,8 @@ void xackCommand(client *c) {
}
}
}
}
addReplyLongLong
(
c
,
acknowledged
);
addReplyLongLong
(
c
,
acknowledged
);
cleanup:
if
(
ids
!=
static_ids
)
zfree
(
ids
);
}
}
/* XPENDING <key> <group> [<start> <stop> <count> [<consumer>]]
/* XPENDING <key> <group> [<start> <stop> <count> [<consumer>]]
...
@@ -2227,9 +2234,13 @@ void xclaimCommand(client *c) {
...
@@ -2227,9 +2234,13 @@ void xclaimCommand(client *c) {
* the client successfully claimed some message, so it should be
* the client successfully claimed some message, so it should be
* executed in a "all or nothing" fashion. */
* executed in a "all or nothing" fashion. */
int
j
;
int
j
;
streamID
static_ids
[
STREAMID_STATIC_VECTOR_LEN
];
streamID
*
ids
=
static_ids
;
int
id_count
=
c
->
argc
-
5
;
if
(
id_count
>
STREAMID_STATIC_VECTOR_LEN
)
ids
=
zmalloc
(
sizeof
(
streamID
)
*
id_count
);
for
(
j
=
5
;
j
<
c
->
argc
;
j
++
)
{
for
(
j
=
5
;
j
<
c
->
argc
;
j
++
)
{
streamID
id
;
if
(
streamParseStrictIDOrReply
(
NULL
,
c
->
argv
[
j
],
&
ids
[
j
-
5
],
0
)
!=
C_OK
)
break
;
if
(
streamParseStrictIDOrReply
(
NULL
,
c
->
argv
[
j
],
&
id
,
0
)
!=
C_OK
)
break
;
}
}
int
last_id_arg
=
j
-
1
;
/* Next time we iterate the IDs we now the range. */
int
last_id_arg
=
j
-
1
;
/* Next time we iterate the IDs we now the range. */
...
@@ -2249,24 +2260,24 @@ void xclaimCommand(client *c) {
...
@@ -2249,24 +2260,24 @@ void xclaimCommand(client *c) {
j
++
;
j
++
;
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
j
],
&
deliverytime
,
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
j
],
&
deliverytime
,
"Invalid IDLE option argument for XCLAIM"
)
"Invalid IDLE option argument for XCLAIM"
)
!=
C_OK
)
return
;
!=
C_OK
)
goto
cleanup
;
deliverytime
=
now
-
deliverytime
;
deliverytime
=
now
-
deliverytime
;
}
else
if
(
!
strcasecmp
(
opt
,
"TIME"
)
&&
moreargs
)
{
}
else
if
(
!
strcasecmp
(
opt
,
"TIME"
)
&&
moreargs
)
{
j
++
;
j
++
;
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
j
],
&
deliverytime
,
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
j
],
&
deliverytime
,
"Invalid TIME option argument for XCLAIM"
)
"Invalid TIME option argument for XCLAIM"
)
!=
C_OK
)
return
;
!=
C_OK
)
goto
cleanup
;
}
else
if
(
!
strcasecmp
(
opt
,
"RETRYCOUNT"
)
&&
moreargs
)
{
}
else
if
(
!
strcasecmp
(
opt
,
"RETRYCOUNT"
)
&&
moreargs
)
{
j
++
;
j
++
;
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
j
],
&
retrycount
,
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
j
],
&
retrycount
,
"Invalid RETRYCOUNT option argument for XCLAIM"
)
"Invalid RETRYCOUNT option argument for XCLAIM"
)
!=
C_OK
)
return
;
!=
C_OK
)
goto
cleanup
;
}
else
if
(
!
strcasecmp
(
opt
,
"LASTID"
)
&&
moreargs
)
{
}
else
if
(
!
strcasecmp
(
opt
,
"LASTID"
)
&&
moreargs
)
{
j
++
;
j
++
;
if
(
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
last_id
,
0
)
!=
C_OK
)
return
;
if
(
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
last_id
,
0
)
!=
C_OK
)
goto
cleanup
;
}
else
{
}
else
{
addReplyErrorFormat
(
c
,
"Unrecognized XCLAIM option '%s'"
,
opt
);
addReplyErrorFormat
(
c
,
"Unrecognized XCLAIM option '%s'"
,
opt
);
return
;
goto
cleanup
;
}
}
}
}
...
@@ -2296,10 +2307,8 @@ void xclaimCommand(client *c) {
...
@@ -2296,10 +2307,8 @@ void xclaimCommand(client *c) {
void
*
arraylenptr
=
addReplyDeferredLen
(
c
);
void
*
arraylenptr
=
addReplyDeferredLen
(
c
);
size_t
arraylen
=
0
;
size_t
arraylen
=
0
;
for
(
int
j
=
5
;
j
<=
last_id_arg
;
j
++
)
{
for
(
int
j
=
5
;
j
<=
last_id_arg
;
j
++
)
{
streamID
id
;
streamID
id
=
ids
[
j
-
5
]
;
unsigned
char
buf
[
sizeof
(
streamID
)];
unsigned
char
buf
[
sizeof
(
streamID
)];
if
(
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
id
,
0
)
!=
C_OK
)
serverPanic
(
"StreamID invalid after check. Should not be possible."
);
streamEncodeID
(
buf
,
&
id
);
streamEncodeID
(
buf
,
&
id
);
/* Lookup the ID in the group PEL. */
/* Lookup the ID in the group PEL. */
...
@@ -2379,6 +2388,8 @@ void xclaimCommand(client *c) {
...
@@ -2379,6 +2388,8 @@ void xclaimCommand(client *c) {
}
}
setDeferredArrayLen
(
c
,
arraylenptr
,
arraylen
);
setDeferredArrayLen
(
c
,
arraylenptr
,
arraylen
);
preventCommandPropagation
(
c
);
preventCommandPropagation
(
c
);
cleanup:
if
(
ids
!=
static_ids
)
zfree
(
ids
);
}
}
...
@@ -2397,16 +2408,19 @@ void xdelCommand(client *c) {
...
@@ -2397,16 +2408,19 @@ void xdelCommand(client *c) {
/* We need to sanity check the IDs passed to start. Even if not
/* We need to sanity check the IDs passed to start. Even if not
* a big issue, it is not great that the command is only partially
* a big issue, it is not great that the command is only partially
* executed because at some point an invalid ID is parsed. */
* executed because at some point an invalid ID is parsed. */
streamID
id
;
streamID
static_ids
[
STREAMID_STATIC_VECTOR_LEN
];
streamID
*
ids
=
static_ids
;
int
id_count
=
c
->
argc
-
2
;
if
(
id_count
>
STREAMID_STATIC_VECTOR_LEN
)
ids
=
zmalloc
(
sizeof
(
streamID
)
*
id_count
);
for
(
int
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
for
(
int
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
if
(
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
id
,
0
)
!=
C_OK
)
return
;
if
(
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
id
s
[
j
-
2
]
,
0
)
!=
C_OK
)
goto
cleanup
;
}
}
/* Actually apply the command. */
/* Actually apply the command. */
int
deleted
=
0
;
int
deleted
=
0
;
for
(
int
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
for
(
int
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
streamParseStrictIDOrReply
(
c
,
c
->
argv
[
j
],
&
id
,
0
);
/* Retval already checked. */
deleted
+=
streamDeleteItem
(
s
,
&
ids
[
j
-
2
]);
deleted
+=
streamDeleteItem
(
s
,
&
id
);
}
}
/* Propagate the write if needed. */
/* Propagate the write if needed. */
...
@@ -2416,6 +2430,8 @@ void xdelCommand(client *c) {
...
@@ -2416,6 +2430,8 @@ void xdelCommand(client *c) {
server
.
dirty
+=
deleted
;
server
.
dirty
+=
deleted
;
}
}
addReplyLongLong
(
c
,
deleted
);
addReplyLongLong
(
c
,
deleted
);
cleanup:
if
(
ids
!=
static_ids
)
zfree
(
ids
);
}
}
/* General form: XTRIM <key> [... options ...]
/* General form: XTRIM <key> [... options ...]
...
...
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