[dovecot-cvs] dovecot/src/lib-storage/index index-sort.c,NONE,1.1 index-sort.h,NONE,1.1 Makefile.am,1.5,1.6 index-search.c,1.46,1.47 index-storage.h,1.23,1.24

cras at procontrol.fi cras at procontrol.fi
Wed Dec 4 20:28:40 EET 2002


Update of /home/cvs/dovecot/src/lib-storage/index
In directory danu:/tmp/cvs-serv16863/src/lib-storage/index

Modified Files:
	Makefile.am index-search.c index-storage.h 
Added Files:
	index-sort.c index-sort.h 
Log Message:
First implementation of SORT extension. String comparing still not up to
spec, so we don't advertise it in capability string yet. The code supports
getting the data partially pre-sorted to reduce memory usage and make it
faster. So, in future we could use this by creating sorted binary trees.

Also moved mail-storage-register.c into it's own .a lib to fix circular
dependencies.



--- NEW FILE: index-sort.c ---
/* Copyright (C) 2002 Timo Sirainen */

#include "lib.h"
#include "obuffer.h"
#include "rfc822-date.h"
#include "imap-envelope.h"
#include "imap-message-cache.h"
#include "mail-index.h"
#include "index-storage.h"
#include "index-sort.h"

static ImapMessageCache *search_open_cache(IndexSortContext *ctx,
					   unsigned int uid)
{
	if (ctx->last_uid != uid) {
		ctx->cached = FALSE;
		ctx->last_uid = uid;
		ctx->rec = ctx->ibox->index->lookup_uid_range(ctx->ibox->index,
							      uid, uid, NULL);
		if (ctx->rec == NULL) {
			ctx->last_uid = 0;
			return NULL;
		}
	}

	if (!ctx->cached) {
		ctx->cached = TRUE;
		(void)index_msgcache_open(ctx->ibox->cache,
					  ctx->ibox->index, ctx->rec,
					  IMAP_CACHE_ENVELOPE);
	}

	return ctx->ibox->cache;
}

static uoff_t _input_uofft(MailSortType type, unsigned int id, void *context)
{
	IndexSortContext *ctx = context;
        ImapMessageCache *cache;

	if (type != MAIL_SORT_SIZE) {
		i_unreached();
		return 0;
	}

        cache = search_open_cache(ctx, id);
	return cache == NULL ? 0 : imap_msgcache_get_virtual_size(cache);
}

static const char *_input_str(MailSortType type, unsigned int id, void *context)
{
	IndexSortContext *ctx = context;
	ImapEnvelopeField env_field;
	const char *envelope;

	switch (type) {
	case MAIL_SORT_CC:
		env_field = IMAP_ENVELOPE_CC;
		break;
	case MAIL_SORT_DATE:
                env_field = IMAP_ENVELOPE_DATE;
		break;
	case MAIL_SORT_FROM:
                env_field = IMAP_ENVELOPE_FROM;
		break;
	case MAIL_SORT_SUBJECT:
                env_field = IMAP_ENVELOPE_SUBJECT;
		break;
	case MAIL_SORT_TO:
                env_field = IMAP_ENVELOPE_TO;
		break;
	default:
		i_unreached();
		return NULL;
	}

	/* get field from hopefully cached envelope */
	envelope = imap_msgcache_get(search_open_cache(ctx, id),
				     IMAP_CACHE_ENVELOPE);
	return envelope == NULL ? NULL :
		imap_envelope_parse(envelope, env_field);
}

static time_t _input_time(MailSortType type, unsigned int id, void *context)
{
	IndexSortContext *ctx = context;
        ImapMessageCache *cache;
	const char *str;
	time_t time;
	int timezone_offset;

	switch (type) {
	case MAIL_SORT_ARRIVAL:
		cache = search_open_cache(ctx, id);
		return cache == NULL ? 0 :
			imap_msgcache_get_internal_date(cache);
	case MAIL_SORT_DATE:
		str = _input_str(type, id, context);
		if (str == NULL)
			return 0;

		if (!rfc822_parse_date(str, &time, &timezone_offset))
			return 0;

		return time - timezone_offset*60;
	default:
		i_unreached();
		return 0;
	}
}

static void _input_reset(void *context)
{
	IndexSortContext *ctx = context;

	ctx->cached = FALSE;
}

static void _output(unsigned int *data, size_t count, void *context)
{
	IndexSortContext *ctx = context;
	char num[MAX_INT_STRLEN+1];
	size_t i, len;

	for (i = 0; i < count; i++) {
		len = i_snprintf(num, sizeof(num), " %u", data[i]);
		o_buffer_send(ctx->outbuf, num, len);
	}
}

MailSortFuncs index_sort_funcs = {
	_input_time,
	_input_uofft,
	_input_str,
	_input_reset,
	_output
};

--- NEW FILE: index-sort.h ---
#ifndef __INDEX_SORT_H
#define __INDEX_SORT_H

#include "mail-storage.h"
#include "mail-sort.h"

typedef struct {
	IndexMailbox *ibox;
	OBuffer *outbuf;

	unsigned int last_uid;
	MailIndexRecord *rec;

	unsigned int cached:1;
} IndexSortContext;

extern MailSortFuncs index_sort_funcs;

#endif

Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/Makefile.am,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Makefile.am	12 Nov 2002 05:27:30 -0000	1.5
+++ Makefile.am	4 Dec 2002 18:28:37 -0000	1.6
@@ -19,6 +19,7 @@
 	index-msgcache.c \
 	index-save.c \
 	index-search.c \
+	index-sort.c \
 	index-status.c \
 	index-storage.c \
 	index-sync.c \

Index: index-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- index-search.c	30 Nov 2002 14:58:23 -0000	1.46
+++ index-search.c	4 Dec 2002 18:28:38 -0000	1.47
@@ -12,6 +12,7 @@
 #include "imap-date.h"
 #include "imap-envelope.h"
 #include "index-storage.h"
+#include "index-sort.h"
 #include "mail-index-util.h"
 #include "mail-modifylog.h"
 #include "mail-custom-flags.h"
@@ -53,6 +54,8 @@
 	MessagePart *part;
 } SearchBodyContext;
 
+static MailSortType sort_unsorted[] = { MAIL_SORT_END };
+
 static int msgset_contains(const char *set, unsigned int match_num,
 			   unsigned int max_num)
 {
@@ -753,7 +756,8 @@
 }
 
 static int search_messages(IndexMailbox *ibox, const char *charset,
-			   MailSearchArg *args, OBuffer *outbuf, int uid_result)
+			   MailSearchArg *args, MailSortContext *sort_ctx,
+			   OBuffer *outbuf, int uid_result)
 {
 	SearchIndexContext ctx;
 	MailIndexRecord *rec;
@@ -821,9 +825,16 @@
 			}
 
 			if (found) {
-				i_snprintf(num, sizeof(num), " %u",
-					   uid_result ? rec->uid : client_seq);
-				o_buffer_send(outbuf, num, strlen(num));
+				if (sort_ctx == NULL) {
+					size_t len;
+
+					len = i_snprintf(num, sizeof(num),
+							 " %u", uid_result ?
+							 rec->uid : client_seq);
+					o_buffer_send(outbuf, num, len);
+				} else {
+					mail_sort_input(sort_ctx, rec->uid);
+				}
 			}
 		}
 
@@ -839,16 +850,34 @@
 }
 
 int index_storage_search(Mailbox *box, const char *charset, MailSearchArg *args,
-			 OBuffer *outbuf, int uid_result)
+			 MailSortType *sorting, OBuffer *outbuf, int uid_result)
 {
 	IndexMailbox *ibox = (IndexMailbox *) box;
+	MailSortContext *sort_ctx;
+	IndexSortContext index_sort_ctx;
 	int failed;
 
 	if (!index_storage_sync_and_lock(ibox, TRUE, MAIL_LOCK_SHARED))
 		return FALSE;
 
-	o_buffer_send(outbuf, "* SEARCH", 8);
-	failed = !search_messages(ibox, charset, args, outbuf, uid_result);
+	if (sorting == NULL) {
+		sort_ctx = NULL;
+		o_buffer_send(outbuf, "* SEARCH", 8);
+	} else {
+		memset(&index_sort_ctx, 0, sizeof(index_sort_ctx));
+		index_sort_ctx.ibox = ibox;
+		index_sort_ctx.outbuf = outbuf;
+
+		sort_ctx = mail_sort_init(sort_unsorted, sorting,
+					  index_sort_funcs, &index_sort_ctx);
+		o_buffer_send(outbuf, "* SORT", 6);
+	}
+
+	failed = !search_messages(ibox, charset, args, sort_ctx,
+				  outbuf, uid_result);
+	if (sort_ctx != NULL)
+		mail_sort_deinit(sort_ctx);
+
 	o_buffer_send(outbuf, "\r\n", 2);
 
 	if (!index_storage_lock(ibox, MAIL_LOCK_UNLOCK))

Index: index-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- index-storage.h	25 Nov 2002 19:02:50 -0000	1.23
+++ index-storage.h	4 Dec 2002 18:28:38 -0000	1.24
@@ -84,6 +84,7 @@
 int index_storage_fetch(Mailbox *box, MailFetchData *fetch_data,
 			OBuffer *outbuf, int *all_found);
 int index_storage_search(Mailbox *box, const char *charset, MailSearchArg *args,
-			 OBuffer *outbuf, int uid_result);
+			 MailSortType *sorting, OBuffer *outbuf,
+			 int uid_result);
 
 #endif




More information about the dovecot-cvs mailing list