summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md27
-rw-r--r--hiredis.c3
-rw-r--r--hiredis.h3
3 files changed, 32 insertions, 1 deletions
diff --git a/README.md b/README.md
index f1f5566..62fe106 100644
--- a/README.md
+++ b/README.md
@@ -320,6 +320,10 @@ The reply parsing API consists of the following functions:
int redisReaderFeed(redisReader *reader, const char *buf, size_t len);
int redisReaderGetReply(redisReader *reader, void **reply);
+The same set of functions are used internally by hiredis when creating a
+normal Redis context, the above API just exposes it to the user for a direct
+usage.
+
### Usage
The function `redisReaderCreate` creates a `redisReader` structure that holds a
@@ -346,6 +350,29 @@ immediately after creating the `redisReader`.
For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c)
uses customized reply object functions to create Ruby objects.
+### Reader max buffer
+
+Both when using the Reader API directly or when using it indirectly via a
+normal Redis context, the redisReader structure uses a buffer in order to
+accumulate data from the server.
+Usually this buffer is destroyed when it is empty and is larger than 16
+kb in order to avoid wasting memory in unused buffers
+
+However when working with very big payloads destroying the buffer may slow
+down performances considerably, so it is possible to modify the max size of
+an idle buffer changing the value of the `maxbuf` field of the reader structure
+to the desired value. The special value of 0 means that there is no maximum
+value for an idle buffer, so the buffer will never get freed.
+
+For instance if you have a normal Redis context you can set the maximum idle
+buffer to zero (unlimited) just with:
+
+ context->reader->maxbuf = 0;
+
+This should be done only in order to maximize performances when working with
+large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again
+as soon as possible in order to prevent allocation of useless memory.
+
## AUTHORS
Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and
diff --git a/hiredis.c b/hiredis.c
index 1a57adb..f1d0188 100644
--- a/hiredis.c
+++ b/hiredis.c
@@ -564,6 +564,7 @@ redisReader *redisReaderCreate(void) {
r->errstr[0] = '\0';
r->fn = &defaultFunctions;
r->buf = sdsempty();
+ r->maxbuf = REDIS_READER_MAX_BUF;
if (r->buf == NULL) {
free(r);
return NULL;
@@ -591,7 +592,7 @@ int redisReaderFeed(redisReader *r, const char *buf, size_t len) {
/* Copy the provided buffer. */
if (buf != NULL && len >= 1) {
/* Destroy internal buffer when it is empty and is quite large. */
- if (r->len == 0 && sdsavail(r->buf) > 16*1024) {
+ if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) {
sdsfree(r->buf);
r->buf = sdsempty();
r->pos = 0;
diff --git a/hiredis.h b/hiredis.h
index 7c04b62..accf6b2 100644
--- a/hiredis.h
+++ b/hiredis.h
@@ -86,6 +86,8 @@
#define REDIS_REPLY_STATUS 5
#define REDIS_REPLY_ERROR 6
+#define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -125,6 +127,7 @@ typedef struct redisReader {
char *buf; /* Read buffer */
size_t pos; /* Buffer cursor */
size_t len; /* Buffer length */
+ size_t maxbuf; /* Max length of unused buffer */
redisReadTask rstack[4];
int ridx; /* Index of current read task */