From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 9CE2F429E29 for ; Sat, 11 Jun 2011 13:06:13 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0PqqZ0Jj+QTT for ; Sat, 11 Jun 2011 13:06:12 -0700 (PDT) Received: from dmz-mailsec-scanner-4.mit.edu (DMZ-MAILSEC-SCANNER-4.MIT.EDU [18.9.25.15]) by olra.theworths.org (Postfix) with ESMTP id CC9D2431FB6 for ; Sat, 11 Jun 2011 13:06:12 -0700 (PDT) X-AuditID: 1209190f-b7b0eae000000a42-e4-4df3cab98d52 Received: from mailhub-auth-1.mit.edu ( [18.9.21.35]) by dmz-mailsec-scanner-4.mit.edu (Symantec Messaging Gateway) with SMTP id 87.DC.02626.9BAC3FD4; Sat, 11 Jun 2011 16:06:17 -0400 (EDT) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id p5BK6CiA015024; Sat, 11 Jun 2011 16:06:12 -0400 Received: from drake.mit.edu (209-6-116-242.c3-0.arl-ubr1.sbo-arl.ma.cable.rcn.com [209.6.116.242]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id p5BK6BmA005941 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Sat, 11 Jun 2011 16:06:12 -0400 (EDT) Received: from amthrax by drake.mit.edu with local (Exim 4.76) (envelope-from ) id 1QVURf-0000I8-56; Sat, 11 Jun 2011 16:06:11 -0400 From: Austin Clements To: notmuch@notmuchmail.org Subject: [PATCH 07/17] lib: Add notmuch_database_{begin,end}_atomic. Date: Sat, 11 Jun 2011 16:04:33 -0400 Message-Id: <1307822683-848-8-git-send-email-amdragon@mit.edu> X-Mailer: git-send-email 1.7.5.1 In-Reply-To: <1307822683-848-1-git-send-email-amdragon@mit.edu> References: <87ei34rnc5.fsf@yoom.home.cworth.org> <1307822683-848-1-git-send-email-amdragon@mit.edu> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrHIsWRmVeSWpSXmKPExsUixCmqrLvz1Gdfg/v/pCyu35zJ7MDo8WzV LeYAxigum5TUnMyy1CJ9uwSujL51ZxkLbshUfD78n7GB8aR4FyMnh4SAicT+TdPYIGwxiQv3 1gPZXBxCAvsYJS43TmMGSQgJbGCU+NQpDZG4zyQx6fV/VghnPqPE85V3WEGq2AQ0JLbtX84I YosISEvsvDsbKM7BwSygJvGnSwUkLCzgItFyewNYOYuAqkTr/yawzbwCdhILru1mh7hCQeLK lXksIDangL3EvINXWSCOSJNYcms3+wRG/gWMDKsYZVNyq3RzEzNzilOTdYuTE/PyUot0TfRy M0v0UlNKNzGCg0aSfwfjt4NKhxgFOBiVeHhV1n72FWJNLCuuzD3EKMnBpCTKq3MCKMSXlJ9S mZFYnBFfVJqTWnyIUYKDWUmEd337J18h3pTEyqrUonyYlDQHi5I47yxJdV8hgfTEktTs1NSC 1CKYrAwHh5IE7+aTQEMFi1LTUyvSMnNKENJMHJwgw3mAhh8FqeEtLkjMLc5Mh8ifYtTleLxh 0yFGIZa8/LxUKXHe+yBFAiBFGaV5cHNg0f6KURzoLWHeXSBVPMBEATfpFdASJqAlAqVgS0oS EVJSDYzz58vJZl699lu6h7tF0cVWNVE85cH7m0uYVY4eTc4NODT/ct28sM0uln+mbN11MmZ3 +Optj/7fqjvJkKrUbb4jYs+RBaskHSp3MLrJpyxwjEqy2pfIp9t45Yaqv/LP188WSKpF20fd V/19QWzrf98ZC4JU9FZqTeebc9ekOlPll++ttx98OqcpsRRnJBpqMRcVJwIAffDV+9ECAAA= Cc: Austin Clements X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Jun 2011 20:06:13 -0000 These operations translate into non-flushed Xapian transactions, allowing arbitrary groups of database operations to be performed atomically. --- lib/database.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ lib/notmuch.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 0 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 7f79cf4..ddb6167 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -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 (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 (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. diff --git a/lib/notmuch.h b/lib/notmuch.h index e508309..208d22c 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -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' -- 1.7.5.1