From efa026648ba504c237082af13fcc03d052b25d93 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sat, 30 Apr 2011 11:31:34 +0300 Subject: [PATCH] * mu-store.cc: some optimizations, and add the possibility to use the slightly faster 'add_document' instead of 'replace_document' (it's not used yet though) --- src/mu-index.c | 2 +- src/mu-store.cc | 42 ++++++++++++++++++++++++++------------- src/mu-store.h | 9 +++++++-- src/tests/test-mu-store.c | 8 ++++---- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/mu-index.c b/src/mu-index.c index ab8013dc..850d7f02 100644 --- a/src/mu-index.c +++ b/src/mu-index.c @@ -149,7 +149,7 @@ insert_or_update_maybe (const char* fullpath, const char* mdir, } /* we got a valid id; scan the message contents as well */ - if (G_UNLIKELY((mu_store_store (data->_store, msg) != MU_OK))) { + if (G_UNLIKELY((mu_store_store (data->_store, msg, TRUE) != MU_OK))) { g_warning ("%s: storing content %s failed", __FUNCTION__, fullpath); return MU_ERROR; diff --git a/src/mu-store.cc b/src/mu-store.cc index e5b0cf29..c0f580fb 100644 --- a/src/mu-store.cc +++ b/src/mu-store.cc @@ -47,7 +47,7 @@ struct _MuStore { _MuStore (const char *xpath, const char *contacts_cache) : _db (xpath, Xapian::DB_CREATE_OR_OPEN), _in_transaction(0), _processed (0), _trx_size(MU_STORE_DEFAULT_TRX_SIZE), _contacts (0), - _version (0){ + _version (0) { if (!check_version (this)) throw std::runtime_error @@ -84,7 +84,7 @@ struct _MuStore { int _processed; size_t _trx_size; guint _batchsize; /* batch size of a xapian transaction */ - + /* contacts object to cache all the contact information */ MuContacts *_contacts; @@ -456,7 +456,6 @@ xapian_pfx (MuMsgContact *contact) } - static void each_contact_info (MuMsgContact *contact, MsgDoc *msgdoc) { @@ -488,25 +487,33 @@ each_contact_info (MuMsgContact *contact, MsgDoc *msgdoc) } } - -/* get a unique id for this message */ -static std::string +/* get a unique id for this message; note, this function returns a + * static buffer -- not reentrant */ +static const char* get_message_uid (const char* path) { - static const std::string pathprefix - (1, mu_msg_field_xapian_prefix(MU_MSG_FIELD_ID_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; + } - return pathprefix + path; + strcpy (buf + 1, path); + return buf; } -static const std::string +/* get a unique id for this message; note, this function returns a + * static buffer -- not reentrant */ +static const char* get_message_uid (MuMsg *msg) { - return get_message_uid (mu_msg_get_path(msg)); + return get_message_uid (mu_msg_get_path(msg)); } MuResult -mu_store_store (MuStore *store, MuMsg *msg) +mu_store_store (MuStore *store, MuMsg *msg, gboolean replace) { g_return_val_if_fail (store, MU_ERROR); g_return_val_if_fail (msg, MU_ERROR); @@ -529,8 +536,15 @@ mu_store_store (MuStore *store, MuMsg *msg) (MuMsgContactForeachFunc)each_contact_info, &msgdoc); - /* we replace all existing documents for this file */ - id = store->_db.replace_document (uid, newdoc); + /* 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.replace_document (uid, newdoc); + else + id = store->_db.add_document (newdoc); + ++store->_processed; commit_trx_if (store, store->_processed % store->_trx_size == 0); diff --git a/src/mu-store.h b/src/mu-store.h index 20f6ca1b..e875f1b8 100644 --- a/src/mu-store.h +++ b/src/mu-store.h @@ -100,11 +100,16 @@ void mu_store_flush (MuStore *store); * store an email message in the XapianStore * * @param store a valid store - * @param msg a valid message + * @param msg a valid message + * @param replace whether or not we should try to replace the same + * message if it already exists; that is usually desirable, but when + * we're sure already that the document does not exist (e.g, in case + * of a initial fill or rebuild of the database), we can set 'replace' + * to FALSE for a couple% performance gain * * @return TRUE if it succeeded, FALSE otherwise */ -MuResult mu_store_store (MuStore *store, MuMsg *msg); +MuResult mu_store_store (MuStore *store, MuMsg *msg, gboolean replace); /** diff --git a/src/tests/test-mu-store.c b/src/tests/test-mu-store.c index 836d8f43..e97b17d1 100644 --- a/src/tests/test-mu-store.c +++ b/src/tests/test-mu-store.c @@ -100,7 +100,7 @@ test_mu_store_store_and_count (void) /* add one */ msg = mu_msg_new (MU_TESTMAILDIR "cur/1283599333.1840_11.cthulhu!2,", NULL, NULL); g_assert (msg); - g_assert_cmpuint (mu_store_store (store, msg), ==, MU_OK); + g_assert_cmpuint (mu_store_store (store, msg, TRUE), ==, MU_OK); g_assert_cmpuint (1,==,mu_store_count (store)); g_assert_cmpuint (TRUE,==,mu_store_contains_message (store, MU_TESTMAILDIR "cur/1283599333.1840_11.cthulhu!2,")); @@ -109,7 +109,7 @@ test_mu_store_store_and_count (void) /* add another one */ msg = mu_msg_new (MU_TESTMAILDIR2 "bar/cur/mail3", NULL, NULL); g_assert (msg); - g_assert_cmpuint (mu_store_store (store, msg), ==, MU_OK); + g_assert_cmpuint (mu_store_store (store, msg, TRUE), ==, MU_OK); g_assert_cmpuint (2,==,mu_store_count (store)); g_assert_cmpuint (TRUE,==,mu_store_contains_message (store, MU_TESTMAILDIR2 "bar/cur/mail3")); mu_msg_unref (msg); @@ -117,7 +117,7 @@ test_mu_store_store_and_count (void) /* try to add the first one again. count should be 2 still */ msg = mu_msg_new (MU_TESTMAILDIR "cur/1283599333.1840_11.cthulhu!2,", NULL, NULL); g_assert (msg); - g_assert_cmpuint (mu_store_store (store, msg), ==, MU_OK); + g_assert_cmpuint (mu_store_store (store, msg, TRUE), ==, MU_OK); g_assert_cmpuint (2,==,mu_store_count (store)); mu_msg_unref (msg); @@ -150,7 +150,7 @@ test_mu_store_store_remove_and_count (void) msg = mu_msg_new (MU_TESTMAILDIR "cur/1283599333.1840_11.cthulhu!2,", NULL, &err); g_assert (msg); - g_assert_cmpuint (mu_store_store (store, msg), ==, MU_OK); + g_assert_cmpuint (mu_store_store (store, msg, TRUE), ==, MU_OK); g_assert_cmpuint (1,==,mu_store_count (store)); mu_msg_unref (msg);