fts-backend-lucene.c revision 9b664389d8bc53b15f5e39f8c02a579e24f55192
/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "hash.h"
#include "hex-binary.h"
#include "mail-namespace.h"
#include "mail-storage-private.h"
#include "fts-expunge-log.h"
#include "lucene-wrapper.h"
#include "fts-lucene-plugin.h"
#include <wchar.h>
#define LUCENE_INDEX_DIR_NAME "lucene-indexes"
#define LUCENE_EXPUNGE_LOG_NAME "dovecot-expunges.log"
#define LUCENE_OPTIMIZE_BATCH_MSGS_COUNT 100
struct lucene_fts_backend {
struct fts_backend backend;
char *dir_path;
struct lucene_index *index;
struct mailbox *selected_box;
unsigned int selected_box_generation;
struct fts_expunge_log *expunge_log;
unsigned int dir_created:1;
unsigned int updating:1;
};
struct lucene_fts_backend_update_context {
struct fts_backend_update_context ctx;
char *hdr_name;
unsigned int added_msgs;
bool lucene_opened;
struct fts_expunge_log_append_ctx *expunge_ctx;
};
{
if (backend->dir_created)
return 0;
}
static int
{
struct mailbox_metadata metadata;
&metadata) < 0) {
i_error("lucene: Couldn't get mailbox %s GUID: %s",
return -1;
}
return 0;
}
static int
{
unsigned char guid_hex[MAILBOX_GUID_HEX_LENGTH];
unsigned int i;
return 0;
if (fts_backend_lucene_mkdir(backend) < 0)
return -1;
return -1;
for (i = 0; i < N_ELEMENTS(wguid_hex); i++)
} else {
}
sizeof(backend->selected_box_guid));
return 0;
}
static struct fts_backend *fts_backend_lucene_alloc(void)
{
struct lucene_fts_backend *backend;
}
static int
const char **error_r ATTR_UNUSED)
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
struct fts_lucene_user *fuser =
const char *path;
} else {
}
return 0;
}
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
}
static int
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
return 0;
/* either nothing has been indexed, or the index was corrupted.
do it the slow way. */
return -1;
return -1;
return 0;
}
static struct fts_backend_update_context *
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
struct lucene_fts_backend_update_context *ctx;
if (fts_backend_lucene_mkdir(backend) < 0)
}
static bool
{
struct lucene_fts_backend *backend =
unsigned int expunges;
/* only indexer process can actually do anything
about optimizing */
return FALSE;
}
return TRUE;
return FALSE;
return FALSE;
return expunges > 0 &&
}
static int
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
struct lucene_fts_backend *backend =
if (ctx->lucene_opened)
ret = -1;
}
return ret;
}
static void
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
}
}
static void
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
struct lucene_fts_backend *backend =
ctx->expunge_ctx =
}
}
static bool
const struct fts_backend_build_key *key)
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
struct lucene_fts_backend *backend =
if (!ctx->lucene_opened) {
}
break;
break;
i_unreached();
}
ctx->added_msgs++;
}
return TRUE;
}
static void
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
}
static int
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
struct lucene_fts_backend *backend =
int ret;
return -1;
T_BEGIN {
} T_END;
return ret;
}
static int
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
return 0;
}
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
return -1;
}
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
int ret;
if (ret == 0) {
/* log was corrupted, need to rescan */
}
if (ret >= 0)
return ret;
}
static int
struct fts_result *result)
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
int ret;
return -1;
T_BEGIN {
result);
} T_END;
return ret;
}
/* a char* hash function from ASU -- from glib */
static unsigned int wstr_hash(const void *p)
{
const wchar_t *s = p;
unsigned int g, h = 0;
while (*s != '\0') {
h = (h << 4) + *s;
if ((g = h & 0xf0000000UL)) {
h = h ^ (g >> 24);
h = h ^ g;
}
s++;
}
return h;
}
static int
{
struct fts_result *box_result;
const char *guid;
unsigned int i, j;
return -1;
for (j = 0; j < MAILBOX_GUID_HEX_LENGTH; j++)
}
(void)array_append_space(&box_results);
return 0;
}
static int
struct fts_multi_result *result)
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
int ret;
if (fts_backend_lucene_mkdir(backend) < 0)
return -1;
T_BEGIN {
struct hash_table *guids;
if (ret == 0) {
result);
}
} T_END;
return ret;
}
struct fts_backend fts_backend_lucene = {
.name = "lucene",
.flags = 0,
{
}
};