[dovecot-cvs] dovecot/src/lib ibuffer-file.c,1.7,1.8
cras at procontrol.fi
cras at procontrol.fi
Fri Nov 22 14:42:33 EET 2002
Update of /home/cvs/dovecot/src/lib
In directory danu:/tmp/cvs-serv7223
Modified Files:
ibuffer-file.c
Log Message:
Several bugfixes and speedups related to i_buffer_skip().
Index: ibuffer-file.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/ibuffer-file.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- ibuffer-file.c 29 Oct 2002 17:40:33 -0000 1.7
+++ ibuffer-file.c 22 Nov 2002 12:42:30 -0000 1.8
@@ -26,10 +26,11 @@
#include "lib.h"
#include "alarm-hup.h"
#include "ibuffer-internal.h"
+#include "network.h"
#include <time.h>
#include <unistd.h>
-#include <network.h>
+#include <sys/stat.h>
#define I_BUFFER_MIN_SIZE 4096
@@ -46,6 +47,7 @@
void (*timeout_func)(void *);
void *timeout_context;
+ unsigned int file:1;
unsigned int autoclose_fd:1;
} FileIBuffer;
@@ -124,12 +126,28 @@
{
FileIBuffer *fbuf = (FileIBuffer *) buf;
time_t timeout_time;
+ uoff_t read_limit;
size_t size;
ssize_t ret;
if (buf->ibuffer.closed)
return -1;
+ if (fbuf->skip_left > 0) {
+ i_assert(buf->skip == buf->pos);
+
+ if (fbuf->file) {
+ /* we're a file, so we can lseek() */
+ buf->ibuffer.v_offset -= fbuf->skip_left;
+
+ i_buffer_seek(&buf->ibuffer, buf->ibuffer.v_offset +
+ fbuf->skip_left);
+
+ if (buf->ibuffer.closed)
+ return -1;
+ }
+ }
+
buf->ibuffer.buf_errno = 0;
if (buf->pos == buf->buffer_size) {
@@ -143,19 +161,23 @@
}
if (buf->pos == buf->buffer_size)
- return -2; /* buffer full */
+ return -2; /* buffer full */
}
size = buf->buffer_size - buf->pos;
if (buf->ibuffer.v_limit > 0) {
i_assert(buf->ibuffer.v_limit >= buf->ibuffer.v_offset);
- if (size >= buf->ibuffer.v_limit - buf->ibuffer.v_offset) {
- size = buf->ibuffer.v_limit - buf->ibuffer.v_offset;
- if (size == 0) {
- /* virtual limit reached == EOF */
- return -1;
- }
+
+ read_limit = buf->ibuffer.v_limit -
+ buf->ibuffer.v_offset + fbuf->skip_left;
+ if (read_limit <= buf->pos - buf->skip) {
+ /* virtual limit reached == EOF */
+ return -1;
}
+
+ read_limit -= buf->pos - buf->skip;
+ if (size > read_limit)
+ size = read_limit;
}
timeout_time = GET_TIMEOUT_TIME(fbuf);
@@ -187,13 +209,13 @@
}
if (ret > 0 && fbuf->skip_left > 0) {
- if (fbuf->skip_left > (uoff_t)ret) {
- buf->skip += ret;
+ if (fbuf->skip_left >= (size_t)ret) {
fbuf->skip_left -= ret;
ret = 0;
} else {
ret -= fbuf->skip_left;
- buf->skip -= fbuf->skip_left;
+ buf->pos += fbuf->skip_left;
+ buf->skip += fbuf->skip_left;
fbuf->skip_left = 0;
}
}
@@ -206,34 +228,15 @@
static void _skip(_IBuffer *buf, uoff_t count)
{
FileIBuffer *fbuf = (FileIBuffer *) buf;
- uoff_t old_limit;
- ssize_t ret;
- off_t skipped;
-
- if (buf->buffer_size == 0)
- i_buffer_grow(buf, I_BUFFER_MIN_SIZE);
- skipped = 0;
- old_limit = buf->ibuffer.v_limit;
- i_buffer_set_read_limit(&buf->ibuffer, buf->ibuffer.v_offset + count);
-
- while (count > 0 && (ret = i_buffer_read(&buf->ibuffer)) > 0) {
- if ((size_t)ret > count)
- ret = count;
-
- count -= ret;
- buf->skip += ret;
- buf->ibuffer.v_offset += ret;
- }
-
- i_buffer_set_read_limit(&buf->ibuffer, old_limit);
-
- fbuf->skip_left = count;
+ fbuf->skip_left += count - (buf->pos - buf->skip);
+ buf->skip = buf->pos = 0;
buf->ibuffer.v_offset += count;
}
static void _seek(_IBuffer *buf, uoff_t v_offset)
{
+ FileIBuffer *fbuf = (FileIBuffer *) buf;
uoff_t real_offset;
off_t ret;
@@ -248,6 +251,9 @@
else if (ret != (off_t)real_offset) {
buf->ibuffer.buf_errno = EINVAL;
ret = -1;
+ } else {
+ buf->skip = buf->pos = 0;
+ fbuf->skip_left = 0;
}
}
@@ -262,20 +268,27 @@
IBuffer *i_buffer_create_file(int fd, Pool pool, size_t max_buffer_size,
int autoclose_fd)
{
- FileIBuffer *mbuf;
+ FileIBuffer *fbuf;
+ struct stat st;
- mbuf = p_new(pool, FileIBuffer, 1);
- mbuf->max_buffer_size = max_buffer_size;
- mbuf->autoclose_fd = autoclose_fd;
+ fbuf = p_new(pool, FileIBuffer, 1);
+ fbuf->max_buffer_size = max_buffer_size;
+ fbuf->autoclose_fd = autoclose_fd;
- mbuf->ibuf.iobuf.close = _close;
- mbuf->ibuf.iobuf.destroy = _destroy;
- mbuf->ibuf.iobuf.set_max_size = _set_max_size;
- mbuf->ibuf.iobuf.set_blocking = _set_blocking;
+ fbuf->ibuf.iobuf.close = _close;
+ fbuf->ibuf.iobuf.destroy = _destroy;
+ fbuf->ibuf.iobuf.set_max_size = _set_max_size;
+ fbuf->ibuf.iobuf.set_blocking = _set_blocking;
- mbuf->ibuf.read = _read;
- mbuf->ibuf.skip_count = _skip;
- mbuf->ibuf.seek = _seek;
+ fbuf->ibuf.read = _read;
+ fbuf->ibuf.skip_count = _skip;
+ fbuf->ibuf.seek = _seek;
- return _i_buffer_create(&mbuf->ibuf, pool, fd, 0, 0);
+ /* get size of fd if it's a file */
+ if (fstat(fd, &st) < 0)
+ st.st_size = 0;
+ else if (S_ISREG(st.st_mode))
+ fbuf->file = TRUE;
+
+ return _i_buffer_create(&fbuf->ibuf, pool, fd, 0, (uoff_t)st.st_size);
}
More information about the dovecot-cvs
mailing list