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
828736e7
Unverified
Commit
828736e7
authored
Apr 27, 2020
by
Salvatore Sanfilippo
Committed by
GitHub
Apr 27, 2020
Browse files
Merge pull request #7146 from oranagra/optimize_deferred_reply
optimize memory usage of deferred replies
parents
4447ddc8
fb732f7a
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/networking.c
View file @
828736e7
...
@@ -436,6 +436,36 @@ void addReplyStatusFormat(client *c, const char *fmt, ...) {
...
@@ -436,6 +436,36 @@ void addReplyStatusFormat(client *c, const char *fmt, ...) {
sdsfree
(
s
);
sdsfree
(
s
);
}
}
/* Sometimes we are forced to create a new reply node, and we can't append to
* the previous one, when that happens, we wanna try to trim the unused space
* at the end of the last reply node which we won't use anymore. */
void
trimReplyUnusedTailSpace
(
client
*
c
)
{
listNode
*
ln
=
listLast
(
c
->
reply
);
clientReplyBlock
*
tail
=
ln
?
listNodeValue
(
ln
)
:
NULL
;
/* Note that 'tail' may be NULL even if we have a tail node, becuase when
* addDeferredMultiBulkLength() is used */
if
(
!
tail
)
return
;
/* We only try to trim the space is relatively high (more than a 1/4 of the
* allocation), otherwise there's a high chance realloc will NOP.
* Also, to avoid large memmove which happens as part of realloc, we only do
* that if the used part is small. */
if
(
tail
->
size
-
tail
->
used
>
tail
->
size
/
4
&&
tail
->
used
<
PROTO_REPLY_CHUNK_BYTES
)
{
size_t
old_size
=
tail
->
size
;
tail
=
zrealloc
(
tail
,
tail
->
used
+
sizeof
(
clientReplyBlock
));
/* If realloc was a NOP, we got the same value which has internal frag */
if
(
tail
==
listNodeValue
(
ln
))
return
;
/* take over the allocation's internal fragmentation (at least for
* memory usage tracking) */
tail
->
size
=
zmalloc_usable
(
tail
)
-
sizeof
(
clientReplyBlock
);
c
->
reply_bytes
+=
tail
->
size
-
old_size
;
listNodeValue
(
ln
)
=
tail
;
}
}
/* Adds an empty object to the reply list that will contain the multi bulk
/* Adds an empty object to the reply list that will contain the multi bulk
* length, which is not known when this function is called. */
* length, which is not known when this function is called. */
void
*
addReplyDeferredLen
(
client
*
c
)
{
void
*
addReplyDeferredLen
(
client
*
c
)
{
...
@@ -443,6 +473,7 @@ void *addReplyDeferredLen(client *c) {
...
@@ -443,6 +473,7 @@ void *addReplyDeferredLen(client *c) {
* ready to be sent, since we are sure that before returning to the
* ready to be sent, since we are sure that before returning to the
* event loop setDeferredAggregateLen() will be called. */
* event loop setDeferredAggregateLen() will be called. */
if
(
prepareClientToWrite
(
c
)
!=
C_OK
)
return
NULL
;
if
(
prepareClientToWrite
(
c
)
!=
C_OK
)
return
NULL
;
trimReplyUnusedTailSpace
(
c
);
listAddNodeTail
(
c
->
reply
,
NULL
);
/* NULL is our placeholder. */
listAddNodeTail
(
c
->
reply
,
NULL
);
/* NULL is our placeholder. */
return
listLast
(
c
->
reply
);
return
listLast
(
c
->
reply
);
}
}
...
...
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