Mercurial > dovecot > core-2.2
changeset 13114:04716e20f44f
IMAP: Implemented the rest of FUZZY extension.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 26 Jul 2011 15:09:02 +0300 |
parents | 2e15e70f5f2d |
children | fa852748e601 |
files | configure.in src/imap/imap-search.c src/imap/imap-search.h |
diffstat | 3 files changed, 61 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Tue Jul 26 15:04:57 2011 +0300 +++ b/configure.in Tue Jul 26 15:09:02 2011 +0300 @@ -2624,7 +2624,7 @@ dnl IDLE doesn't really belong to banner. It's there just to make Blackberries dnl happy, because otherwise BIS server disables push email. capability_banner="IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE" -capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS" +capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS FUZZY" AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities) AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", IMAP capabilities advertised in banner)
--- a/src/imap/imap-search.c Tue Jul 26 15:04:57 2011 +0300 +++ b/src/imap/imap-search.c Tue Jul 26 15:09:02 2011 +0300 @@ -14,6 +14,8 @@ #include "imap-search-args.h" #include "imap-search.h" +#include <stdlib.h> + static int imap_search_deinit(struct imap_search_context *ctx); static int @@ -67,6 +69,8 @@ ctx->return_options |= SEARCH_RETURN_SAVE; else if (strcmp(name, "UPDATE") == 0) ctx->return_options |= SEARCH_RETURN_UPDATE; + else if (strcmp(name, "RELEVANCY") == 0) + ctx->return_options |= SEARCH_RETURN_RELEVANCY; else if (strcmp(name, "PARTIAL") == 0) { if (ctx->partial1 != 0) { client_send_command_error(cmd, @@ -230,6 +234,34 @@ str_append_c(str, ')'); } +static void +imap_search_send_relevancy(struct imap_search_context *ctx, string_t *dest) +{ + const float *scores; + unsigned int i, count; + float diff, imap_score; + + scores = array_get(&ctx->relevancy_scores, &count); + if (count == 0) + return; + + /* we'll need to convert float scores to numbers 1..100 + FIXME: would be a good idea to try to detect non-linear score + mappings and convert them better.. */ + diff = ctx->max_relevancy - ctx->min_relevancy; + if (diff == 0) + diff = 1.0; + for (i = 0; i < count; i++) { + if (i > 0) + str_append_c(dest, ' '); + imap_score = (scores[i] - ctx->min_relevancy) / diff * 100.0; + if (imap_score < 1) + str_append(dest, "1"); + else + str_printfa(dest, "%u", (unsigned int)imap_score); + } +} + static void imap_search_send_result(struct imap_search_context *ctx) { struct client *client = ctx->cmd->client; @@ -268,6 +300,11 @@ imap_write_seq_range(str, &ctx->result); } } + if ((ctx->return_options & SEARCH_RETURN_RELEVANCY) != 0) { + str_append(str, " RELEVANCY ("); + imap_search_send_relevancy(ctx, str); + str_append_c(str, ')'); + } if ((ctx->return_options & SEARCH_RETURN_PARTIAL) != 0) imap_search_send_partial(ctx, str); @@ -297,6 +334,20 @@ seq_range_array_add(&ctx->cmd->client->search_saved_uidset, 0, mail->uid); } + if ((ctx->return_options & SEARCH_RETURN_RELEVANCY) != 0) { + const char *str; + float score; + + if (mail_get_special(mail, MAIL_FETCH_SEARCH_RELEVANCY, &str) < 0) + score = 0; + else + score = strtod(str, NULL); + array_append(&ctx->relevancy_scores, &score, 1); + if (ctx->min_relevancy > score) + ctx->min_relevancy = score; + if (ctx->max_relevancy < score) + ctx->max_relevancy = score; + } } static void search_add_result_id(struct imap_search_context *ctx, uint32_t id) @@ -501,6 +552,8 @@ i_array_init(&ctx->result, 128); if ((ctx->return_options & SEARCH_RETURN_UPDATE) != 0) imap_search_result_save(ctx); + if ((ctx->return_options & SEARCH_RETURN_RELEVANCY) != 0) + i_array_init(&ctx->relevancy_scores, 128); cmd->func = cmd_search_more; cmd->context = ctx; @@ -533,6 +586,8 @@ if (ctx->to != NULL) timeout_remove(&ctx->to); + if (array_is_created(&ctx->relevancy_scores)) + array_free(&ctx->relevancy_scores); array_free(&ctx->result); mail_search_args_deinit(ctx->sargs); mail_search_args_unref(&ctx->sargs);
--- a/src/imap/imap-search.h Tue Jul 26 15:04:57 2011 +0300 +++ b/src/imap/imap-search.h Tue Jul 26 15:09:02 2011 +0300 @@ -12,7 +12,8 @@ SEARCH_RETURN_MODSEQ = 0x0020, SEARCH_RETURN_SAVE = 0x0040, SEARCH_RETURN_UPDATE = 0x0080, - SEARCH_RETURN_PARTIAL = 0x0100 + SEARCH_RETURN_PARTIAL = 0x0100, + SEARCH_RETURN_RELEVANCY = 0x0200 /* Options that don't return any seq/uid results */ #define SEARCH_RETURN_NORESULTS \ (SEARCH_RETURN_ESEARCH | SEARCH_RETURN_MODSEQ | SEARCH_RETURN_SAVE | \ @@ -33,6 +34,9 @@ ARRAY_TYPE(seq_range) result; unsigned int result_count; + ARRAY_DEFINE(relevancy_scores, float); + float min_relevancy, max_relevancy; + uint64_t highest_seen_modseq; struct timeval start_time;