From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id L2bXIXxIHWBPRwAA0tVLHw (envelope-from ) for ; Fri, 05 Feb 2021 13:30:36 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2 with LMTPS id aKQSHXxIHWAmOQAAB5/wlQ (envelope-from ) for ; Fri, 05 Feb 2021 13:30:36 +0000 Received: from mail.notmuchmail.org (nmbug.tethera.net [IPv6:2607:5300:201:3100::1657]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (2048 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 09F9B9403CD for ; Fri, 5 Feb 2021 13:30:36 +0000 (UTC) Received: from nmbug.tethera.net (localhost [127.0.0.1]) by mail.notmuchmail.org (Postfix) with ESMTP id 13E9026870; Fri, 5 Feb 2021 08:28:24 -0500 (EST) Received: from fethera.tethera.net (fethera.tethera.net [IPv6:2607:5300:60:c5::1]) by mail.notmuchmail.org (Postfix) with ESMTP id F220B1FBA9 for ; Fri, 5 Feb 2021 08:27:34 -0500 (EST) Received: by fethera.tethera.net (Postfix, from userid 1001) id EA77E6067F; Fri, 5 Feb 2021 08:27:34 -0500 (EST) Received: (nullmailer pid 3258375 invoked by uid 1000); Fri, 05 Feb 2021 13:27:02 -0000 From: David Bremner To: notmuch@notmuchmail.org Cc: David Bremner Subject: [PATCH 02/39] lib: cache configuration information from database Date: Fri, 5 Feb 2021 09:26:17 -0400 Message-Id: <20210205132654.3258292-3-david@tethera.net> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210205132654.3258292-1-david@tethera.net> References: <20210205132654.3258292-1-david@tethera.net> MIME-Version: 1.0 Message-ID-Hash: HJMKH6EWFZ65W2UWTMYVY6HAQHVSNFXG X-Message-ID-Hash: HJMKH6EWFZ65W2UWTMYVY6HAQHVSNFXG X-MailFrom: bremner@tethera.net X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-notmuch.notmuchmail.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.1 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_IN X-Migadu-Spam-Score: -0.83 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 2607:5300:201:3100::1657 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Migadu-Queue-Id: 09F9B9403CD X-Spam-Score: -0.83 X-Migadu-Scanner: scn0.migadu.com X-TUID: eAAanDDyeqlG The main goal is to allow configuration information to be temporarily overridden by a separate config file. That will require further changes not in this commit. The performance impact is unclear, and will depend on the balance between number of queries and number of distinct metadata items read on the first call to n_d_get_config. --- lib/config.cc | 58 ++++++++++++++++++++++++++++++++++----- lib/database-private.h | 3 ++ lib/notmuch-private.h | 3 ++ lib/open.cc | 7 ++++- lib/prefix.cc | 18 ++++++------ test/T562-lib-database.sh | 7 ++--- 6 files changed, 75 insertions(+), 21 deletions(-) diff --git a/lib/config.cc b/lib/config.cc index 0b760dbc..c079d752 100644 --- a/lib/config.cc +++ b/lib/config.cc @@ -50,6 +50,11 @@ notmuch_database_set_config (notmuch_database_t *notmuch, if (status) return status; + if (! notmuch->config) { + if ((status = _notmuch_config_load_from_database (notmuch))) + return status; + } + try { notmuch->writable_xapian_db->set_metadata (CONFIG_PREFIX + key, value); } catch (const Xapian::Error &error) { @@ -58,7 +63,13 @@ notmuch_database_set_config (notmuch_database_t *notmuch, _notmuch_database_log (notmuch, "Error: A Xapian exception occurred setting metadata: %s\n", error.get_msg ().c_str ()); } - return status; + + if (status) + return status; + + _notmuch_string_map_set (notmuch->config, key, value); + + return NOTMUCH_STATUS_SUCCESS; } static notmuch_status_t @@ -84,17 +95,25 @@ notmuch_database_get_config (notmuch_database_t *notmuch, const char *key, char **value) { - std::string strval; + const char* stored_val; notmuch_status_t status; + if (! notmuch->config) { + if ((status = _notmuch_config_load_from_database (notmuch))) + return status; + } + if (! value) return NOTMUCH_STATUS_NULL_POINTER; - status = _metadata_value (notmuch, key, strval); - if (status) - return status; - - *value = strdup (strval.c_str ()); + stored_val = _notmuch_string_map_get (notmuch->config, key); + if (! stored_val) { + /* XXX in principle this API should be fixed so empty string + * is distinguished from not found */ + *value = strdup(""); + } else { + *value = strdup (stored_val); + } return NOTMUCH_STATUS_SUCCESS; } @@ -201,3 +220,28 @@ notmuch_config_list_destroy (notmuch_config_list_t *list) { talloc_free (list); } + +notmuch_status_t +_notmuch_config_load_from_database (notmuch_database_t *notmuch) +{ + notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; + notmuch_config_list_t *list; + + if (notmuch->config == NULL) + notmuch->config = _notmuch_string_map_create (notmuch); + + if (unlikely(notmuch->config == NULL)) + return NOTMUCH_STATUS_OUT_OF_MEMORY; + + status = notmuch_database_get_config_list (notmuch, "", &list); + if (status) + return status; + + for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) { + _notmuch_string_map_append (notmuch->config, + notmuch_config_list_key (list), + notmuch_config_list_value (list)); + } + + return status; +} diff --git a/lib/database-private.h b/lib/database-private.h index c9bc712b..d83cf0d0 100644 --- a/lib/database-private.h +++ b/lib/database-private.h @@ -228,6 +228,9 @@ struct _notmuch_database { * here, but at least they are small */ notmuch_string_map_t *user_prefix; notmuch_string_map_t *user_header; + + /* Cached and possibly overridden configuration */ + notmuch_string_map_t *config; }; /* Prior to database version 3, features were implied by the database diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 51016b0b..969caac0 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -704,6 +704,9 @@ struct _notmuch_indexopts { #define EMPTY_STRING(s) ((s)[0] == '\0') +/* config.cc */ +notmuch_status_t +_notmuch_config_load_from_database (notmuch_database_t * db); NOTMUCH_END_DECLS #ifdef __cplusplus diff --git a/lib/open.cc b/lib/open.cc index 1b17e63a..0001794a 100644 --- a/lib/open.cc +++ b/lib/open.cc @@ -90,7 +90,7 @@ notmuch_database_open_verbose (const char *path, notmuch->exception_reported = false; notmuch->status_string = NULL; notmuch->path = talloc_strdup (notmuch, path); - + notmuch->config = NULL; strip_trailing (notmuch->path, '/'); notmuch->writable_xapian_db = NULL; @@ -180,6 +180,11 @@ notmuch_database_open_verbose (const char *path, notmuch->query_parser->add_rangeprocessor (notmuch->date_range_processor); notmuch->query_parser->add_rangeprocessor (notmuch->last_mod_range_processor); + /* Configuration information is needed to set up query parser */ + status = _notmuch_config_load_from_database (notmuch); + if (status) + goto DONE; + status = _notmuch_database_setup_standard_query_fields (notmuch); if (status) goto DONE; diff --git a/lib/prefix.cc b/lib/prefix.cc index dd7b193d..71a76991 100644 --- a/lib/prefix.cc +++ b/lib/prefix.cc @@ -166,8 +166,7 @@ _notmuch_database_setup_standard_query_fields (notmuch_database_t *notmuch) notmuch_status_t _notmuch_database_setup_user_query_fields (notmuch_database_t *notmuch) { - notmuch_config_list_t *list; - notmuch_status_t status; + notmuch_string_map_iterator_t *list; notmuch->user_prefix = _notmuch_string_map_create (notmuch); if (notmuch->user_prefix == NULL) @@ -177,15 +176,16 @@ _notmuch_database_setup_user_query_fields (notmuch_database_t *notmuch) if (notmuch->user_header == NULL) return NOTMUCH_STATUS_OUT_OF_MEMORY; - status = notmuch_database_get_config_list (notmuch, CONFIG_HEADER_PREFIX, &list); - if (status) - return status; + list = _notmuch_string_map_iterator_create (notmuch->config, CONFIG_HEADER_PREFIX, FALSE); + if (! list) + INTERNAL_ERROR ("unable to read headers from configuration"); - for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) { + for (; _notmuch_string_map_iterator_valid (list); + _notmuch_string_map_iterator_move_to_next (list)) { prefix_t query_field; - const char *key = notmuch_config_list_key (list) + const char *key = _notmuch_string_map_iterator_key (list) + sizeof (CONFIG_HEADER_PREFIX) - 1; _notmuch_string_map_append (notmuch->user_prefix, @@ -194,7 +194,7 @@ _notmuch_database_setup_user_query_fields (notmuch_database_t *notmuch) _notmuch_string_map_append (notmuch->user_header, key, - notmuch_config_list_value (list)); + _notmuch_string_map_iterator_value (list)); query_field.name = talloc_strdup (notmuch, key); query_field.prefix = _user_prefix (notmuch, key); @@ -204,7 +204,7 @@ _notmuch_database_setup_user_query_fields (notmuch_database_t *notmuch) _setup_query_field_default (&query_field, notmuch); } - notmuch_config_list_destroy (list); + _notmuch_string_map_iterator_destroy (list); return NOTMUCH_STATUS_SUCCESS; } diff --git a/test/T562-lib-database.sh b/test/T562-lib-database.sh index dd4f2566..887851dd 100755 --- a/test/T562-lib-database.sh +++ b/test/T562-lib-database.sh @@ -340,7 +340,7 @@ test_expect_equal_file EXPECTED OUTPUT test_begin_subtest "get config from closed database" cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} { - const char *result; + char *result; EXPECT0(notmuch_database_close (db)); stat = notmuch_database_get_config (db, "foo", &result); printf("%d\n", stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION); @@ -348,9 +348,8 @@ cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} EOF cat < EXPECTED == stdout == -1 +0 == stderr == -Error: A Xapian exception occurred getting metadata: Database has been closed EOF test_expect_equal_file EXPECTED OUTPUT @@ -376,7 +375,7 @@ cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} notmuch_indexopts_t *result; EXPECT0(notmuch_database_close (db)); result = notmuch_database_get_default_indexopts (db); - printf("%d\n", result == NULL); + printf("%d\n", result != NULL); } EOF cat < EXPECTED -- 2.30.0