changeset 12204:062da0b83c01

lib-index: If transaction log file is small enough, just read all of it to memory immediately.
author Timo Sirainen <tss@iki.fi>
date Wed, 29 Sep 2010 18:09:28 +0100
parents 49bd77c018bd
children 906746b4f383
files src/lib-index/mail-transaction-log-file.c
diffstat 1 files changed, 30 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-transaction-log-file.c	Wed Sep 29 17:15:12 2010 +0100
+++ b/src/lib-index/mail-transaction-log-file.c	Wed Sep 29 18:09:28 2010 +0100
@@ -390,21 +390,42 @@
 static ssize_t
 mail_transaction_log_file_read_header(struct mail_transaction_log_file *file)
 {
-	ssize_t pos, ret;
+	void *dest;
+	size_t pos, dest_size;
+	ssize_t ret;
+
+	i_assert(file->buffer == NULL && file->mmap_base == NULL);
 
 	memset(&file->hdr, 0, sizeof(file->hdr));
+	if (file->last_size < mmap_get_page_size() && file->last_size > 0) {
+		/* just read the entire transaction log to memory */
+		file->buffer = buffer_create_dynamic(default_pool, 4096);
+		file->buffer_offset = 0;
+		dest_size = file->last_size;
+		dest = buffer_append_space_unsafe(file->buffer, dest_size);
+	} else {
+		/* read only the header */
+		dest = &file->hdr;
+		dest_size = sizeof(file->hdr);
+	}
 
-        /* try to read the whole header, but it's not necessarily an error to
-	   read less since the older versions of the log format could be
-	   smaller. */
+	/* it's not necessarily an error to read less than wanted header size,
+	   since older versions of the log format used smaller headers. */
         pos = 0;
 	do {
-		ret = pread(file->fd, PTR_OFFSET(&file->hdr, pos),
-			    sizeof(file->hdr) - pos, pos);
+		ret = pread(file->fd, PTR_OFFSET(dest, pos),
+			    dest_size - pos, pos);
 		if (ret > 0)
 			pos += ret;
-	} while (ret > 0 && pos < (ssize_t)sizeof(file->hdr));
-	return ret < 0 ? -1 : pos;
+	} while (ret > 0 && pos < dest_size);
+
+	if (file->buffer != NULL) {
+		buffer_set_used_size(file->buffer, pos);
+		memcpy(&file->hdr, file->buffer->data,
+		       I_MIN(pos, sizeof(file->hdr)));
+	}
+
+	return ret < 0 ? -1 : (ssize_t)pos;
 }
 
 static int
@@ -598,6 +619,7 @@
 			}
 		} else {
 			file->fd = fd;
+			file->last_size = 0;
 			if (mail_transaction_log_file_read_hdr(file,
 							       FALSE) > 0 &&
 			    mail_transaction_log_file_stat(file, FALSE) == 0) {