Skip to content

Commit

Permalink
* mu-store-(read|write).cc: cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
Dirk-Jan C. Binnema committed Sep 18, 2011
1 parent 2b41379 commit a984a70
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 49 deletions.
14 changes: 11 additions & 3 deletions src/mu-store-priv.hh
Expand Up @@ -150,8 +150,7 @@ public:

/* get a unique id for this message; note, this function returns a
* static buffer -- not reentrant */
const char* get_message_uid (const char* path);
const char* get_message_uid (MuMsg *msg);
const char *get_uid_term (const char *path);

MuContacts* contacts() { return _contacts; }

Expand Down Expand Up @@ -196,7 +195,11 @@ public:

/* MuStore is ref-counted */
guint ref () { return ++_ref_count; }
guint unref () { return --_ref_count; }
guint unref () {
if (_ref_count < 1)
g_critical ("ref count error");
return --_ref_count;
}

/* by default, use transactions of 30000 messages */
static const unsigned DEFAULT_BATCH_SIZE = 30000;
Expand All @@ -222,4 +225,9 @@ private:
};


/* Xapian DB prefix for the UID value */
#define MU_STORE_UID_PREFIX "Q"



#endif /*__MU_STORE_PRIV_HH__*/
65 changes: 47 additions & 18 deletions src/mu-store-read.cc
Expand Up @@ -39,27 +39,32 @@
#include "mu-flags.h"
#include "mu-contacts.h"

/* get a unique id for this message; note, this function returns a
* static buffer -- not reentrant */

// note: not re-entrant
const char*
_MuStore::get_message_uid (const char* path) {
char pfx = 0;
static char buf[PATH_MAX + 10];
if (G_UNLIKELY(!pfx)) {
pfx = mu_msg_field_xapian_prefix(MU_MSG_FIELD_ID_PATH);
buf[0]=pfx;
_MuStore::get_uid_term (const char* path)
{
// combination of DJB, BKDR hash functions to get a 64 bit
// value

unsigned djbhash, bkdrhash, bkdrseed;
unsigned u;
static char hex[18];

djbhash = 5381;
bkdrhash = 0;
bkdrseed = 1313;


for(u = 0; path[u]; ++u) {
djbhash = ((djbhash << 5) + djbhash) + path[u];
bkdrhash = bkdrhash * bkdrseed + path[u];
}
std::strcpy (buf + 1, path);
return buf;
}

/* get a unique id for this message; note, this function returns a
* static buffer -- not reentrant */
const char*
_MuStore::get_message_uid (MuMsg *msg) {
return get_message_uid (mu_msg_get_path(msg));
}
sprintf (hex, MU_STORE_UID_PREFIX "%08x%08x", djbhash, bkdrhash);

return hex;
}


MuStore*
Expand Down Expand Up @@ -155,14 +160,38 @@ mu_store_contains_message (MuStore *store, const char* path, GError **err)
g_return_val_if_fail (path, FALSE);

try {
const std::string uid (store->get_message_uid(path));
const std::string uid (store->get_uid_term (path));
return store->db_read_only()->term_exists (uid) ? TRUE: FALSE;

} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN(err, MU_ERROR_XAPIAN, FALSE);

}


unsigned
mu_store_get_docid_for_path (MuStore *store, const char* path, GError **err)
{
g_return_val_if_fail (store, FALSE);
g_return_val_if_fail (path, FALSE);

try {
Xapian::Query query (store->get_uid_term (path)); // uid is a term
Xapian::Enquire enq (*store->db_read_only());

enq.set_query (query);

Xapian::MSet mset (enq.get_mset (0,1));
if (mset.empty())
throw MuStoreError (MU_ERROR_NO_MATCHES,
"message not found");

return *mset.begin();

} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN(err, MU_ERROR_XAPIAN,
MU_STORE_INVALID_DOCID);
}



time_t
mu_store_get_timestamp (MuStore *store, const char* msgpath, GError **err)
Expand Down
80 changes: 52 additions & 28 deletions src/mu-store-write.cc
Expand Up @@ -557,41 +557,37 @@ each_contact_info (MuMsgContact *contact, MsgDoc *msgdoc)
}


Xapian::Document
doc_from_message (MuStore *store, MuMsg *msg)
{
Xapian::Document doc;
MsgDoc docinfo = {&doc, msg, store};

mu_msg_field_foreach ((MuMsgFieldForEachFunc)add_terms_values, &docinfo);
/* also store the contact-info as separate terms */
mu_msg_contact_foreach (msg, (MuMsgContactForeachFunc)each_contact_info,
&docinfo);
return doc;
}


unsigned
mu_store_add_msg (MuStore *store, MuMsg *msg, gboolean replace,
GError **err)
mu_store_add_msg (MuStore *store, MuMsg *msg, GError **err)
{
g_return_val_if_fail (store, MU_STORE_INVALID_DOCID);
g_return_val_if_fail (msg, MU_STORE_INVALID_DOCID);

try {
Xapian::Document newdoc;
Xapian::docid id;
MsgDoc msgdoc = { &newdoc, msg, store };
const std::string uid(store->get_message_uid(msg));
Xapian::Document doc (doc_from_message(store, msg));
const std::string uid (store->get_uid_term(mu_msg_get_path(msg)));

if (!store->in_transaction())
store->begin_transaction();

/* we must add a unique term, so we can replace
* matching documents */
newdoc.add_term (uid);
mu_msg_field_foreach
((MuMsgFieldForEachFunc)add_terms_values, &msgdoc);
/* also store the contact-info as separate terms */
mu_msg_contact_foreach
(msg,
(MuMsgContactForeachFunc)each_contact_info,
&msgdoc);

/* add_document is slightly
faster, we can use it when
* we know the document does not exist yet, eg., in
* case of a rebuild */
if (replace) /* we replace all existing documents for this file */
id = store->db_writable()->replace_document (uid, newdoc);
else
id = store->db_writable()->add_document (newdoc);
/* note, this will replace any other messages for this path */
doc.add_term (uid);
id = store->db_writable()->replace_document (uid, doc);

if (store->inc_processed() % store->batch_size() == 0)
store->commit_transaction();
Expand All @@ -607,6 +603,36 @@ mu_store_add_msg (MuStore *store, MuMsg *msg, gboolean replace,
}


unsigned
mu_store_update_msg (MuStore *store, unsigned docid, MuMsg *msg, GError **err)
{
g_return_val_if_fail (store, MU_STORE_INVALID_DOCID);
g_return_val_if_fail (msg, MU_STORE_INVALID_DOCID);
g_return_val_if_fail (docid != 0, MU_STORE_INVALID_DOCID);

try {
Xapian::Document doc (doc_from_message(store, msg));

if (!store->in_transaction())
store->begin_transaction();

store->db_writable()->replace_document (docid, doc);

if (store->inc_processed() % store->batch_size() == 0)
store->commit_transaction();

return docid;

} MU_XAPIAN_CATCH_BLOCK_G_ERROR (err, MU_ERROR_XAPIAN_STORE_FAILED);

if (store->in_transaction())
store->rollback_transaction();

return MU_STORE_INVALID_DOCID;
}



unsigned
mu_store_add_path (MuStore *store, const char *path, GError **err)
{
Expand All @@ -621,7 +647,7 @@ mu_store_add_path (MuStore *store, const char *path, GError **err)
if (!msg)
return MU_STORE_INVALID_DOCID;

docid = mu_store_add_msg (store, msg, TRUE, err);
docid = mu_store_add_msg (store, msg, err);
mu_msg_unref (msg);

return docid;
Expand All @@ -644,9 +670,7 @@ mu_store_remove_path (MuStore *store, const char *msgpath)
g_return_val_if_fail (msgpath, FALSE);

try {
const std::string uid (store->get_message_uid (msgpath));

store->db_writable()->delete_document (uid);
store->db_writable()->delete_document (store->get_uid_term (msgpath));
store->inc_processed();

return TRUE;
Expand Down

0 comments on commit a984a70

Please sign in to comment.