2009-11-25 21:55:06 +01:00
|
|
|
/*
|
2010-08-25 20:40:07 +02:00
|
|
|
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
2009-11-25 21:55:06 +01:00
|
|
|
**
|
|
|
|
** This program is free software; you can redistribute it and/or modify
|
|
|
|
1** it under the terms of the GNU General Public License as published by
|
|
|
|
** the Free Software Foundation; either version 3 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** This program is distributed in the hope that it will be useful,
|
|
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
** GNU General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with this program; if not, write to the Free Software Foundation,
|
|
|
|
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
2010-09-26 16:29:54 +02:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2009-11-25 21:55:06 +01:00
|
|
|
#include "config.h"
|
2010-09-26 16:29:54 +02:00
|
|
|
#endif /*HAVE_CONFIG_H*/
|
|
|
|
|
|
|
|
#include "mu-index.h"
|
2009-11-25 21:55:06 +01:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include <glib/gstdio.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
2010-01-01 14:51:50 +01:00
|
|
|
#include "mu-maildir.h"
|
2010-08-25 20:55:08 +02:00
|
|
|
#include "mu-store.h"
|
2010-01-04 19:19:32 +01:00
|
|
|
#include "mu-util.h"
|
2009-11-25 21:55:06 +01:00
|
|
|
|
|
|
|
struct _MuIndex {
|
2010-09-12 20:19:02 +02:00
|
|
|
MuStore *_xapian;
|
|
|
|
gboolean _needs_reindex;
|
2009-11-25 21:55:06 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
MuIndex*
|
2011-01-02 17:05:43 +01:00
|
|
|
mu_index_new (const char *xpath, guint xbatchsize, GError **err)
|
2009-11-25 21:55:06 +01:00
|
|
|
{
|
|
|
|
MuIndex *index;
|
2010-01-04 19:19:32 +01:00
|
|
|
|
2010-01-06 00:25:19 +01:00
|
|
|
g_return_val_if_fail (xpath, NULL);
|
2009-12-02 22:16:57 +01:00
|
|
|
|
|
|
|
index = g_new0 (MuIndex, 1);
|
2011-01-02 17:05:43 +01:00
|
|
|
index->_xapian = mu_store_new (xpath, xbatchsize, err);
|
2009-11-25 21:55:06 +01:00
|
|
|
|
2009-12-02 22:16:57 +01:00
|
|
|
if (!index->_xapian) {
|
|
|
|
g_warning ("%s: failed to open xapian store (%s)",
|
2010-01-06 00:25:19 +01:00
|
|
|
__FUNCTION__, xpath);
|
2009-12-02 22:16:57 +01:00
|
|
|
g_free (index);
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-01-23 19:50:06 +01:00
|
|
|
|
2010-11-24 19:04:20 +01:00
|
|
|
/* see we need to reindex the database; note, there is a small
|
|
|
|
* race-condition here, between mu_index_new and
|
|
|
|
* mu_index_run. Maybe do the check in mu_index_run
|
|
|
|
* instead? */
|
2010-08-25 20:40:07 +02:00
|
|
|
if (mu_util_db_is_empty (xpath))
|
2010-01-31 11:13:06 +01:00
|
|
|
index->_needs_reindex = FALSE;
|
2010-09-09 07:18:14 +02:00
|
|
|
else
|
2010-01-31 11:13:06 +01:00
|
|
|
index->_needs_reindex =
|
2010-08-25 20:40:07 +02:00
|
|
|
mu_util_db_version_up_to_date (xpath) ? FALSE : TRUE;
|
2010-09-09 07:18:14 +02:00
|
|
|
|
2009-12-02 22:16:57 +01:00
|
|
|
return index;
|
2009-11-25 21:55:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
mu_index_destroy (MuIndex *index)
|
|
|
|
{
|
|
|
|
if (!index)
|
|
|
|
return;
|
|
|
|
|
2010-08-25 20:55:08 +02:00
|
|
|
mu_store_destroy (index->_xapian);
|
2009-11-25 21:55:06 +01:00
|
|
|
g_free (index);
|
|
|
|
}
|
|
|
|
|
2010-01-23 19:50:06 +01:00
|
|
|
|
2009-11-25 21:55:06 +01:00
|
|
|
struct _MuIndexCallbackData {
|
2010-09-12 20:19:02 +02:00
|
|
|
MuIndexMsgCallback _idx_msg_cb;
|
|
|
|
MuIndexDirCallback _idx_dir_cb;
|
|
|
|
MuStore* _xapian;
|
|
|
|
void* _user_data;
|
|
|
|
MuIndexStats* _stats;
|
|
|
|
gboolean _reindex;
|
|
|
|
time_t _dirstamp;
|
2009-11-25 21:55:06 +01:00
|
|
|
};
|
2010-09-12 20:19:02 +02:00
|
|
|
typedef struct _MuIndexCallbackData MuIndexCallbackData;
|
2009-11-25 21:55:06 +01:00
|
|
|
|
2010-01-04 21:50:26 +01:00
|
|
|
|
2010-11-27 13:54:19 +01:00
|
|
|
/* checks to determine if we need to (re)index this message
|
|
|
|
* note: just check timestamps is not good enough because
|
|
|
|
* message may be moved from other dirs (e.g. from 'new' to
|
|
|
|
* 'cur') and the time stamps won't change.
|
|
|
|
* */
|
|
|
|
static inline gboolean
|
|
|
|
needs_index (MuIndexCallbackData *data, const char *fullpath,
|
|
|
|
time_t filestamp)
|
|
|
|
{
|
|
|
|
/* unconditionally reindex */
|
|
|
|
if (data->_reindex)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* it's not in the database yet */
|
|
|
|
if (!mu_store_contains_message (data->_xapian, fullpath))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* it's there, but it's not up to date */
|
|
|
|
if ((unsigned)filestamp >= (unsigned)data->_dirstamp)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE; /* index not needed */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-25 21:55:06 +01:00
|
|
|
static MuResult
|
2010-02-08 20:21:30 +01:00
|
|
|
insert_or_update_maybe (const char* fullpath, const char* mdir,
|
2010-11-27 13:54:19 +01:00
|
|
|
time_t filestamp, MuIndexCallbackData *data,
|
|
|
|
gboolean *updated)
|
2009-11-25 21:55:06 +01:00
|
|
|
{
|
2010-08-24 23:57:16 +02:00
|
|
|
MuMsg *msg;
|
2010-11-25 20:49:25 +01:00
|
|
|
GError *err;
|
2010-01-11 19:46:14 +01:00
|
|
|
|
2009-11-25 21:55:06 +01:00
|
|
|
*updated = FALSE;
|
2010-11-27 13:54:19 +01:00
|
|
|
if (!needs_index (data, fullpath, filestamp))
|
|
|
|
return MU_OK; /* nothing to do for this one */
|
|
|
|
|
2010-11-25 20:49:25 +01:00
|
|
|
err = NULL;
|
|
|
|
msg = mu_msg_new (fullpath, mdir, &err);
|
2010-11-27 13:54:19 +01:00
|
|
|
if ((G_UNLIKELY(!msg))) {
|
2009-11-25 21:55:06 +01:00
|
|
|
g_warning ("%s: failed to create mu_msg for %s",
|
|
|
|
__FUNCTION__, fullpath);
|
|
|
|
return MU_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we got a valid id; scan the message contents as well */
|
2010-11-27 13:54:19 +01:00
|
|
|
if (G_UNLIKELY((mu_store_store (data->_xapian, msg) != MU_OK))) {
|
2009-11-25 21:55:06 +01:00
|
|
|
g_warning ("%s: storing content %s failed", __FUNCTION__,
|
|
|
|
fullpath);
|
2010-11-27 13:54:19 +01:00
|
|
|
return MU_ERROR;
|
2009-11-25 21:55:06 +01:00
|
|
|
}
|
|
|
|
|
2011-01-09 17:54:14 +01:00
|
|
|
mu_msg_unref (msg);
|
2009-11-25 21:55:06 +01:00
|
|
|
*updated = TRUE;
|
2010-01-04 21:50:26 +01:00
|
|
|
|
2009-11-25 21:55:06 +01:00
|
|
|
return MU_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static MuResult
|
2010-01-15 21:11:51 +01:00
|
|
|
run_msg_callback_maybe (MuIndexCallbackData *data)
|
2009-11-25 21:55:06 +01:00
|
|
|
{
|
2010-01-25 08:28:08 +01:00
|
|
|
MuResult result;
|
2009-12-09 23:11:30 +01:00
|
|
|
|
2010-01-25 08:28:08 +01:00
|
|
|
if (!data || !data->_idx_msg_cb)
|
|
|
|
return MU_OK;
|
|
|
|
|
|
|
|
result = data->_idx_msg_cb (data->_stats, data->_user_data);
|
2010-09-12 20:39:36 +02:00
|
|
|
if G_UNLIKELY((result != MU_OK && result != MU_STOP))
|
2010-11-30 21:20:27 +01:00
|
|
|
g_warning ("error in callback");
|
2010-01-25 08:28:08 +01:00
|
|
|
|
|
|
|
return result;
|
2009-11-25 21:55:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static MuResult
|
2010-02-08 20:21:30 +01:00
|
|
|
on_run_maildir_msg (const char* fullpath, const char* mdir,
|
|
|
|
time_t filestamp, MuIndexCallbackData *data)
|
2009-11-25 21:55:06 +01:00
|
|
|
{
|
|
|
|
MuResult result;
|
|
|
|
gboolean updated;
|
|
|
|
|
2010-01-15 21:11:51 +01:00
|
|
|
result = run_msg_callback_maybe (data);
|
2009-11-25 21:55:06 +01:00
|
|
|
if (result != MU_OK)
|
|
|
|
return result;
|
2010-02-08 20:21:30 +01:00
|
|
|
|
2009-11-25 21:55:06 +01:00
|
|
|
/* see if we need to update/insert anything...*/
|
2010-02-08 20:21:30 +01:00
|
|
|
result = insert_or_update_maybe (fullpath, mdir, filestamp, data,
|
2010-01-07 08:01:24 +01:00
|
|
|
&updated);
|
2010-01-07 20:52:44 +01:00
|
|
|
|
2009-11-25 21:55:06 +01:00
|
|
|
/* update statistics */
|
2010-01-04 21:50:26 +01:00
|
|
|
if (data && data->_stats) {
|
2009-11-25 21:55:06 +01:00
|
|
|
++data->_stats->_processed;
|
|
|
|
if (data && data->_stats) {
|
|
|
|
if (updated)
|
|
|
|
++data->_stats->_updated;
|
|
|
|
else
|
|
|
|
++data->_stats->_uptodate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static MuResult
|
|
|
|
on_run_maildir_dir (const char* fullpath, gboolean enter,
|
|
|
|
MuIndexCallbackData *data)
|
|
|
|
{
|
|
|
|
/* xapian stores a per-dir timestamp; we use this timestamp
|
|
|
|
* to determine whether a message is up-to-data
|
|
|
|
*/
|
2010-01-07 08:01:24 +01:00
|
|
|
if (enter) {
|
2009-11-25 21:55:06 +01:00
|
|
|
data->_dirstamp =
|
2010-08-25 20:55:08 +02:00
|
|
|
mu_store_get_timestamp (data->_xapian,
|
2009-11-25 21:55:06 +01:00
|
|
|
fullpath);
|
2010-01-08 19:54:01 +01:00
|
|
|
g_debug ("entering %s (ts==%u)",
|
2010-01-07 08:01:24 +01:00
|
|
|
fullpath, (unsigned)data->_dirstamp);
|
|
|
|
} else {
|
|
|
|
time_t now = time (NULL);
|
2010-08-25 20:55:08 +02:00
|
|
|
mu_store_set_timestamp (data->_xapian, fullpath,
|
2010-01-07 08:01:24 +01:00
|
|
|
now);
|
2010-01-08 19:54:01 +01:00
|
|
|
g_debug ("leaving %s (ts=%u)",
|
2010-01-07 08:01:24 +01:00
|
|
|
fullpath, (unsigned)data->_dirstamp);
|
|
|
|
}
|
2009-11-25 21:55:06 +01:00
|
|
|
|
2009-12-09 23:11:30 +01:00
|
|
|
if (data->_idx_dir_cb)
|
2009-11-25 21:55:06 +01:00
|
|
|
return data->_idx_dir_cb (fullpath, enter,
|
|
|
|
data->_user_data);
|
|
|
|
|
|
|
|
return MU_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2010-01-15 21:11:51 +01:00
|
|
|
check_path (const char* path)
|
2009-11-25 21:55:06 +01:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (path, FALSE);
|
2010-02-04 22:00:34 +01:00
|
|
|
|
|
|
|
if (!g_path_is_absolute (path)) {
|
|
|
|
g_warning ("%s: not an absolute path: %s",
|
|
|
|
__FUNCTION__, path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-11-25 21:55:06 +01:00
|
|
|
|
|
|
|
if (access (path, R_OK) != 0) {
|
|
|
|
g_warning ("%s: cannot open '%s': %s",
|
|
|
|
__FUNCTION__, path, strerror (errno));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-02-02 07:46:01 +01:00
|
|
|
static void
|
2010-08-25 20:55:08 +02:00
|
|
|
init_cb_data (MuIndexCallbackData *cb_data, MuStore *xapian,
|
2010-02-02 07:46:01 +01:00
|
|
|
gboolean reindex, MuIndexStats *stats,
|
|
|
|
MuIndexMsgCallback msg_cb, MuIndexDirCallback dir_cb,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
cb_data->_idx_msg_cb = msg_cb;
|
|
|
|
cb_data->_idx_dir_cb = dir_cb;
|
|
|
|
|
|
|
|
cb_data->_user_data = user_data;
|
|
|
|
cb_data->_xapian = xapian;
|
|
|
|
|
|
|
|
cb_data->_reindex = reindex;
|
|
|
|
cb_data->_dirstamp = 0;
|
|
|
|
|
|
|
|
cb_data->_stats = stats;
|
|
|
|
if (cb_data->_stats)
|
|
|
|
memset (cb_data->_stats, 0, sizeof(MuIndexStats));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-25 21:55:06 +01:00
|
|
|
|
|
|
|
MuResult
|
|
|
|
mu_index_run (MuIndex *index, const char* path,
|
2009-11-28 13:06:21 +01:00
|
|
|
gboolean reindex, MuIndexStats *stats,
|
2009-11-25 21:55:06 +01:00
|
|
|
MuIndexMsgCallback msg_cb, MuIndexDirCallback dir_cb,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
MuIndexCallbackData cb_data;
|
2010-01-06 00:25:19 +01:00
|
|
|
MuResult rv;
|
2009-11-25 21:55:06 +01:00
|
|
|
|
|
|
|
g_return_val_if_fail (index && index->_xapian, MU_ERROR);
|
2010-01-25 08:28:08 +01:00
|
|
|
g_return_val_if_fail (msg_cb, MU_ERROR);
|
2010-01-04 19:19:32 +01:00
|
|
|
|
2010-01-15 21:11:51 +01:00
|
|
|
if (!check_path (path))
|
2010-01-04 19:19:32 +01:00
|
|
|
return MU_ERROR;
|
2010-01-23 19:50:06 +01:00
|
|
|
|
|
|
|
if (!reindex && index->_needs_reindex) {
|
|
|
|
g_warning ("database not up-to-date; needs full reindex");
|
|
|
|
return MU_ERROR;
|
|
|
|
}
|
|
|
|
|
2010-02-02 07:46:01 +01:00
|
|
|
init_cb_data (&cb_data, index->_xapian, reindex, stats,
|
|
|
|
msg_cb, dir_cb, user_data);
|
2009-11-25 21:55:06 +01:00
|
|
|
|
2010-01-06 00:25:19 +01:00
|
|
|
rv = mu_maildir_walk (path,
|
|
|
|
(MuMaildirWalkMsgCallback)on_run_maildir_msg,
|
|
|
|
(MuMaildirWalkDirCallback)on_run_maildir_dir,
|
|
|
|
&cb_data);
|
2010-01-23 19:50:06 +01:00
|
|
|
|
2010-08-25 20:55:08 +02:00
|
|
|
mu_store_flush (index->_xapian);
|
2010-09-12 20:39:36 +02:00
|
|
|
|
2010-01-06 00:25:19 +01:00
|
|
|
return rv;
|
2009-11-25 21:55:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static MuResult
|
2010-02-08 20:21:30 +01:00
|
|
|
on_stats_maildir_file (const char *fullpath, const char* mdir,
|
|
|
|
time_t timestamp,
|
2009-11-25 21:55:06 +01:00
|
|
|
MuIndexCallbackData *cb_data)
|
|
|
|
{
|
|
|
|
MuResult result;
|
|
|
|
|
|
|
|
if (cb_data && cb_data->_idx_msg_cb)
|
|
|
|
result = cb_data->_idx_msg_cb (cb_data->_stats,
|
|
|
|
cb_data->_user_data);
|
|
|
|
else
|
|
|
|
result = MU_OK;
|
|
|
|
|
2009-12-09 23:11:30 +01:00
|
|
|
if (result == MU_OK) {
|
2009-11-25 21:55:06 +01:00
|
|
|
if (cb_data->_stats)
|
|
|
|
++cb_data->_stats->_processed;
|
|
|
|
return MU_OK;
|
2009-12-09 23:11:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result; /* MU_STOP or MU_OK */
|
2009-11-25 21:55:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MuResult
|
|
|
|
mu_index_stats (MuIndex *index, const char* path,
|
|
|
|
MuIndexStats *stats, MuIndexMsgCallback cb_msg,
|
|
|
|
MuIndexDirCallback cb_dir, void *user_data)
|
|
|
|
{
|
|
|
|
MuIndexCallbackData cb_data;
|
|
|
|
|
|
|
|
g_return_val_if_fail (index, MU_ERROR);
|
2010-01-25 08:28:08 +01:00
|
|
|
g_return_val_if_fail (cb_msg, MU_ERROR);
|
|
|
|
|
2010-01-15 21:11:51 +01:00
|
|
|
if (!check_path (path))
|
2010-01-04 19:19:32 +01:00
|
|
|
return MU_ERROR;
|
2009-11-25 21:55:06 +01:00
|
|
|
|
2009-12-05 15:38:47 +01:00
|
|
|
if (stats)
|
|
|
|
memset (stats, 0, sizeof(MuIndexStats));
|
|
|
|
|
2009-11-25 21:55:06 +01:00
|
|
|
cb_data._idx_msg_cb = cb_msg;
|
|
|
|
cb_data._idx_dir_cb = cb_dir;
|
|
|
|
|
|
|
|
cb_data._stats = stats;
|
|
|
|
cb_data._user_data = user_data;
|
|
|
|
|
|
|
|
cb_data._dirstamp = 0;
|
|
|
|
|
2010-01-01 14:51:50 +01:00
|
|
|
return mu_maildir_walk (path,
|
|
|
|
(MuMaildirWalkMsgCallback)on_stats_maildir_file,
|
2009-12-31 11:58:46 +01:00
|
|
|
NULL,&cb_data);
|
2009-11-25 21:55:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-03 22:54:22 +01:00
|
|
|
struct _CleanupData {
|
2010-08-25 20:55:08 +02:00
|
|
|
MuStore *_xapian;
|
2010-01-03 22:54:22 +01:00
|
|
|
MuIndexStats *_stats;
|
|
|
|
MuIndexCleanupDeleteCallback _cb;
|
|
|
|
void *_user_data;
|
|
|
|
|
|
|
|
};
|
|
|
|
typedef struct _CleanupData CleanupData;
|
|
|
|
|
|
|
|
|
|
|
|
static MuResult
|
2010-01-15 21:11:51 +01:00
|
|
|
foreach_doc_cb (const char* path, CleanupData *cudata)
|
2009-11-25 21:55:06 +01:00
|
|
|
{
|
2010-01-05 08:08:39 +01:00
|
|
|
MuResult rv;
|
|
|
|
|
2010-01-03 22:54:22 +01:00
|
|
|
if (access (path, R_OK) != 0) {
|
2010-01-05 08:08:39 +01:00
|
|
|
|
2010-01-06 00:25:19 +01:00
|
|
|
g_debug ("not readable: %s; removing", path);
|
2010-08-25 20:55:08 +02:00
|
|
|
rv = mu_store_remove (cudata->_xapian, path);
|
2010-01-05 08:08:39 +01:00
|
|
|
if (rv != MU_OK)
|
|
|
|
return rv; /* something went wrong... bail out */
|
|
|
|
|
2010-01-04 19:19:32 +01:00
|
|
|
if (cudata->_stats)
|
|
|
|
++cudata->_stats->_cleaned_up;
|
2010-01-03 22:54:22 +01:00
|
|
|
}
|
|
|
|
|
2010-01-04 19:19:32 +01:00
|
|
|
if (cudata->_stats)
|
|
|
|
++cudata->_stats->_processed;
|
|
|
|
|
2010-01-03 22:54:22 +01:00
|
|
|
if (!cudata->_cb)
|
|
|
|
return MU_OK;
|
2009-11-26 19:28:29 +01:00
|
|
|
|
2010-01-03 22:54:22 +01:00
|
|
|
return cudata->_cb (cudata->_stats, cudata->_user_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MuResult
|
|
|
|
mu_index_cleanup (MuIndex *index, MuIndexStats *stats,
|
|
|
|
MuIndexCleanupDeleteCallback cb,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
MuResult rv;
|
|
|
|
CleanupData cudata;
|
|
|
|
|
|
|
|
g_return_val_if_fail (index, MU_ERROR);
|
2010-01-25 08:28:08 +01:00
|
|
|
g_return_val_if_fail (cb, MU_ERROR);
|
|
|
|
|
2010-01-03 22:54:22 +01:00
|
|
|
cudata._xapian = index->_xapian;
|
|
|
|
cudata._stats = stats;
|
|
|
|
cudata._cb = cb;
|
|
|
|
cudata._user_data = user_data;
|
|
|
|
|
2010-08-25 20:55:08 +02:00
|
|
|
rv = mu_store_foreach (index->_xapian,
|
|
|
|
(MuStoreForeachFunc)foreach_doc_cb,
|
2010-01-03 22:54:22 +01:00
|
|
|
&cudata);
|
2010-08-25 20:55:08 +02:00
|
|
|
mu_store_flush (index->_xapian);
|
2010-01-06 00:25:19 +01:00
|
|
|
|
2010-01-03 22:54:22 +01:00
|
|
|
return rv;
|
2010-01-03 12:41:32 +01:00
|
|
|
}
|
2010-01-04 19:19:32 +01:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
mu_index_stats_clear (MuIndexStats *stats)
|
|
|
|
{
|
|
|
|
if (!stats)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
memset (stats, 0, sizeof(MuIndexStats));
|
|
|
|
return TRUE;
|
|
|
|
}
|