diff options
author | yoav <yoav@monfort.co.il> | 2012-12-12 15:59:22 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2013-07-16 15:41:24 +0200 |
commit | 63d15dfc879489ebe811064886d69a347cca544d (patch) | |
tree | 50d59b50a89f725b5025a908525a49a4ecdfe552 /src/rio.h | |
parent | 9d520a7f70d24ea663b8de9c7178624d76a8d846 (diff) | |
download | redis-63d15dfc879489ebe811064886d69a347cca544d.tar.gz |
Chunked loading of RDB to prevent redis from stalling reading very large keys.
Diffstat (limited to 'src/rio.h')
-rw-r--r-- | src/rio.h | 31 |
1 files changed, 25 insertions, 6 deletions
@@ -53,6 +53,12 @@ struct _rio { /* The current checksum */ uint64_t cksum; + /* number of bytes read or written */ + size_t processed_bytes; + + /* maximum simgle read or write chunk size */ + size_t max_processing_chunk; + /* Backend-specific vars. */ union { struct { @@ -74,16 +80,29 @@ typedef struct _rio rio; * if needed. */ static inline size_t rioWrite(rio *r, const void *buf, size_t len) { - if (r->update_cksum) r->update_cksum(r,buf,len); - return r->write(r,buf,len); + while (len) { + size_t bytes_to_write = (r->max_processing_chunk && r->max_processing_chunk < len) ? r->max_processing_chunk : len; + if (r->update_cksum) r->update_cksum(r,buf,bytes_to_write); + if (r->write(r,buf,bytes_to_write) == 0) + return 0; + buf = (char*)buf + bytes_to_write; + len -= bytes_to_write; + r->processed_bytes += bytes_to_write; + } + return 1; } static inline size_t rioRead(rio *r, void *buf, size_t len) { - if (r->read(r,buf,len) == 1) { - if (r->update_cksum) r->update_cksum(r,buf,len); - return 1; + while (len) { + size_t bytes_to_read = (r->max_processing_chunk && r->max_processing_chunk < len) ? r->max_processing_chunk : len; + if (r->read(r,buf,bytes_to_read) == 0) + return 0; + if (r->update_cksum) r->update_cksum(r,buf,bytes_to_read); + buf = (char*)buf + bytes_to_read; + len -= bytes_to_read; + r->processed_bytes += bytes_to_read; } - return 0; + return 1; } static inline off_t rioTell(rio *r) { |