lib: Add notmuch_database_{begin,end}_atomic.

These operations translate into non-flushed Xapian transactions,
allowing arbitrary groups of database operations to be performed
atomically.
This commit is contained in:
Austin Clements 2011-01-29 11:25:24 -05:00 committed by David Bremner
parent fcd433709e
commit 957f1ba3fc
2 changed files with 74 additions and 0 deletions

View file

@ -974,6 +974,50 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
return NOTMUCH_STATUS_SUCCESS;
}
notmuch_status_t
notmuch_database_begin_atomic (notmuch_database_t *notmuch)
{
if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
return NOTMUCH_STATUS_SUCCESS;
try {
(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->begin_transaction (false);
} catch (const Xapian::Error &error) {
fprintf (stderr, "A Xapian exception occurred beginning transaction: %s.\n",
error.get_msg().c_str());
notmuch->exception_reported = TRUE;
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
return NOTMUCH_STATUS_SUCCESS;
}
notmuch_status_t
notmuch_database_end_atomic (notmuch_database_t *notmuch)
{
Xapian::WritableDatabase *db;
if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
return NOTMUCH_STATUS_SUCCESS;
db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
try {
db->commit_transaction ();
/* This is a hack for testing. Xapian never flushes on a
* non-flushed commit, even if the flush threshold is 1.
* However, we rely on flushing to test atomicity. */
const char *thresh = getenv ("XAPIAN_FLUSH_THRESHOLD");
if (thresh && atoi (thresh) == 1)
db->commit ();
} catch (const Xapian::Error &error) {
fprintf (stderr, "A Xapian exception occurred committing transaction: %s.\n",
error.get_msg().c_str());
notmuch->exception_reported = TRUE;
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
return NOTMUCH_STATUS_SUCCESS;
}
/* We allow the user to use arbitrarily long paths for directories. But
* we have a term-length limit. So if we exceed that, we'll use the
* SHA-1 of the path for the database term.

View file

@ -214,6 +214,36 @@ notmuch_database_upgrade (notmuch_database_t *database,
double progress),
void *closure);
/* Begin an atomic database operation.
*
* Any modifications performed between a successful begin and a
* notmuch_database_end_atomic will be applied to the database
* atomically. Note that, unlike a typical database transaction, this
* only ensures atomicity, not durability; neither begin nor end
* necessarily flush modifications to disk.
*
* Return value:
*
* NOTMUCH_STATUS_SUCCESS: Successfully entered atomic section.
*
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred;
* atomic section not entered.
*/
notmuch_status_t
notmuch_database_begin_atomic (notmuch_database_t *notmuch);
/* Indicate the end of an atomic database operation.
*
* Return value:
*
* NOTMUCH_STATUS_SUCCESS: Successfully completed atomic section.
*
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred;
* atomic section not ended.
*/
notmuch_status_t
notmuch_database_end_atomic (notmuch_database_t *notmuch);
/* Retrieve a directory object from the database for 'path'.
*
* Here, 'path' should be a path relative to the path of 'database'