mirror of https://github.com/djcb/mu.git
* mu-store-(read|write).cc: cleanups
This commit is contained in:
parent
2b41379183
commit
a984a70543
|
@ -150,8 +150,7 @@ public:
|
||||||
|
|
||||||
/* get a unique id for this message; note, this function returns a
|
/* get a unique id for this message; note, this function returns a
|
||||||
* static buffer -- not reentrant */
|
* static buffer -- not reentrant */
|
||||||
const char* get_message_uid (const char* path);
|
const char *get_uid_term (const char *path);
|
||||||
const char* get_message_uid (MuMsg *msg);
|
|
||||||
|
|
||||||
MuContacts* contacts() { return _contacts; }
|
MuContacts* contacts() { return _contacts; }
|
||||||
|
|
||||||
|
@ -196,7 +195,11 @@ public:
|
||||||
|
|
||||||
/* MuStore is ref-counted */
|
/* MuStore is ref-counted */
|
||||||
guint ref () { return ++_ref_count; }
|
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 */
|
/* by default, use transactions of 30000 messages */
|
||||||
static const unsigned DEFAULT_BATCH_SIZE = 30000;
|
static const unsigned DEFAULT_BATCH_SIZE = 30000;
|
||||||
|
@ -222,4 +225,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Xapian DB prefix for the UID value */
|
||||||
|
#define MU_STORE_UID_PREFIX "Q"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*__MU_STORE_PRIV_HH__*/
|
#endif /*__MU_STORE_PRIV_HH__*/
|
||||||
|
|
|
@ -39,27 +39,32 @@
|
||||||
#include "mu-flags.h"
|
#include "mu-flags.h"
|
||||||
#include "mu-contacts.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*
|
const char*
|
||||||
_MuStore::get_message_uid (const char* path) {
|
_MuStore::get_uid_term (const char* path)
|
||||||
char pfx = 0;
|
{
|
||||||
static char buf[PATH_MAX + 10];
|
// combination of DJB, BKDR hash functions to get a 64 bit
|
||||||
if (G_UNLIKELY(!pfx)) {
|
// value
|
||||||
pfx = mu_msg_field_xapian_prefix(MU_MSG_FIELD_ID_PATH);
|
|
||||||
buf[0]=pfx;
|
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
|
sprintf (hex, MU_STORE_UID_PREFIX "%08x%08x", djbhash, bkdrhash);
|
||||||
* static buffer -- not reentrant */
|
|
||||||
const char*
|
|
||||||
_MuStore::get_message_uid (MuMsg *msg) {
|
|
||||||
return get_message_uid (mu_msg_get_path(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MuStore*
|
MuStore*
|
||||||
|
@ -155,7 +160,7 @@ mu_store_contains_message (MuStore *store, const char* path, GError **err)
|
||||||
g_return_val_if_fail (path, FALSE);
|
g_return_val_if_fail (path, FALSE);
|
||||||
|
|
||||||
try {
|
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;
|
return store->db_read_only()->term_exists (uid) ? TRUE: FALSE;
|
||||||
|
|
||||||
} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN(err, MU_ERROR_XAPIAN, FALSE);
|
} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN(err, MU_ERROR_XAPIAN, FALSE);
|
||||||
|
@ -163,6 +168,30 @@ mu_store_contains_message (MuStore *store, const char* path, GError **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
time_t
|
||||||
mu_store_get_timestamp (MuStore *store, const char* msgpath, GError **err)
|
mu_store_get_timestamp (MuStore *store, const char* msgpath, GError **err)
|
||||||
|
|
|
@ -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
|
unsigned
|
||||||
mu_store_add_msg (MuStore *store, MuMsg *msg, gboolean replace,
|
mu_store_add_msg (MuStore *store, MuMsg *msg, GError **err)
|
||||||
GError **err)
|
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (store, MU_STORE_INVALID_DOCID);
|
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 (msg, MU_STORE_INVALID_DOCID);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Xapian::Document newdoc;
|
|
||||||
Xapian::docid id;
|
Xapian::docid id;
|
||||||
MsgDoc msgdoc = { &newdoc, msg, store };
|
Xapian::Document doc (doc_from_message(store, msg));
|
||||||
const std::string uid(store->get_message_uid(msg));
|
const std::string uid (store->get_uid_term(mu_msg_get_path(msg)));
|
||||||
|
|
||||||
if (!store->in_transaction())
|
if (!store->in_transaction())
|
||||||
store->begin_transaction();
|
store->begin_transaction();
|
||||||
|
|
||||||
/* we must add a unique term, so we can replace
|
/* note, this will replace any other messages for this path */
|
||||||
* matching documents */
|
doc.add_term (uid);
|
||||||
newdoc.add_term (uid);
|
id = store->db_writable()->replace_document (uid, doc);
|
||||||
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);
|
|
||||||
|
|
||||||
if (store->inc_processed() % store->batch_size() == 0)
|
if (store->inc_processed() % store->batch_size() == 0)
|
||||||
store->commit_transaction();
|
store->commit_transaction();
|
||||||
|
@ -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
|
unsigned
|
||||||
mu_store_add_path (MuStore *store, const char *path, GError **err)
|
mu_store_add_path (MuStore *store, const char *path, GError **err)
|
||||||
{
|
{
|
||||||
|
@ -621,7 +647,7 @@ mu_store_add_path (MuStore *store, const char *path, GError **err)
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return MU_STORE_INVALID_DOCID;
|
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);
|
mu_msg_unref (msg);
|
||||||
|
|
||||||
return docid;
|
return docid;
|
||||||
|
@ -644,9 +670,7 @@ mu_store_remove_path (MuStore *store, const char *msgpath)
|
||||||
g_return_val_if_fail (msgpath, FALSE);
|
g_return_val_if_fail (msgpath, FALSE);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const std::string uid (store->get_message_uid (msgpath));
|
store->db_writable()->delete_document (store->get_uid_term (msgpath));
|
||||||
|
|
||||||
store->db_writable()->delete_document (uid);
|
|
||||||
store->inc_processed();
|
store->inc_processed();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in New Issue