changeset 13199:8dcb7c7f66d5

doveadm index: Added -n parameter to specify max number of recent msgs to perform indexing. The idea is that if a user hasn't opened the mailbox for a long time (or ever), there's not much point in wasting time on doing indexing.
author Timo Sirainen <tss@iki.fi>
date Wed, 10 Aug 2011 14:17:54 +0300
parents 753a8346e1ba
children 3087d25c2f6b
files src/indexer/indexer-client.c src/indexer/indexer-queue.c src/indexer/indexer-queue.h src/indexer/indexer.c src/indexer/master-connection.c src/indexer/worker-connection.c src/indexer/worker-connection.h
diffstat 7 files changed, 42 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/indexer/indexer-client.c	Wed Aug 10 13:46:31 2011 +0300
+++ b/src/indexer/indexer-client.c	Wed Aug 10 14:17:54 2011 +0300
@@ -67,9 +67,9 @@
 			     const char *const *args, const char **error_r)
 {
 	struct indexer_client_request *ctx = NULL;
-	unsigned int tag;
+	unsigned int tag, max_recent_msgs;
 
-	if (str_array_length(args) != 3) {
+	if (str_array_length(args) < 3) {
 		*error_r = "Wrong parameter count";
 		return -1;
 	}
@@ -77,6 +77,12 @@
 		*error_r = "Invalid tag";
 		return -1;
 	}
+	if (args[3] == NULL)
+		max_recent_msgs = 0;
+	else if (str_to_uint(args[3], &max_recent_msgs) < 0) {
+		*error_r = "Invalid max_recent_msgs";
+		return -1;
+	}
 
 	if (tag != 0) {
 		ctx = i_new(struct indexer_client_request, 1);
@@ -85,7 +91,8 @@
 		indexer_client_ref(client);
 	}
 
-	indexer_queue_append(client->queue, append, args[1], args[2], ctx);
+	indexer_queue_append(client->queue, append, args[1], args[2],
+			     max_recent_msgs, ctx);
 	o_stream_send_str(client->output, t_strdup_printf("%u\tOK\n", tag));
 	return 0;
 }
--- a/src/indexer/indexer-queue.c	Wed Aug 10 13:46:31 2011 +0300
+++ b/src/indexer/indexer-queue.c	Wed Aug 10 14:17:54 2011 +0300
@@ -93,7 +93,7 @@
 
 void indexer_queue_append(struct indexer_queue *queue, bool append,
 			  const char *username, const char *mailbox,
-			  void *context)
+			  unsigned int max_recent_msgs, void *context)
 {
 	struct indexer_request *request;
 
@@ -102,9 +102,12 @@
 		request = i_new(struct indexer_request, 1);
 		request->username = i_strdup(username);
 		request->mailbox = i_strdup(mailbox);
+		request->max_recent_msgs = max_recent_msgs;
 		request_add_context(request, context);
 		hash_table_insert(queue->requests, request, request);
 	} else {
+		if (request->max_recent_msgs > max_recent_msgs)
+			request->max_recent_msgs = max_recent_msgs;
 		request_add_context(request, context);
 		if (append) {
 			/* keep the request in its old position */
--- a/src/indexer/indexer-queue.h	Wed Aug 10 13:46:31 2011 +0300
+++ b/src/indexer/indexer-queue.h	Wed Aug 10 14:17:54 2011 +0300
@@ -8,6 +8,8 @@
 
 	char *username;
 	char *mailbox;
+	unsigned int max_recent_msgs;
+
 	void **contexts;
 };
 
@@ -20,7 +22,7 @@
 	
 void indexer_queue_append(struct indexer_queue *queue, bool append,
 			  const char *username, const char *mailbox,
-			  void *context);
+			  unsigned int max_recent_msgs, void *context);
 void indexer_queue_cancel_all(struct indexer_queue *queue);
 
 bool indexer_queue_is_empty(struct indexer_queue *queue);
--- a/src/indexer/indexer.c	Wed Aug 10 13:46:31 2011 +0300
+++ b/src/indexer/indexer.c	Wed Aug 10 14:17:54 2011 +0300
@@ -50,7 +50,8 @@
 	wrequest->request = request;
 
 	worker_connection_request(conn, request->username,
-				  request->mailbox, wrequest);
+				  request->mailbox, request->max_recent_msgs,
+				  wrequest);
 }
 
 static void queue_handle_existing_user_requests(struct indexer_queue *queue)
--- a/src/indexer/master-connection.c	Wed Aug 10 13:46:31 2011 +0300
+++ b/src/indexer/master-connection.c	Wed Aug 10 14:17:54 2011 +0300
@@ -44,10 +44,12 @@
 		process_title_set("[idling]");
 }
 
-static int index_mailbox(struct mail_user *user, const char *mailbox)
+static int index_mailbox(struct mail_user *user, const char *mailbox,
+			 unsigned int max_recent_msgs)
 {
 	struct mail_namespace *ns;
 	struct mailbox *box;
+	struct mailbox_status status;
 	const char *errstr;
 	enum mail_error error;
 	int ret = 0;
@@ -61,6 +63,18 @@
 	/* FIXME: the current lib-storage API doesn't allow sending
 	   "n% competed" notifications */
 	box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_KEEP_RECENT);
+	if (max_recent_msgs != 0) {
+		/* index only if there aren't too many recent messages */
+		if (mailbox_get_status(box, STATUS_RECENT, &status) < 0) {
+			i_error("Mailbox %s status failed: %s", mailbox,
+				mail_storage_get_last_error(mailbox_get_storage(box), NULL));
+			ret = -1;
+		}
+		if (ret < 0 || status.recent > max_recent_msgs) {
+			mailbox_free(&box);
+			return ret;
+		}
+	}
 	if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ |
 			 MAILBOX_SYNC_FLAG_PRECACHE) < 0) {
 		errstr = mail_storage_get_last_error(mailbox_get_storage(box),
@@ -86,10 +100,12 @@
 	struct mail_storage_service_user *service_user;
 	struct mail_user *user;
 	const char *str, *error;
+	unsigned int max_recent_msgs;
 	int ret;
 
-	/* <username> <mailbox> */
-	if (str_array_length(args) != 2) {
+	/* <username> <mailbox> <max_recent_msgs> */
+	if (str_array_length(args) != 3 ||
+	    str_to_uint(args[2], &max_recent_msgs) < 0) {
 		i_error("Invalid input from master: %s", line);
 		return -1;
 	}
@@ -105,7 +121,7 @@
 		ret = -1;
 	} else {
 		indexer_worker_refresh_proctitle(user->username, args[1]);
-		ret = index_mailbox(user, args[1]);
+		ret = index_mailbox(user, args[1], max_recent_msgs);
 		indexer_worker_refresh_proctitle(NULL, NULL);
 		mail_user_unref(&user);
 		mail_storage_service_user_free(&service_user);
--- a/src/indexer/worker-connection.c	Wed Aug 10 13:46:31 2011 +0300
+++ b/src/indexer/worker-connection.c	Wed Aug 10 14:17:54 2011 +0300
@@ -194,7 +194,7 @@
 
 void worker_connection_request(struct worker_connection *conn,
 			       const char *username, const char *mailbox,
-			       void *context)
+			       unsigned int max_recent_msgs, void *context)
 {
 	i_assert(worker_connection_is_connected(conn));
 	i_assert(context != NULL);
@@ -212,7 +212,7 @@
 		str_tabescape_write(str, username);
 		str_append_c(str, '\t');
 		str_tabescape_write(str, mailbox);
-		str_append_c(str, '\n');
+		str_printfa(str, "\t%u\n", max_recent_msgs);
 		o_stream_send(conn->output, str_data(str), str_len(str));
 	} T_END;
 }
--- a/src/indexer/worker-connection.h	Wed Aug 10 13:46:31 2011 +0300
+++ b/src/indexer/worker-connection.h	Wed Aug 10 14:17:54 2011 +0300
@@ -23,7 +23,7 @@
    only for the same username. */
 void worker_connection_request(struct worker_connection *conn,
 			       const char *username, const char *mailbox,
-			       void *context);
+			       unsigned int max_recent_msgs, void *context);
 /* Returns TRUE if a request is being handled. */
 bool worker_connection_is_busy(struct worker_connection *conn);
 /* Returns username of the currently pending requests,