diff --git a/src/mu-msg-iter.cc b/src/mu-msg-iter.cc index c3576f57..1d3af73a 100644 --- a/src/mu-msg-iter.cc +++ b/src/mu-msg-iter.cc @@ -1,5 +1,5 @@ /* -*- mode: c++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- -** +** ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema ** ** This program is free software; you can redistribute it and/or modify @@ -41,28 +41,29 @@ public: MuMsgIterThreadInfo *ti; ti = (MuMsgIterThreadInfo*)g_hash_table_lookup (_threadinfo, - GUINT_TO_POINTER(doc.get_docid())); + GUINT_TO_POINTER(doc.get_docid())); return std::string (ti && ti->threadpath ? ti->threadpath : ""); } private: - GHashTable *_threadinfo; + GHashTable *_threadinfo; }; struct _MuMsgIter { +public: _MuMsgIter (Xapian::Enquire &enq, size_t maxnum, gboolean threads, MuMsgFieldId sortfield): - _enq(enq), _msg(0), _threadhash (0) { - + _enq(enq), _thread_hash (0), _msg(0) { + _matches = _enq.get_mset (0, maxnum); - if (threads && !_matches.empty()) { + if (threads && !_matches.empty()) { _matches.fetch(); - _threadhash = mu_threader_calculate + _thread_hash = mu_threader_calculate (this, _matches.size(), sortfield); - ThreadKeyMaker keymaker(_threadhash); + ThreadKeyMaker keymaker(_thread_hash); enq.set_sort_by_key (&keymaker, false); _matches = _enq.get_mset (0, maxnum); @@ -71,25 +72,39 @@ struct _MuMsgIter { _cursor = _matches.begin(); /* this seems to make search slightly faster, some - * non-scientific testing suggests. 5-10% or so */ + * non-scientific testing suggests. 5-10% or so */ if (_matches.size() <= MAX_FETCH_SIZE) _matches.fetch (); } - + ~_MuMsgIter () { + if (_thread_hash) + g_hash_table_destroy (_thread_hash); + set_msg (NULL); + } + + const Xapian::Enquire& enquire() { return _enq; } + Xapian::MSet& matches() { return _matches; } + + Xapian::MSet::const_iterator cursor () const { return _cursor; } + void set_cursor (Xapian::MSetIterator cur) { _cursor = cur; } + void cursor_next () { ++_cursor; } + + GHashTable *thread_hash () { return _thread_hash; } + + MuMsg *msg() { return _msg; } + MuMsg *set_msg (MuMsg *msg) { if (_msg) mu_msg_unref (_msg); - - if (_threadhash) - g_hash_table_destroy (_threadhash); + return _msg = msg; } - +private: const Xapian::Enquire _enq; Xapian::MSet _matches; Xapian::MSet::const_iterator _cursor; - + + GHashTable *_thread_hash; MuMsg *_msg; - GHashTable *_threadhash; }; MuMsgIter* @@ -103,11 +118,10 @@ mu_msg_iter_new (XapianEnquire *enq, size_t maxnum, g_return_val_if_fail (mu_msg_field_id_is_valid (sortfield) || sortfield == MU_MSG_FIELD_ID_NONE, FALSE); - try { return new MuMsgIter ((Xapian::Enquire&)*enq, maxnum, threads, sortfield); - + } MU_XAPIAN_CATCH_BLOCK_RETURN(NULL); } @@ -115,143 +129,112 @@ mu_msg_iter_new (XapianEnquire *enq, size_t maxnum, void mu_msg_iter_destroy (MuMsgIter *iter) { - try { delete iter; } MU_XAPIAN_CATCH_BLOCK; + try { delete iter; } MU_XAPIAN_CATCH_BLOCK; } - + MuMsg* -mu_msg_iter_get_msg (MuMsgIter *iter, GError **err) +mu_msg_iter_get_msg_floating (MuMsgIter *iter) { - Xapian::Document *docp; - - g_return_val_if_fail (iter, NULL); - g_return_val_if_fail (!mu_msg_iter_is_done(iter), NULL); - - /* get a new MuMsg based on the current doc */ - if (iter->_msg) { - mu_msg_unref (iter->_msg); - iter->_msg = NULL; - } + g_return_val_if_fail (iter, NULL); + g_return_val_if_fail (!mu_msg_iter_is_done(iter), NULL); - docp = new Xapian::Document(iter->_cursor.get_document()); - iter->_msg = mu_msg_new_from_doc ((XapianDocument*)docp, err); - if (!iter->_msg) { - g_warning ("%s: failed to create MuMsg",__FUNCTION__); - return NULL; - } + try { + MuMsg *msg; + GError *err; + Xapian::Document *docp; - return iter->_msg; + docp = new Xapian::Document(iter->cursor().get_document()); + + err = NULL; + msg = iter->set_msg (mu_msg_new_from_doc ((XapianDocument*)docp, &err)); + if (!msg) + MU_HANDLE_G_ERROR(err); + + return msg; + + } MU_XAPIAN_CATCH_BLOCK_RETURN (NULL); } gboolean mu_msg_iter_reset (MuMsgIter *iter) { - g_return_val_if_fail (iter, FALSE); + g_return_val_if_fail (iter, FALSE); - try { - iter->_cursor = iter->_matches.begin(); - - } MU_XAPIAN_CATCH_BLOCK_RETURN (FALSE); + iter->set_msg (NULL); - return TRUE; + try { + iter->set_cursor(iter->matches().begin()); + + } MU_XAPIAN_CATCH_BLOCK_RETURN (FALSE); + + return TRUE; } gboolean mu_msg_iter_next (MuMsgIter *iter) { - g_return_val_if_fail (iter, FALSE); - - if (mu_msg_iter_is_done(iter)) - return FALSE; - - try { - ++iter->_cursor; - return iter->_cursor == iter->_matches.end() ? FALSE:TRUE; - /* try to get a new MuMsg based on the current doc */ - //return update_msg (iter); - - } MU_XAPIAN_CATCH_BLOCK_RETURN(FALSE); + g_return_val_if_fail (iter, FALSE); + + iter->set_msg (NULL); + + if (mu_msg_iter_is_done(iter)) + return FALSE; + + try { + iter->cursor_next(); + return iter->cursor() == iter->matches().end() ? FALSE:TRUE; + + } MU_XAPIAN_CATCH_BLOCK_RETURN(FALSE); } - - gboolean mu_msg_iter_is_done (MuMsgIter *iter) { g_return_val_if_fail (iter, TRUE); try { - return iter->_cursor == iter->_matches.end() ? TRUE : FALSE; + return iter->cursor() == iter->matches().end() ? TRUE : FALSE; } MU_XAPIAN_CATCH_BLOCK_RETURN (TRUE); } -static const gchar* -get_field (MuMsgIter *iter, MuMsgFieldId mfid) -{ - return mu_msg_get_field_string (iter->_msg, mfid); -} - -const gchar* -mu_msg_iter_get_field (MuMsgIter *iter, MuMsgFieldId mfid) -{ - g_return_val_if_fail (!mu_msg_iter_is_done(iter), NULL); - g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), NULL); - - return get_field (iter, mfid); -} - -static gint64 -get_field_numeric (MuMsgIter *iter, MuMsgFieldId mfid) -{ - return mu_msg_get_field_numeric (iter->_msg, mfid); -} - - -gint64 -mu_msg_iter_get_field_numeric (MuMsgIter *iter, MuMsgFieldId mfid) -{ - g_return_val_if_fail (!mu_msg_iter_is_done(iter), -1); - g_return_val_if_fail (mu_msg_field_is_numeric(mfid), -1); - - return get_field_numeric (iter, mfid); -} /* hmmm.... is it impossible to get a 0 docid, or just very improbable? */ unsigned int mu_msg_iter_get_docid (MuMsgIter *iter) { g_return_val_if_fail (!mu_msg_iter_is_done(iter), - (unsigned int)-1); + (unsigned int)-1); try { - return iter->_cursor.get_document().get_docid(); + return iter->cursor().get_document().get_docid(); } MU_XAPIAN_CATCH_BLOCK_RETURN (0); } + const MuMsgIterThreadInfo* mu_msg_iter_get_thread_info (MuMsgIter *iter) { g_return_val_if_fail (!mu_msg_iter_is_done(iter), NULL); - g_return_val_if_fail (iter->_threadhash, NULL); + g_return_val_if_fail (iter->thread_hash(), NULL); try { const MuMsgIterThreadInfo *ti; unsigned int docid; - + docid = mu_msg_iter_get_docid (iter); ti = (const MuMsgIterThreadInfo*)g_hash_table_lookup - (iter->_threadhash, - GUINT_TO_POINTER(docid)); + (iter->thread_hash(), GUINT_TO_POINTER(docid)); if (!ti) g_printerr ("no ti for %u\n", docid); - + return ti; - + } MU_XAPIAN_CATCH_BLOCK_RETURN (NULL); } diff --git a/src/mu-msg-iter.h b/src/mu-msg-iter.h index 04cd6f0d..8ce04a09 100644 --- a/src/mu-msg-iter.h +++ b/src/mu-msg-iter.h @@ -30,7 +30,7 @@ G_BEGIN_DECLS * MuMsgIter is a structure to iterate over the results of a * query. You can iterate only in one-direction, and you can do it * only once. - * + * */ struct _MuMsgIter; @@ -40,14 +40,14 @@ typedef struct _MuMsgIter MuMsgIter; /** * create a new MuMsgIter -- basically, an iterator over the search * results - * + * * @param enq a Xapian::Enquire* cast to XapianEnquire* (because this * is C, not C++),providing access to search results * @param batchsize how many results to retrieve at once * @param threads whether to calculate threads * @param sorting field when using threads; note, when 'threads' is * FALSE, this should be MU_MSG_FIELD_ID_NONE - * + * * @return a new MuMsgIter, or NULL in case of error */ MuMsgIter *mu_msg_iter_new (XapianEnquire *enq, @@ -58,9 +58,9 @@ MuMsgIter *mu_msg_iter_new (XapianEnquire *enq, /** * get the next message (which you got from * e.g. mu_query_run) - * + * * @param iter a valid MuMsgIter iterator - * + * * @return TRUE if it succeeded, FALSE otherwise (e.g., because there * are no more messages in the query result) */ @@ -70,18 +70,18 @@ gboolean mu_msg_iter_next (MuMsgIter *iter); /** * reset the iterator to the beginning - * + * * @param iter a valid MuMsgIter iterator - * + * * @return TRUE if it succeeded, FALSE otherwise */ gboolean mu_msg_iter_reset (MuMsgIter *iter); /** * does this iterator point past the end of the list? - * + * * @param iter a valid MuMsgIter iterator - * + * * @return TRUE if the iter points past end of the list, FALSE * otherwise */ @@ -90,7 +90,7 @@ gboolean mu_msg_iter_is_done (MuMsgIter *iter); /** * destroy the sequence of messages; ie. /all/ of them - * + * * @param msg a valid MuMsgIter message or NULL */ void mu_msg_iter_destroy (MuMsgIter *iter); @@ -99,24 +99,22 @@ void mu_msg_iter_destroy (MuMsgIter *iter); /** * get the corresponding MuMsg for this iter; this instance is owned * by MuMsgIter, and becomes invalid after either mu_msg_iter_destroy - * or mu_msg_iter_next. _do not_ unref it. - * - * @param iter a valid MuMsgIter instance - * @param err which receives error info or NULL. err is only filled - * when the function returns NULL - * + * or mu_msg_iter_next. _do not_ unref it; it's a floating reference. + * + * @param iter a valid MuMsgIter instance* + * * @return a MuMsg instance, or NULL in case of error */ -MuMsg* mu_msg_iter_get_msg (MuMsgIter *iter, GError **err) +MuMsg* mu_msg_iter_get_msg_floating (MuMsgIter *iter) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; /** * get the document id for the current message - * + * * @param iter a valid MuMsgIter iterator - * + * * @return the docid or (unsigned int)-1 in case of error */ unsigned int mu_msg_iter_get_docid (MuMsgIter *iter); @@ -124,9 +122,9 @@ unsigned int mu_msg_iter_get_docid (MuMsgIter *iter); /** * calculate the message threads - * - * @param iter a valid MuMsgIter iterator - * + * + * @param iter a valid MuMsgIter iterator + * * @return TRUE if it worked, FALSE otherwsie. */ gboolean mu_msg_iter_calculate_threads (MuMsgIter *iter); @@ -149,34 +147,16 @@ typedef struct _MuMsgIterThreadInfo MuMsgIterThreadInfo; /** * get a the MuMsgThreaderInfo struct for this message; this only * works when you created the mu-msg-iter with threading enabled - * - * @param iter a valid MuMsgIter iterator - * + * + * @param iter a valid MuMsgIter iterator + * * @return an info struct */ const MuMsgIterThreadInfo* mu_msg_iter_get_thread_info (MuMsgIter *iter); -/** - * get some message field - * - * @param iter a valid MuMsgIter iterator - * @param field the string field to retrieve - * - * @return the field value, or NULL - */ -const gchar* mu_msg_iter_get_field (MuMsgIter *iter, - MuMsgFieldId mfid); +/* FIXME */ +const char* mu_msg_iter_get_path (MuMsgIter *iter); -/** - * get some numeric message field - * - * @param iter a valid MuMsgIter iterator - * @param field the numeric field to retrieve - * - * @return the field value, or -1 in case of error - */ -gint64 mu_msg_iter_get_field_numeric (MuMsgIter *iter, - MuMsgFieldId mfid); G_END_DECLS #endif /*__MU_MSG_ITER_H__*/