From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 1DD9E1388C1 for ; Sat, 28 Nov 2015 02:44:49 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 613E421C014; Sat, 28 Nov 2015 02:44:42 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 58BA721C077 for ; Sat, 28 Nov 2015 02:44:40 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 3DB80340739 for ; Sat, 28 Nov 2015 02:44:39 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 574D1FD6 for ; Sat, 28 Nov 2015 02:44:35 +0000 (UTC) From: "Mike Frysinger" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Frysinger" Message-ID: <1448664350.89d451252b18c0ae2f768f6248964638f8aadd9f.vapier@gentoo> Subject: [gentoo-commits] proj/portage-utils:master commit in: /, libq/ X-VCS-Repository: proj/portage-utils X-VCS-Files: libq/virtuals.c qcache.c X-VCS-Directories: libq/ / X-VCS-Committer: vapier X-VCS-Committer-Name: Mike Frysinger X-VCS-Revision: 89d451252b18c0ae2f768f6248964638f8aadd9f X-VCS-Branch: master Date: Sat, 28 Nov 2015 02:44:35 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 77c0b33c-68f3-457d-bee4-318a81d0f40f X-Archives-Hash: ba32039a3a54485cfbee3d0a90b2321e commit: 89d451252b18c0ae2f768f6248964638f8aadd9f Author: Mike Frysinger gentoo org> AuthorDate: Fri Nov 27 22:45:50 2015 +0000 Commit: Mike Frysinger gentoo org> CommitDate: Fri Nov 27 22:45:50 2015 +0000 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=89d45125 qcache: add multiple overlay support We have to rework two things: - turn the arch array into a set; the implementation is not optimal - pass in the current overlay to the callback func so it can keep track of when we switch between them With that in place, walking all the overlays is pretty quick. URL: https://bugs.gentoo.org/553260 libq/virtuals.c | 16 +++++++ qcache.c | 131 +++++++++++++++++++++++++++++++++----------------------- 2 files changed, 94 insertions(+), 53 deletions(-) diff --git a/libq/virtuals.c b/libq/virtuals.c index 536c622..1818281 100644 --- a/libq/virtuals.c +++ b/libq/virtuals.c @@ -46,6 +46,22 @@ add_set(const char *name, queue *q) return append_set(q, ll); } +/* Performance here is terrible. Should use a hash at some point. */ +_q_static queue * +add_set_unique(const char *name, queue *q, bool *ok) +{ + queue *ll = q; + while (ll) { + if (!strcmp(ll->name, name)) { + *ok = false; + return q; + } + ll = ll->next; + } + *ok = true; + return add_set(name, q); +} + /* remove a set from a cache. matches ->name and frees name,item */ _q_static queue * del_set(char *s, queue *q, int *ok) diff --git a/qcache.c b/qcache.c index 5cac394..d4b7884 100644 --- a/qcache.c +++ b/qcache.c @@ -51,9 +51,10 @@ static const char * const qcache_opts_help[] = { /********************************************************************/ typedef struct { - char *category; - char *package; - char *ebuild; + const char *overlay; + const char *category; + const char *package; + const char *ebuild; portage_cache *cache_data; unsigned char cur; unsigned char num; @@ -63,7 +64,7 @@ typedef struct { /* Global Variables */ /********************************************************************/ -static char **archlist; /* Read from PORTDIR/profiles/arch.list in qcache_init() */ +static queue *arches; static int archlist_count; static size_t arch_longest_len; const char status[3] = {'-', '~', '+'}; @@ -113,6 +114,7 @@ int decode_status(char c) _q_static int decode_arch(const char *arch) { + queue *q = arches; int a; const char *p; @@ -120,9 +122,13 @@ int decode_arch(const char *arch) if (*p == '~' || *p == '-') p++; - for (a = 0; a < archlist_count; ++a) - if (strcmp(archlist[a], p) == 0) + a = 0; + while (q) { + if (strcmp(q->name, p) == 0) return a; + ++a; + q = q->next; + } return -1; } @@ -139,6 +145,7 @@ int decode_arch(const char *arch) _q_static void print_keywords(const char *category, const char *ebuild, int *keywords) { + queue *arch = arches; int a; char *package; @@ -149,14 +156,13 @@ void print_keywords(const char *category, const char *ebuild, int *keywords) for (a = 0; a < archlist_count; ++a) { switch (keywords[a]) { case stable: - printf("%s%c%s%s ", GREEN, status[keywords[a]], archlist[a], NORM); + printf("%s%c%s%s ", GREEN, status[keywords[a]], arch->name, NORM); break; case testing: - printf("%s%c%s%s ", YELLOW, status[keywords[a]], archlist[a], NORM); - break; - default: + printf("%s%c%s%s ", YELLOW, status[keywords[a]], arch->name, NORM); break; } + arch = arch->next; } printf("\n"); @@ -386,6 +392,8 @@ int qcache_ebuild_select(const struct dirent *entry) /* Traversal function */ /********************************************************************/ +_q_static void qcache_load_arches(const char *overlay); + /* * int qcache_traverse(void (*func)(qcache_data*)); * @@ -399,14 +407,16 @@ int qcache_ebuild_select(const struct dirent *entry) * exit or return -1 on failure. */ _q_static -int qcache_traverse(void (*func)(qcache_data*)) +int qcache_traverse_overlay(void (*func)(qcache_data*), const char *overlay) { - qcache_data data; + qcache_data data = { + .overlay = overlay, + }; char *catpath, *pkgpath, *ebuildpath, *cachepath; int i, j, k, len, num_cat, num_pkg, num_ebuild; struct dirent **categories, **packages, **ebuilds; - xasprintf(&catpath, "%s/dep/%s", portedb, portdir); + xasprintf(&catpath, "%s/dep/%s", portedb, overlay); if (-1 == (num_cat = scandir(catpath, &categories, qcache_file_select, alphasort))) { errp("%s", catpath); @@ -418,7 +428,7 @@ int qcache_traverse(void (*func)(qcache_data*)) /* traverse categories */ for (i = 0; i < num_cat; i++) { - xasprintf(&pkgpath, "%s/%s", portdir, categories[i]->d_name); + xasprintf(&pkgpath, "%s/%s", overlay, categories[i]->d_name); if (-1 == (num_pkg = scandir(pkgpath, &packages, qcache_file_select, alphasort))) { if (errno != ENOENT) @@ -439,7 +449,7 @@ int qcache_traverse(void (*func)(qcache_data*)) /* traverse packages */ for (j = 0; j < num_pkg; j++) { - xasprintf(&ebuildpath, "%s/%s/%s", portdir, categories[i]->d_name, packages[j]->d_name); + xasprintf(&ebuildpath, "%s/%s/%s", overlay, categories[i]->d_name, packages[j]->d_name); if (-1 == (num_ebuild = scandir(ebuildpath, &ebuilds, qcache_ebuild_select, qcache_vercmp))) { /* Do not complain about spurious files */ @@ -504,9 +514,28 @@ int qcache_traverse(void (*func)(qcache_data*)) free(categories); free(catpath); + return 0; +} + +_q_static +int qcache_traverse(void (*func)(qcache_data*)) +{ + int ret; + size_t n; + const char *overlay; + + /* Preload all the arches. Not entirely correctly (as arches are bound + * to overlays if set), but oh well. */ + array_for_each(overlays, n, overlay) + qcache_load_arches(overlay); + + ret = 0; + array_for_each(overlays, n, overlay) + ret |= qcache_traverse_overlay(func, overlay); + func(NULL); - return 0; + return ret; } /********************************************************************/ @@ -653,6 +682,8 @@ _q_static void qcache_stats(qcache_data *data) { static time_t runtime; + static queue *allcats; + static const char *last_overlay; static int numpkg = 0; static int numebld = 0; static int numcat; @@ -686,12 +717,14 @@ void qcache_stats(qcache_data *data) (int)arch_longest_len, "", RED, "only", NORM); printf("+%.*s+\n", (int)(arch_longest_len + 46), border); + queue *arch = arches; for (a = 0; a < archlist_count; ++a) { - printf("| %s%*s%s |", GREEN, (int)arch_longest_len, archlist[a], NORM); + printf("| %s%*s%s |", GREEN, (int)arch_longest_len, arch->name, NORM); printf("%s%8d%s |", BLUE, packages_stable[a], NORM); printf("%s%8d%s |", BLUE, packages_testing[a], NORM); printf("%s%8d%s |", BLUE, packages_testing[a]+packages_stable[a], NORM); printf("%s%11.2f%s%% |\n", BLUE, (100.0*(packages_testing[a]+packages_stable[a]))/numpkg, NORM); + arch = arch->next; } printf("+%.*s+\n\n", (int)(arch_longest_len + 46), border); @@ -704,23 +737,33 @@ void qcache_stats(qcache_data *data) free(packages_testing); free(keywords); free(current_package_keywords); + free_sets(allcats); return; } - if (!numpkg) { - struct dirent **categories; + if (last_overlay != data->overlay) { + DIR *dir; + struct dirent *de; char *catpath; - xasprintf(&catpath, "%s/dep/%s", portedb, portdir); + runtime = time(NULL); - if (-1 == (numcat = scandir(catpath, &categories, qcache_file_select, alphasort))) { - errp("%s", catpath); - free(catpath); - } - scandir_free(categories, numcat); + xasprintf(&catpath, "%s/dep/%s", portedb, data->overlay); + dir = opendir(catpath); + while ((de = readdir(dir))) + if (de->d_type == DT_DIR && de->d_name[0] != '.') { + bool ok; + allcats = add_set_unique(de->d_name, allcats, &ok); + if (ok) + ++numcat; + } + closedir(dir); + free(catpath); - runtime = time(NULL); + last_overlay = data->overlay; + } + if (!numpkg) { packages_stable = xcalloc(archlist_count, sizeof(*packages_stable)); packages_testing = xcalloc(archlist_count, sizeof(*packages_testing)); keywords = xcalloc(archlist_count, sizeof(*keywords)); @@ -812,26 +855,15 @@ void qcache_testing_only(qcache_data *data) /* Misc functions */ /********************************************************************/ -/* - * int qcache_init(); - * - * Initialize variables (archlist, num_arches) - * - * OUT: - * 0 is return on success. - * ERR: - * -1 is returned on error. - */ _q_static -bool qcache_init(void) +void qcache_load_arches(const char *overlay) { - bool ret = false; FILE *fp; char *filename, *s; size_t buflen, linelen; char *buf; - xasprintf(&filename, "%s/profiles/arch.list", portdir); + xasprintf(&filename, "%s/profiles/arch.list", overlay); fp = fopen(filename, "re"); if (!fp) goto done; @@ -847,18 +879,18 @@ bool qcache_init(void) if (buf[0] == '\0') continue; - ++archlist_count; - archlist = xrealloc_array(archlist, sizeof(*archlist), archlist_count); - archlist[archlist_count - 1] = xstrdup(buf); - arch_longest_len = MAX(arch_longest_len, strlen(buf)); + bool ok; + arches = add_set_unique(buf, arches, &ok); + if (ok) { + ++archlist_count; + arch_longest_len = MAX(arch_longest_len, strlen(buf)); + } } free(buf); - ret = true; fclose(fp); done: free(filename); - return ret; } /* @@ -869,11 +901,7 @@ bool qcache_init(void) _q_static void qcache_free(void) { - size_t a; - - for (a = 0; a < archlist_count; ++a) - free(archlist[a]); - free(archlist); + free_sets(arches); } /********************************************************************/ @@ -906,9 +934,6 @@ int qcache_main(int argc, char **argv) } } - if (!qcache_init()) - err("Could not initialize arch list"); - if (optind < argc) qcache_test_arch = decode_arch(argv[optind]);