dovecot-2.2: istream-lf: Cleanup & performance improvement.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Apr 29 09:35:37 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/66620a924bfa
changeset: 17287:66620a924bfa
user: Timo Sirainen <tss at iki.fi>
date: Tue Apr 29 12:35:05 2014 +0300
description:
istream-lf: Cleanup & performance improvement.
memchr() is faster than lopping through the data ourself.
diffstat:
src/lib/istream-crlf.c | 68 ++++++++++++++++++++++++++-----------------------
1 files changed, 36 insertions(+), 32 deletions(-)
diffs (91 lines):
diff -r 507aee5fef6d -r 66620a924bfa src/lib/istream-crlf.c
--- a/src/lib/istream-crlf.c Tue Apr 29 00:53:01 2014 +0300
+++ b/src/lib/istream-crlf.c Tue Apr 29 12:35:05 2014 +0300
@@ -114,10 +114,10 @@
static ssize_t i_stream_crlf_read_lf(struct istream_private *stream)
{
struct crlf_istream *cstream = (struct crlf_istream *)stream;
- const unsigned char *data;
- size_t i, dest, size;
+ const unsigned char *data, *p;
+ size_t i, dest, size, max;
ssize_t ret;
- int diff;
+ bool pending_cr;
ret = i_stream_crlf_read_common(cstream);
if (ret <= 0)
@@ -126,40 +126,44 @@
data = i_stream_get_data(stream->parent, &size);
/* @UNSAFE */
+ /* \r\n -> \n
+ \r<anything> -> \r<anything>
+ \r\r\n -> \r\n */
dest = stream->pos;
- if (data[0] == '\n') {
- stream->w_buffer[dest++] = '\n';
- cstream->pending_cr = FALSE;
- } else {
- if (cstream->pending_cr) {
- /* CR without LF */
+ pending_cr = cstream->pending_cr;
+ for (i = 0; i < size && dest < stream->buffer_size; ) {
+ if (data[i] == '\r') {
+ if (pending_cr) {
+ /* \r\r */
+ stream->w_buffer[dest++] = '\r';
+ } else {
+ pending_cr = TRUE;
+ }
+ i++;
+ } else if (data[i] == '\n') {
+ /* [\r]\n */
+ pending_cr = FALSE;
+ stream->w_buffer[dest++] = '\n';
+ i++;
+ } else if (pending_cr) {
+ /* \r<anything> */
+ pending_cr = FALSE;
stream->w_buffer[dest++] = '\r';
- if (dest == stream->buffer_size) {
- stream->pos++;
- cstream->pending_cr = FALSE;
- return 1;
- }
+ } else {
+ /* copy everything until the next \r */
+ max = I_MIN(size - i, stream->buffer_size - dest);
+ p = memchr(data + i, '\r', max);
+ if (p != NULL)
+ max = p - (data+i);
+ memcpy(stream->w_buffer + dest, data + i, max);
+ dest += max;
+ i += max;
}
- if (data[0] != '\r')
- stream->w_buffer[dest++] = data[0];
}
+ i_assert(i <= size);
+ i_assert(dest <= stream->buffer_size);
- diff = 1;
- for (i = 1; i < size && dest < stream->buffer_size; i++) {
- if (data[i] == '\r') {
- if (data[i-1] != '\r')
- continue;
- } else if (data[i-1] == '\r' && data[i] != '\n') {
- stream->w_buffer[dest++] = '\r';
- if (dest == stream->buffer_size) {
- diff = 0;
- break;
- }
- }
-
- stream->w_buffer[dest++] = data[i];
- }
- cstream->pending_cr = data[i-diff] == '\r';
+ cstream->pending_cr = pending_cr;
i_stream_skip(stream->parent, i);
ret = dest - stream->pos;
More information about the dovecot-cvs
mailing list