Gentoo Archives: gentoo-commits

From: Fabian Groffen <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage-utils:master commit in: libq/
Date: Fri, 10 May 2019 15:33:05
Message-Id: 1557501805.f855d0f4f7c3e6e570a1ad3dc98d737e78996e4a.grobian@gentoo
1 commit: f855d0f4f7c3e6e570a1ad3dc98d737e78996e4a
2 Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
3 AuthorDate: Fri May 10 15:23:25 2019 +0000
4 Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
5 CommitDate: Fri May 10 15:23:25 2019 +0000
6 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=f855d0f4
7
8 libq/tree: make pkg sorting based on atom_compare
9
10 Using alphasort on pkgs makes little sense because they include version
11 information that needs careful extraction and matching rules as
12 implemented by atom_compare.
13
14 In order to use atom_compare efficiently, that is, reusing the
15 atom_explode work done for the elements while running qsort, use
16 tree_get_atom, which caches the retrieved atom. Extra bonus is that any
17 function that retrieves the atom afterwards gets it for free. This
18 speeds up significantly apps that need to construct atoms, such as
19 qkeywords.
20
21 Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
22
23 libq/tree.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++--------------
24 libq/tree.h | 2 +-
25 2 files changed, 51 insertions(+), 16 deletions(-)
26
27 diff --git a/libq/tree.c b/libq/tree.c
28 index c8b4b5e..86dd18f 100644
29 --- a/libq/tree.c
30 +++ b/libq/tree.c
31 @@ -25,6 +25,8 @@
32 #include <ctype.h>
33 #include <xalloc.h>
34
35 +static int tree_pkg_compar(const void *l, const void *r);
36 +
37 static tree_ctx *
38 tree_open_int(const char *sroot, const char *tdir, bool quiet)
39 {
40 @@ -56,7 +58,7 @@ tree_open_int(const char *sroot, const char *tdir, bool quiet)
41 ctx->do_sort = false;
42 ctx->cat_de = NULL;
43 ctx->catsortfunc = alphasort;
44 - ctx->pkgsortfunc = alphasort;
45 + ctx->pkgsortfunc = tree_pkg_compar;
46 ctx->repo = NULL;
47 ctx->ebuilddir_ctx = NULL;
48 ctx->ebuilddir_pkg_ctx = NULL;
49 @@ -208,7 +210,7 @@ tree_open_cat(tree_ctx *ctx, const char *name)
50 cat_ctx->fd = fd;
51 cat_ctx->dir = dir;
52 cat_ctx->ctx = ctx;
53 - cat_ctx->pkg_de = NULL;
54 + cat_ctx->pkg_ctxs = NULL;
55 return cat_ctx;
56 }
57
58 @@ -260,7 +262,7 @@ tree_close_cat(tree_cat_ctx *cat_ctx)
59 /* closedir() above does this for us: */
60 /* close(ctx->fd); */
61 if (cat_ctx->ctx->do_sort)
62 - scandir_free(cat_ctx->pkg_de, cat_ctx->pkg_cnt);
63 + free(cat_ctx->pkg_ctxs);
64 free(cat_ctx);
65 }
66
67 @@ -309,30 +311,63 @@ tree_open_pkg(tree_cat_ctx *cat_ctx, const char *name)
68 return pkg_ctx;
69 }
70
71 +static int
72 +tree_pkg_compar(const void *l, const void *r)
73 +{
74 + tree_pkg_ctx *pl = *(tree_pkg_ctx **)l;
75 + tree_pkg_ctx *pr = *(tree_pkg_ctx **)r;
76 + depend_atom *al = tree_get_atom(pl, false);
77 + depend_atom *ar = tree_get_atom(pr, false);
78 +
79 + switch (atom_compare(al, ar)) {
80 + case EQUAL: return 0;
81 + case NEWER: return -1;
82 + case OLDER: return 1;
83 + default: return strcmp(al->PN, ar->PN);
84 + }
85 +
86 + /* unreachable */
87 +}
88 +
89 static tree_pkg_ctx *
90 tree_next_pkg_int(tree_cat_ctx *cat_ctx);
91 static tree_pkg_ctx *
92 tree_next_pkg_int(tree_cat_ctx *cat_ctx)
93 {
94 tree_pkg_ctx *pkg_ctx = NULL;
95 + const struct dirent *de;
96
97 if (cat_ctx->ctx->do_sort) {
98 - if (cat_ctx->pkg_de == NULL) {
99 - cat_ctx->pkg_cnt = scandirat(cat_ctx->fd, ".", &cat_ctx->pkg_de,
100 - tree_filter_pkg, cat_ctx->ctx->pkgsortfunc);
101 + if (cat_ctx->pkg_ctxs == NULL) {
102 + size_t pkg_size = 0;
103 + cat_ctx->pkg_ctxs = NULL;
104 + cat_ctx->pkg_cnt = 0;
105 cat_ctx->pkg_cur = 0;
106 - }
107 + while ((de = readdir(cat_ctx->dir)) != NULL) {
108 + if (tree_filter_pkg(de) == 0)
109 + continue;
110 +
111 + if (cat_ctx->pkg_cnt == pkg_size) {
112 + pkg_size += 256;
113 + cat_ctx->pkg_ctxs = xrealloc(cat_ctx->pkg_ctxs,
114 + sizeof(*cat_ctx->pkg_ctxs) * pkg_size);
115 + }
116 + pkg_ctx = cat_ctx->pkg_ctxs[cat_ctx->pkg_cnt++] =
117 + tree_open_pkg(cat_ctx, de->d_name);
118 + if (pkg_ctx == NULL)
119 + cat_ctx->pkg_cnt--;
120 + }
121
122 - while (cat_ctx->pkg_cur < cat_ctx->pkg_cnt) {
123 - pkg_ctx =
124 - tree_open_pkg(cat_ctx,
125 - cat_ctx->pkg_de[cat_ctx->pkg_cur++]->d_name);
126 - if (!pkg_ctx)
127 - continue;
128 - break;
129 + if (cat_ctx->ctx->pkgsortfunc != NULL) {
130 + qsort(cat_ctx->pkg_ctxs, cat_ctx->pkg_cnt,
131 + sizeof(*cat_ctx->pkg_ctxs), cat_ctx->ctx->pkgsortfunc);
132 + }
133 }
134 +
135 + pkg_ctx = NULL;
136 + if (cat_ctx->pkg_cur < cat_ctx->pkg_cnt)
137 + pkg_ctx = cat_ctx->pkg_ctxs[cat_ctx->pkg_cur++];
138 } else {
139 - const struct dirent *de;
140 do {
141 de = readdir(cat_ctx->dir);
142 if (!de)
143
144 diff --git a/libq/tree.h b/libq/tree.h
145 index 7f05819..36554be 100644
146 --- a/libq/tree.h
147 +++ b/libq/tree.h
148 @@ -48,7 +48,7 @@ struct tree_cat_ctx {
149 int fd;
150 DIR *dir;
151 tree_ctx *ctx;
152 - struct dirent **pkg_de;
153 + tree_pkg_ctx **pkg_ctxs;
154 size_t pkg_cnt;
155 size_t pkg_cur;
156 };