From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from localhost (fantadrom.bsd.lv [local]); by fantadrom.bsd.lv (OpenSMTPD) with ESMTPA id 2ad5b117; for ; Tue, 20 Jan 2015 13:21:48 -0500 (EST) Date: Tue, 20 Jan 2015 13:21:48 -0500 (EST) Message-Id: <1131798396323019379.enqueue@fantadrom.bsd.lv> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: schwarze@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: Make the man(1) and apropos(1) options -s and -S much less X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- Make the man(1) and apropos(1) options -s and -S much less expensive: Do not append an SQL clause looking into the large "keys" table. Instead, filter the result of the SQL query in buildnames() where equivalent data from the much smaller "mlinks" table is already available for free. This is relevant because man(1) uses the equivalent of "-S ${MACHINE}" by default since main.c rev. 1.216, to make sure that manuals for the current architecture are shown. With many ports installed, this patch can speed up man(1) by a factor of more than a hundred. Slowness reported by Theo Buehler , thanks! Modified Files: -------------- mdocml: mansearch.c Revision Data ------------- Index: mansearch.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/mansearch.c,v retrieving revision 1.52 retrieving revision 1.53 diff -Lmansearch.c -Lmansearch.c -u -p -r1.52 -r1.53 --- mansearch.c +++ mansearch.c @@ -1,7 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2012 Kristaps Dzonsons - * Copyright (c) 2013, 2014 Ingo Schwarze + * Copyright (c) 2013, 2014, 2015 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -85,7 +85,8 @@ struct match { int form; /* bit field: formatted, zipped? */ }; -static void buildnames(struct manpage *, sqlite3 *, +static void buildnames(const struct mansearch *, + struct manpage *, sqlite3 *, sqlite3_stmt *, uint64_t, const char *, int form); static char *buildoutput(sqlite3 *, sqlite3_stmt *, @@ -96,8 +97,6 @@ static void *hash_calloc(size_t, size_t static struct expr *exprcomp(const struct mansearch *, int, char *[]); static void exprfree(struct expr *); -static struct expr *exprspec(struct expr *, uint64_t, - const char *, const char *); static struct expr *exprterm(const struct mansearch *, char *, int); static int manpage_compare(const void *, const void *); static void sql_append(char **sql, size_t *sz, @@ -343,14 +342,16 @@ mansearch(const struct mansearch *search mpage->bits = mp->bits; mpage->sec = 10; mpage->form = mp->form; - buildnames(mpage, db, s, mp->pageid, + buildnames(search, mpage, db, s, mp->pageid, paths->paths[i], mp->form); - mpage->output = TYPE_Nd & outbit ? - mp->desc : outbit ? - buildoutput(db, s2, mp->pageid, outbit) : NULL; - + if (mpage->names != NULL) { + mpage->output = TYPE_Nd & outbit ? + mp->desc : outbit ? + buildoutput(db, s2, mp->pageid, outbit) : + NULL; + cur++; + } free(mp); - cur++; } sqlite3_finalize(s); @@ -407,7 +408,8 @@ manpage_compare(const void *vp1, const v } static void -buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s, +buildnames(const struct mansearch *search, struct manpage *mpage, + sqlite3 *db, sqlite3_stmt *s, uint64_t pageid, const char *path, int form) { char *newnames, *prevsec, *prevarch; @@ -432,10 +434,15 @@ buildnames(struct manpage *mpage, sqlite sep1 = ", "; } - /* Fetch the next name. */ + /* Fetch the next name, rejecting sec/arch mismatches. */ sec = (const char *)sqlite3_column_text(s, 0); + if (search->sec != NULL && strcasecmp(sec, search->sec)) + continue; arch = (const char *)sqlite3_column_text(s, 1); + if (search->arch != NULL && *arch != '\0' && + strcasecmp(arch, search->arch)) + continue; name = (const char *)sqlite3_column_text(s, 2); /* Remember the first section found. */ @@ -645,8 +652,7 @@ exprcomp(const struct mansearch *search, struct expr *first, *prev, *cur, *next; first = cur = NULL; - logic = igncase = toclose = 0; - toopen = NULL != search->sec || NULL != search->arch; + logic = igncase = toopen = toclose = 0; for (i = 0; i < argc; i++) { if (0 == strcmp("(", argv[i])) { @@ -712,45 +718,13 @@ exprcomp(const struct mansearch *search, toopen = logic = igncase = 0; } - if (toopen || logic || igncase || toclose) - goto fail; - - if (NULL != search->sec || NULL != search->arch) - cur->close++; - if (NULL != search->arch) - cur = exprspec(cur, TYPE_arch, search->arch, "^(%s|any)$"); - if (NULL != search->sec) - exprspec(cur, TYPE_sec, search->sec, "^%s$"); - - return(first); + if ( ! (toopen || logic || igncase || toclose)) + return(first); fail: if (NULL != first) exprfree(first); return(NULL); -} - -static struct expr * -exprspec(struct expr *cur, uint64_t key, const char *value, - const char *format) -{ - char errbuf[BUFSIZ]; - char *cp; - int irc; - - mandoc_asprintf(&cp, format, value); - cur->next = mandoc_calloc(1, sizeof(struct expr)); - cur = cur->next; - cur->and = 1; - cur->bits = key; - if (0 != (irc = regcomp(&cur->regexp, cp, - REG_EXTENDED | REG_NOSUB | REG_ICASE))) { - regerror(irc, &cur->regexp, errbuf, sizeof(errbuf)); - fprintf(stderr, "regcomp: %s\n", errbuf); - cur->substr = value; - } - free(cp); - return(cur); } static struct expr * -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv