* mu-msg-iter: add mu_msg_iter_get_thread_id, make using threads non-optional

This commit is contained in:
djcb 2012-12-25 17:32:43 +02:00
parent 1a14d19cad
commit 03921e6cf1
2 changed files with 61 additions and 42 deletions

View File

@ -59,37 +59,25 @@ public:
MuMsgFieldId sortfield, MuMsgIterFlags flags):
_enq(enq), _thread_hash (0), _msg(0), _flags(flags) {
bool threads, descending;
bool descending;
threads = (flags & MU_MSG_ITER_FLAG_THREADS);
descending = (flags & MU_MSG_ITER_FLAG_DESCENDING);
_skip_unreadable = (flags & MU_MSG_ITER_FLAG_SKIP_UNREADABLE);
_skip_dups = (flags & MU_MSG_ITER_FLAG_SKIP_DUPS);
// set _skip_dups to false, so we'll calculate threadinfo
// for all, and then skip some after sorting
_skip_dups = false;
_matches = _enq.get_mset (0, maxnum);
/* if we need to calculate threads, initialy get /all/
* matches, calculate threads based on that, and then
* return maxnum messages
*/
_matches = _enq.get_mset (0, threads ? G_MAXINT: maxnum);
_matches.fetch();
_skip_dups = false;
_thread_hash = mu_threader_calculate
(this, _matches.size(), sortfield, descending);
/* when threading, we calculate the threads for the
* set of matches, then requery/sort based on the
* threading */
if (threads && !_matches.empty()) {
_matches.fetch();
_thread_hash = mu_threader_calculate
(this, _matches.size(), sortfield,
descending ? TRUE: FALSE);
ThreadKeyMaker keymaker(_thread_hash);
enq.set_sort_by_key (&keymaker, false);
_matches = _enq.get_mset (0, maxnum);
}
_cursor = _matches.begin();
ThreadKeyMaker keymaker(_thread_hash);
enq.set_sort_by_key (&keymaker, false);
_matches = _enq.get_mset (0, maxnum);
_skip_dups = (flags & MU_MSG_ITER_FLAG_SKIP_DUPS);
_cursor = _matches.begin();
/* this seems to make search slightly faster, some
* non-scientific testing suggests. 5-10% or so */
@ -126,9 +114,11 @@ public:
try {
const std::string msg_uid
(cursor().get_document().get_value(MU_MSG_FIELD_ID_MSGID));
if (_msg_uid_set.find (msg_uid) != _msg_uid_set.end())
if (_msg_uid_set.find (msg_uid) != _msg_uid_set.end()) {
// std::cerr << "dup: " << msg_uid << std::endl;
return true;
else {
} else {
// std::cerr << "no dup: " << msg_uid << std::endl;
_msg_uid_set.insert (msg_uid);
return false;
}
@ -166,13 +156,15 @@ private:
static gboolean
is_msg_file_readable (MuMsgIter *iter)
{
gboolean readable;
std::string path
(iter->cursor().get_document().get_value(MU_MSG_FIELD_ID_PATH));
if (path.empty())
return FALSE;
return (access (path.c_str(), R_OK) == 0) ? TRUE : FALSE;
readable = (access (path.c_str(), R_OK) == 0) ? TRUE : FALSE;
return readable;
}
@ -184,9 +176,6 @@ mu_msg_iter_new (XapianEnquire *enq, size_t maxnum,
{
g_return_val_if_fail (enq, NULL);
/* sortfield should be set to .._NONE when we're not threading */
g_return_val_if_fail ((flags & MU_MSG_ITER_FLAG_THREADS)
|| sortfield == MU_MSG_FIELD_ID_NONE,
NULL);
g_return_val_if_fail (mu_msg_field_id_is_valid (sortfield) ||
sortfield == MU_MSG_FIELD_ID_NONE,
FALSE);
@ -319,7 +308,11 @@ mu_msg_iter_get_msgid (MuMsgIter *iter)
g_return_val_if_fail (!mu_msg_iter_is_done(iter), NULL);
try {
return iter->cursor().get_document().get_value(MU_MSG_FIELD_ID_MSGID).c_str();
const std::string msgid (
iter->cursor().get_document().get_value(MU_MSG_FIELD_ID_MSGID).c_str());
return msgid.empty() ? NULL : msgid.c_str();
} MU_XAPIAN_CATCH_BLOCK_RETURN (NULL);
}
@ -340,6 +333,22 @@ mu_msg_iter_get_refs (MuMsgIter *iter)
} MU_XAPIAN_CATCH_BLOCK_RETURN (NULL);
}
const char*
mu_msg_iter_get_thread_id (MuMsgIter *iter)
{
g_return_val_if_fail (iter, NULL);
g_return_val_if_fail (!mu_msg_iter_is_done(iter), NULL);
try {
const std::string thread_id (
iter->cursor().get_document().get_value(MU_MSG_FIELD_ID_THREAD_ID).c_str());
return thread_id.empty() ? NULL : thread_id.c_str();
} MU_XAPIAN_CATCH_BLOCK_RETURN (NULL);
}
const MuMsgIterThreadInfo*

View File

@ -39,15 +39,13 @@ typedef struct _MuMsgIter MuMsgIter;
enum _MuMsgIterFlags {
MU_MSG_ITER_FLAG_NONE = 0,
/*calculate the threads? */
MU_MSG_ITER_FLAG_THREADS = 1 << 0,
/* sort Z->A (only for threads) */
MU_MSG_ITER_FLAG_DESCENDING = 1 << 1,
MU_MSG_ITER_FLAG_DESCENDING = 1 << 0,
/* ignore results for which there is no existing
* readable message-file? */
MU_MSG_ITER_FLAG_SKIP_UNREADABLE = 1 << 2,
MU_MSG_ITER_FLAG_SKIP_UNREADABLE = 1 << 1,
/* ignore duplicate messages? */
MU_MSG_ITER_FLAG_SKIP_DUPS = 1 << 3
MU_MSG_ITER_FLAG_SKIP_DUPS = 1 << 2
};
typedef unsigned MuMsgIterFlags;
@ -60,8 +58,7 @@ typedef unsigned MuMsgIterFlags;
* @param enq a Xapian::Enquire* cast to XapianEnquire* (because this
* is C, not C++),providing access to search results
* @param maxnum the maximum number of results
* @param sorting field for threads; when threads are not wanted, set it to
* MU_MSG_FIELD_ID_NONE
* @param sortfield field to sort by
* @param flags flags for this iterator (see MsgIterFlags)
* @param err receives error information. if the error is
@ -71,7 +68,7 @@ typedef unsigned MuMsgIterFlags;
*/
MuMsgIter *mu_msg_iter_new (XapianEnquire *enq,
size_t maxnum,
MuMsgFieldId threadsortfield,
MuMsgFieldId sortfield,
MuMsgIterFlags flags,
GError **err) G_GNUC_WARN_UNUSED_RESULT;
@ -180,7 +177,7 @@ const MuMsgIterThreadInfo* mu_msg_iter_get_thread_info (MuMsgIter *iter);
/**
* get a the message-id for this message
* get the message-id for this message
*
* @param iter a valid MuMsgIter iterator
*
@ -201,6 +198,19 @@ const char* mu_msg_iter_get_msgid (MuMsgIter *iter);
char** mu_msg_iter_get_refs (MuMsgIter *iter);
/**
* get the thread-id for this message
*
* @param iter a valid MuMsgIter iterator
*
* @return the thread-id; this only stays valid as long as the
* current iter stays valid.
*/
const char* mu_msg_iter_get_thread_id (MuMsgIter *iter);