[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