dovecot-2.2: lib-fts: normalizer-icu now delays initialization o...

dovecot at dovecot.org dovecot at dovecot.org
Sat May 9 08:32:19 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/3ae8ae7f1022
changeset: 18553:3ae8ae7f1022
user:      Teemu Huovila <teemu.huovila at dovecot.fi>
date:      Sat May 09 11:09:37 2015 +0300
description:
lib-fts: normalizer-icu now delays initialization of libicu.
This way the normalizer can be quickly created even if it's never even used.

diffstat:

 src/lib-fts/fts-filter-normalizer-icu.c |  40 ++++++++++++++++++++------------
 src/lib-fts/test-fts-filter.c           |   7 +++--
 2 files changed, 29 insertions(+), 18 deletions(-)

diffs (111 lines):

diff -r 95a827d97e5b -r 3ae8ae7f1022 src/lib-fts/fts-filter-normalizer-icu.c
--- a/src/lib-fts/fts-filter-normalizer-icu.c	Sat May 09 11:06:45 2015 +0300
+++ b/src/lib-fts/fts-filter-normalizer-icu.c	Sat May 09 11:09:37 2015 +0300
@@ -18,6 +18,7 @@
 	struct fts_filter filter;
 	const char *error;
 	pool_t pool;
+	const char *transliterator_id;
 	UTransliterator *transliterator;
 };
 
@@ -170,15 +171,9 @@
 {
 	struct fts_filter_normalizer *np;
 	pool_t pp;
-	UErrorCode err = U_ZERO_ERROR;
-	UParseError perr;
-	UChar *id_uchar = NULL;
-	int32_t id_len_uchar = 0;
 	unsigned int i;
 	const char *id = "Any-Lower; NFKD; [: Nonspacing Mark :] Remove; NFC";
 
-	memset(&perr, 0, sizeof(perr));
-
 	for (i = 0; settings[i] != NULL; i += 2) {
 		const char *key = settings[i], *value = settings[i+1];
 
@@ -195,22 +190,36 @@
 	np = p_new(pp, struct fts_filter_normalizer, 1);
 	np->pool = pp;
 	np->filter =  *fts_filter_normalizer_icu;
-	if (make_uchar(id, &id_uchar, &id_len_uchar) < 0) {
+	np->transliterator_id = p_strdup(pp, id);
+	*filter_r = &np->filter;
+	return 0;
+}
 
+static int fts_filter_normalizer_icu_create_trans(struct fts_filter_normalizer *np)
+{
+	UErrorCode err = U_ZERO_ERROR;
+	UParseError perr;
+	UChar *id_uchar = NULL;
+	int32_t id_len_uchar = 0;
+
+	memset(&perr, 0, sizeof(perr));
+
+	if (make_uchar(np->transliterator_id, &id_uchar, &id_len_uchar) < 0) {
+		return -1;
 	}
 	np->transliterator = utrans_openU(id_uchar, u_strlen(id_uchar), UTRANS_FORWARD,
 	                                  NULL, 0, &perr, &err);
 	if (U_FAILURE(err)) {
 		if (perr.line >= 1) {
-			fts_filter_normalizer_icu_error(error_r, "Failed to open transliterator for id: %s. Lib ICU error: %s. Parse error on line %u offset %u.", id, u_errorName(err), perr.line, perr.offset);
+			fts_filter_normalizer_icu_error(&np->error, "Failed to open transliterator for id: %s. Lib ICU error: %s. Parse error on line %u offset %u.",
+			                                np->transliterator_id, u_errorName(err), perr.line, perr.offset);
 		}
 		else {
-			fts_filter_normalizer_icu_error(error_r, "Failed to open transliterator for id: %s. Lib ICU error: %s.", id, u_errorName(err));
+			fts_filter_normalizer_icu_error(&np->error, "Failed to open transliterator for id: %s. Lib ICU error: %s.",
+			                                np->transliterator_id, u_errorName(err));
 		}
-		fts_filter_normalizer_icu_destroy(&np->filter);
 		return -1;
 	}
-	*filter_r = &np->filter;
 	return 0;
 }
 
@@ -229,14 +238,15 @@
 	if (np->error != NULL)
 		goto err_exit;
 
+	if (np->transliterator == NULL)
+		if (fts_filter_normalizer_icu_create_trans(np) < 0)
+			goto err_exit;
+
 	if (make_uchar(*token, &utext, &utext_cap) < 0) {
 		fts_filter_normalizer_icu_error(&np->error, "Conversion to UChar failed");
 		goto err_exit;
 	}
-	/*
-	   TODO: Some problems here.  How much longer can the result
-	   be, than the source? Can it be calculated?  Preflighted?
-	*/
+
 	utext_limit = u_strlen(utext);
 	utrans_transUChars(np->transliterator, utext, &utext_len,
 	                   utext_cap, 0, &utext_limit, &err);
diff -r 95a827d97e5b -r 3ae8ae7f1022 src/lib-fts/test-fts-filter.c
--- a/src/lib-fts/test-fts-filter.c	Sat May 09 11:06:45 2015 +0300
+++ b/src/lib-fts/test-fts-filter.c	Sat May 09 11:09:37 2015 +0300
@@ -459,14 +459,15 @@
 	const char *settings[] =
 		{"id", "Any-One-Out-There; DKFN; [: Nonspacing Mark :] Remove",
 		 NULL};
-	const char *error = NULL;
+	const char *error = NULL, *token = "foo";
 	int ret;
 
 	test_begin("fts filter normalizer invalid id");
 	filter_class = fts_filter_find(ICU_NORMALIZER_FILTER_NAME);
 	ret = fts_filter_create(filter_class, NULL, NULL, settings, &norm, &error);
-	test_assert(ret < 0 && error != NULL);
-	test_assert(norm == NULL);
+	test_assert(ret ==  0 && error == NULL);
+	ret = fts_filter_filter(norm, &token);
+	test_assert(ret <  0);
 	test_end();
 }
 


More information about the dovecot-cvs mailing list