summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2012-08-21 15:01:47 +0200
committerantirez <antirez@gmail.com>2012-08-21 15:01:47 +0200
commit7f095053c6db41249248a6b4366ecd11572c96d0 (patch)
tree150e8b3ad9bc5c04bcd659f7e1763037a48426ae
parent7f346477c88121e1cfaa7c052d7adc20469982d7 (diff)
Configurable reader max idle buffer size.
Hiredis used to free unused redisReader buffers bigger than 16k. Now this limit is configurable (see the documentation updated by this commit) in order to allow working with big payloads without incurring to speed penalty.
-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 */