fts-backend-lucene.c revision a6de00f8d3f65335149f6fe828fca9da6328d42a
/* 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 "file-dotlock.h"
#include "mail-namespace.h"
#include "mail-storage-private.h"
#include "lucene-wrapper.h"
#include "fts-lucene-plugin.h"
#include <wchar.h>
#define LUCENE_INDEX_DIR_NAME "lucene-indexes"
#define LUCENE_EXPUNGE_FILENAME "pending-expunges"
#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 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, expunges;
};
{
if (backend->dir_created)
return 0;
}
static int
{
struct mailbox_metadata metadata;
unsigned char guid_hex[MAILBOX_GUID_HEX_LENGTH];
unsigned int i;
return 0;
if (fts_backend_lucene_mkdir(backend) < 0)
return -1;
&metadata) < 0) {
i_error("fts-lucene: Couldn't get mailbox %s GUID: %s",
return -1;
}
for (i = 0; i < N_ELEMENTS(wguid_hex); i++)
} else {
}
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;
const char *path;
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 =
const struct dotlock_settings dotlock_set = {
.timeout = 1,
.stale_timeout = 30,
};
const char *path;
unsigned int expunges = 0;
return TRUE;
return FALSE;
numdocs == 0)
return FALSE;
/* update pending expunges count */
if (fdw == -1)
return FALSE;
if (fdr == -1) {
} else {
if (ret < 0)
else {
}
}
(void)file_dotlock_replace(&dotlock, 0);
}
static int
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
struct lucene_fts_backend *backend =
return ret;
}
static void
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
struct lucene_fts_backend *backend =
}
}
static void
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
}
static bool
const struct fts_backend_build_key *key)
{
struct lucene_fts_backend_update_context *ctx =
(struct lucene_fts_backend_update_context *)_ctx;
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
{
return 0;
}
static int
{
struct mailbox_status status;
return -1;
} T_END;
return 0;
}
static int
{
struct mailbox_status status;
unsigned int count;
/* FIXME: missing_uids from the middle of mailbox could probably
be handled better. they now create duplicates on next indexing? */
if (count > 0)
else {
}
}
{
struct lucene_fts_backend *backend =
(struct lucene_fts_backend *)_backend;
struct mailbox_list_iterate_context *iter;
const struct mailbox_info *info;
int ret = 0;
(MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) != 0)
continue;
&missing_uids) < 0 ||
ret = -1;
mailbox_free(&box);
array_clear(&uids);
}
if (mailbox_list_iter_deinit(&iter) < 0)
ret = -1;
/* FIXME: optionally go through mailboxes in index and delete those
that don't exist anymre */
ret = -1;
array_free(&uids);
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,
{
}
};