From: "Fabian Groffen" <grobian@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/portage-utils:master commit in: libq/
Date: Mon, 14 Jun 2021 09:34:15 +0000 (UTC) [thread overview]
Message-ID: <1623166127.9a4c654be5e759b4bb0fed1ac802a57fb1cb5c30.grobian@gentoo> (raw)
commit: 9a4c654be5e759b4bb0fed1ac802a57fb1cb5c30
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Jun 8 15:28:47 2021 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Jun 8 15:28:47 2021 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=9a4c654b
libq/tree: build cache for Packages/binpkgs
Because we cannot trust Packages file to be in sorted order, and the
order isn't what we want (most recent match on top), we have to sort the
pkgs found in Packages, so make that exploit the cache, which will speed
up any subsequent tree_match_atom calls, which is good.
Do the same for binpkg trees, since they also cannot be cached
otherwise.
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
libq/tree.c | 180 ++++++++++++++++++++++++++++++------------------------------
libq/tree.h | 1 +
2 files changed, 90 insertions(+), 91 deletions(-)
diff --git a/libq/tree.c b/libq/tree.c
index 358b1f2..d7ec882 100644
--- a/libq/tree.c
+++ b/libq/tree.c
@@ -312,8 +312,29 @@ tree_next_cat(tree_ctx *ctx)
if (ctx->do_sort) {
if (ctx->cat_de == NULL) {
- ctx->cat_cnt = scandirat(ctx->tree_fd,
- ".", &ctx->cat_de, tree_filter_cat, alphasort);
+ if (ctx->cache.all_categories) {
+ char **cats;
+ size_t i;
+ size_t len;
+ struct dirent **ret;
+
+ /* exploit the cache instead of reading from directory */
+ ctx->cat_cnt = cnt_set(ctx->cache.categories);
+ ctx->cat_de = ret = xmalloc(sizeof(*ret) * ctx->cat_cnt);
+ list_set(ctx->cache.categories, &cats);
+ for (i = 0; i < ctx->cat_cnt; i++) {
+ len = strlen(cats[i]) + 1;
+ ret[i] = xzalloc(sizeof(*de) + len);
+ snprintf(ret[i]->d_name, len, "%s", cats[i]);
+ }
+ if (i > 1)
+ qsort(ret, ctx->cat_cnt, sizeof(*ret),
+ (int (*)(const void *, const void *))alphasort);
+ free(cats);
+ } else {
+ ctx->cat_cnt = scandirat(ctx->tree_fd,
+ ".", &ctx->cat_de, tree_filter_cat, alphasort);
+ }
ctx->cat_cur = 0;
}
@@ -1511,7 +1532,7 @@ tree_foreach_pkg(tree_ctx *ctx, tree_pkg_cb callback, void *priv,
ctx->cat_de = NULL;
ctx->cat_cur = 0;
ctx->cat_cnt = 0;
- ctx->do_sort = 0;
+ ctx->do_sort = false;
return ret;
}
@@ -1624,77 +1645,33 @@ tree_get_atoms(tree_ctx *ctx, bool fullcpv, set *satoms)
return state.cpf;
}
-struct tree_match_pkgs_cb_ctx {
- int flags;
- tree_match_ctx *ret;
-};
-
static int
-tree_match_atom_packages_cb(tree_pkg_ctx *ctx, void *priv)
+tree_match_atom_cache_populate_cb(tree_pkg_ctx *ctx, void *priv)
{
- struct tree_match_pkgs_cb_ctx *rctx = priv;
- depend_atom *a;
- tree_match_ctx *n;
-
- /* skip anything after finding first match */
- if (rctx->flags & TREE_MATCH_FIRST && rctx->ret != NULL)
- return 1;
-
- a = tree_get_atom(ctx, rctx->flags & TREE_MATCH_FULL_ATOM);
-
- /* skip virtual category if not requested */
- if (!(rctx->flags & TREE_MATCH_VIRTUAL) &&
- strcmp(a->CATEGORY, "virtual") == 0)
- return 1;
-
- n = xzalloc(sizeof(tree_match_ctx));
- n->free_atom = true;
- n->atom = atom_clone(a);
- snprintf(n->path, sizeof(n->path), "%s/%s/%s.tbz2",
- (char *)ctx->cat_ctx->ctx->path, ctx->cat_ctx->name, ctx->name);
- if (rctx->flags & TREE_MATCH_METADATA) {
- n->meta = xmalloc(sizeof(*n->meta));
- /* for Packages, all pointers to meta here are to the in memory
- * copy of the Packages file, so these pointers can just be
- * copied since the tree has to remain open, thus the pointers
- * will stay valid */
- memcpy(n->meta, ctx->cat_ctx->ctx->pkgs, sizeof(*n->meta));
+ set *cache = priv;
+ tree_cat_ctx *cat_ctx;
+ tree_pkg_ctx *pkg;
+ tree_ctx *tctx = ctx->cat_ctx->ctx;
+ depend_atom *atom = tree_get_atom(ctx, true);
+
+ (void)priv;
+
+ cat_ctx = get_set(atom->CATEGORY, cache);
+ if (cat_ctx == NULL) {
+ cat_ctx = tree_open_cat(tctx, ".");
+ add_set_value(atom->CATEGORY, cat_ctx, cache);
+ /* get a pointer from the set */
+ cat_ctx->name = contains_set(atom->CATEGORY, cache);
}
- n->next = rctx->ret;
- rctx->ret = n;
-
- return 0;
-}
-
-static int
-tree_match_atom_binpkg_cb(tree_pkg_ctx *ctx, void *priv)
-{
- struct tree_match_pkgs_cb_ctx *rctx = priv;
- depend_atom *a;
- tree_match_ctx *n;
-
- /* skip anything after finding first match */
- if (rctx->flags & TREE_MATCH_FIRST && rctx->ret != NULL)
- return 1;
-
- a = tree_get_atom(ctx, rctx->flags & TREE_MATCH_FULL_ATOM);
-
- /* skip virtual category if not requested */
- if (!(rctx->flags & TREE_MATCH_VIRTUAL) &&
- strcmp(a->CATEGORY, "virtual") == 0)
- return 1;
-
- n = xzalloc(sizeof(tree_match_ctx));
- n->free_atom = true;
- n->atom = atom_clone(a);
- snprintf(n->path, sizeof(n->path), "%s/%s/%s.tbz2",
- (char *)ctx->cat_ctx->ctx->path, ctx->cat_ctx->name, ctx->name);
- if (rctx->flags & TREE_MATCH_METADATA)
- n->meta = tree_pkg_read(ctx);
-
- n->next = rctx->ret;
- rctx->ret = n;
+ /* FIXME: this really could use a set */
+ cat_ctx->pkg_cnt++;
+ cat_ctx->pkg_ctxs = xrealloc(cat_ctx->pkg_ctxs,
+ sizeof(*cat_ctx->pkg_ctxs) * cat_ctx->pkg_cnt);
+ cat_ctx->pkg_ctxs[cat_ctx->pkg_cnt - 1] =
+ pkg = tree_open_pkg(cat_ctx, atom->PF);
+ pkg->atom = atom_clone(atom);
+ pkg->name = pkg->atom->PF;
return 0;
}
@@ -1707,24 +1684,48 @@ tree_match_atom(tree_ctx *ctx, depend_atom *query, int flags)
tree_match_ctx *ret = NULL;
depend_atom *atom;
- if (ctx->cachetype == CACHE_PACKAGES) {
- struct tree_match_pkgs_cb_ctx rctx;
- /* Packages needs to be serviced separately because it doesn't
- * use a tree internally, but reads off of the Packages file */
- rctx.flags = flags;
- rctx.ret = NULL;
- ctx->query_atom = query;
- tree_foreach_packages(ctx, tree_match_atom_packages_cb, &rctx);
- ctx->query_atom = NULL;
- return rctx.ret;
- } else if (ctx->cachetype == CACHE_BINPKGS) {
- struct tree_match_pkgs_cb_ctx rctx;
- /* this sulks, but binpkgs modify the pkg_ctx->name to strip off
- * .tbz2, and that makes it non-reusable */
- rctx.flags = flags;
- rctx.ret = NULL;
- tree_foreach_pkg(ctx, tree_match_atom_binpkg_cb, &rctx, true, query);
- return rctx.ret;
+ ctx->do_sort = true; /* sort uses buffer, which cache relies on */
+ ctx->query_atom = NULL; /* ensure the cache contains ALL pkgs */
+
+ if ((ctx->cachetype == CACHE_PACKAGES || ctx->cachetype == CACHE_BINPKGS)
+ && ctx->cache.categories == NULL)
+ {
+ set *cache;
+ DECLARE_ARRAY(cats);
+ size_t n;
+
+ /* Reading these formats requires us to traverse the tree for
+ * each operation, so we better cache the entire thing in one
+ * go. Packages in addition may not store the atoms sorted
+ * (it's a file with content after all) and since we rely on
+ * this for latest and first match, it is important that we sort
+ * the contents so we're sure */
+
+ cache = ctx->cache.categories;
+ if (ctx->cache.categories != NULL)
+ ctx->cache.categories = NULL;
+ else
+ cache = create_set();
+
+ if (ctx->cachetype == CACHE_PACKAGES)
+ tree_foreach_packages(ctx,
+ tree_match_atom_cache_populate_cb, cache);
+ else /* BINPKG */
+ tree_foreach_pkg(ctx,
+ tree_match_atom_cache_populate_cb, cache, true, NULL);
+ ctx->do_sort = true; /* turn it back on */
+ ctx->cache.all_categories = true;
+
+ ctx->cache.categories = cache;
+
+ /* loop through all categories, and sort the pkgs */
+ values_set(cache, cats);
+ array_for_each(cats, n, cat_ctx) {
+ if (cat_ctx->pkg_cnt > 1) {
+ qsort(cat_ctx->pkg_ctxs, cat_ctx->pkg_cnt,
+ sizeof(*cat_ctx->pkg_ctxs), tree_pkg_compar);
+ }
+ }
}
/* activate cache for future lookups, tree_match_atom relies on
@@ -1733,9 +1734,6 @@ tree_match_atom(tree_ctx *ctx, depend_atom *query, int flags)
if (ctx->cache.categories == NULL)
ctx->cache.categories = create_set();
- ctx->do_sort = true; /* sort uses buffer, which cache relies on */
- ctx->query_atom = NULL; /* ensure the cache contains ALL pkgs */
-
#define search_cat(C) \
{ \
char *lastpn = NULL; \
diff --git a/libq/tree.h b/libq/tree.h
index 5a12c92..8741bad 100644
--- a/libq/tree.h
+++ b/libq/tree.h
@@ -48,6 +48,7 @@ struct tree_ctx {
depend_atom *query_atom;
struct tree_cache {
set *categories;
+ bool all_categories:1;
} cache;
};
next reply other threads:[~2021-06-14 9:34 UTC|newest]
Thread overview: 196+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-14 9:34 Fabian Groffen [this message]
-- strict thread matches above, loose matches on Subject: below --
2024-07-03 19:44 [gentoo-commits] proj/portage-utils:master commit in: libq/ Fabian Groffen
2024-04-08 19:27 Fabian Groffen
2024-02-01 8:21 Fabian Groffen
2024-02-01 8:21 Fabian Groffen
2024-01-31 20:41 Fabian Groffen
2024-01-31 19:30 Fabian Groffen
2024-01-31 19:29 Fabian Groffen
2024-01-27 13:28 Fabian Groffen
2023-04-21 19:11 Fabian Groffen
2023-01-30 14:14 Fabian Groffen
2022-05-26 14:36 Fabian Groffen
2022-05-26 14:36 Fabian Groffen
2022-05-20 17:15 Fabian Groffen
2022-05-20 17:15 Fabian Groffen
2022-05-19 8:32 Fabian Groffen
2022-05-19 8:16 Fabian Groffen
2022-05-19 7:45 Fabian Groffen
2022-02-12 17:13 Fabian Groffen
2022-02-12 17:13 Fabian Groffen
2022-02-06 14:51 Fabian Groffen
2022-02-06 14:29 Fabian Groffen
2022-02-06 13:27 Fabian Groffen
2022-02-06 13:27 Fabian Groffen
2022-02-06 12:22 Fabian Groffen
2021-12-29 12:20 Fabian Groffen
2021-12-26 13:59 Fabian Groffen
2021-12-26 13:59 Fabian Groffen
2021-12-26 13:59 Fabian Groffen
2021-12-26 13:59 Fabian Groffen
2021-12-13 8:39 Fabian Groffen
2021-12-13 8:39 Fabian Groffen
2021-11-13 14:27 Fabian Groffen
2021-10-09 12:13 Fabian Groffen
2021-10-04 6:28 Fabian Groffen
2021-10-04 6:28 Fabian Groffen
2021-10-03 10:49 Fabian Groffen
2021-06-23 7:14 Fabian Groffen
2021-06-14 9:34 Fabian Groffen
2021-06-14 9:34 Fabian Groffen
2021-06-14 9:34 Fabian Groffen
2021-06-14 9:34 Fabian Groffen
2021-06-14 9:34 Fabian Groffen
2021-06-01 19:43 Fabian Groffen
2021-05-23 10:54 Fabian Groffen
2021-05-10 9:15 Fabian Groffen
2021-04-29 15:04 Fabian Groffen
2021-04-29 13:47 Fabian Groffen
2021-04-29 13:24 Fabian Groffen
2021-03-13 12:44 Fabian Groffen
2021-02-20 12:06 Fabian Groffen
2021-02-20 11:44 Fabian Groffen
2021-02-17 20:23 Fabian Groffen
2021-02-17 20:23 Fabian Groffen
2021-01-15 20:05 Fabian Groffen
2020-06-27 9:38 Fabian Groffen
2020-06-07 10:41 Fabian Groffen
2020-05-25 18:19 Fabian Groffen
2020-05-25 18:02 Fabian Groffen
2020-05-25 13:26 Fabian Groffen
2020-05-25 11:20 Fabian Groffen
2020-05-25 11:06 Fabian Groffen
2020-05-25 10:43 Fabian Groffen
2020-05-25 10:43 Fabian Groffen
2020-05-25 10:43 Fabian Groffen
2020-05-25 10:43 Fabian Groffen
2020-05-25 10:43 Fabian Groffen
2020-05-17 12:35 Fabian Groffen
2020-05-17 12:35 Fabian Groffen
2020-02-03 13:17 Fabian Groffen
2020-02-03 13:09 Fabian Groffen
2020-01-26 19:31 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-20 19:54 Fabian Groffen
2020-01-20 19:34 Fabian Groffen
2020-01-19 19:36 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 16:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-19 10:05 Fabian Groffen
2020-01-19 9:49 Fabian Groffen
2020-01-19 9:49 Fabian Groffen
2020-01-17 8:22 Fabian Groffen
2020-01-05 16:08 Fabian Groffen
2020-01-05 16:08 Fabian Groffen
2020-01-05 16:08 Fabian Groffen
2020-01-02 15:09 Fabian Groffen
2020-01-02 14:07 Fabian Groffen
2020-01-02 14:07 Fabian Groffen
2020-01-02 14:07 Fabian Groffen
2020-01-02 11:55 Fabian Groffen
2020-01-02 11:19 Fabian Groffen
2019-12-30 17:24 Fabian Groffen
2019-12-27 21:19 Fabian Groffen
2019-12-27 16:57 Fabian Groffen
2019-12-27 16:57 Fabian Groffen
2019-11-29 13:22 Fabian Groffen
2019-11-20 17:23 Fabian Groffen
2019-11-19 20:28 Fabian Groffen
2019-11-17 15:12 Fabian Groffen
2019-11-17 15:12 Fabian Groffen
2019-11-13 18:19 Fabian Groffen
2019-11-13 15:48 Fabian Groffen
2019-11-13 15:20 Fabian Groffen
2019-11-09 10:29 Fabian Groffen
2019-09-26 14:06 Fabian Groffen
2019-09-26 14:06 Fabian Groffen
2019-09-26 14:06 Fabian Groffen
2019-09-26 14:06 Fabian Groffen
2019-09-26 13:00 Fabian Groffen
2019-09-25 15:05 Fabian Groffen
2019-09-21 19:53 Fabian Groffen
2019-09-21 19:53 Fabian Groffen
2019-07-14 18:51 Fabian Groffen
2019-07-13 15:37 Fabian Groffen
2019-07-13 9:50 Fabian Groffen
2019-07-12 18:04 Fabian Groffen
2019-06-19 7:41 Fabian Groffen
2019-06-10 10:09 Fabian Groffen
2019-06-05 7:57 Fabian Groffen
2019-05-21 14:12 Fabian Groffen
2019-05-14 20:19 Fabian Groffen
2019-05-14 20:19 Fabian Groffen
2019-05-11 11:11 Fabian Groffen
2019-05-11 7:14 Fabian Groffen
2019-05-11 7:14 Fabian Groffen
2019-05-10 15:32 Fabian Groffen
2019-05-10 15:32 Fabian Groffen
2019-05-10 15:32 Fabian Groffen
2019-05-07 6:19 Fabian Groffen
2019-05-06 16:04 Fabian Groffen
2019-05-06 16:04 Fabian Groffen
2019-05-05 20:05 Fabian Groffen
2019-05-05 18:13 Fabian Groffen
2019-05-05 8:58 Fabian Groffen
2019-05-04 11:53 Fabian Groffen
2019-05-03 11:45 Fabian Groffen
2019-05-02 15:17 Fabian Groffen
2019-05-01 19:09 Fabian Groffen
2019-04-30 8:20 Fabian Groffen
2019-04-30 7:54 Fabian Groffen
2019-04-28 17:10 Fabian Groffen
2019-04-28 16:21 Fabian Groffen
2019-04-28 16:02 Fabian Groffen
2019-04-27 8:38 Fabian Groffen
2019-04-25 17:36 Fabian Groffen
2019-04-25 9:22 Fabian Groffen
2019-04-25 9:22 Fabian Groffen
2019-04-25 9:22 Fabian Groffen
2019-04-25 9:22 Fabian Groffen
2019-04-19 11:47 Fabian Groffen
2019-03-27 10:55 Fabian Groffen
2019-03-11 20:55 Fabian Groffen
2019-03-09 18:58 Fabian Groffen
2019-02-27 20:53 Fabian Groffen
2019-02-27 20:53 Fabian Groffen
2019-02-05 14:19 Fabian Groffen
2018-12-20 20:02 Fabian Groffen
2018-12-20 20:02 Fabian Groffen
2018-12-20 18:24 Fabian Groffen
2018-04-09 7:15 Fabian Groffen
2018-04-05 13:31 Fabian Groffen
2018-04-05 12:46 Fabian Groffen
2018-04-03 20:00 Fabian Groffen
2018-03-26 18:41 Fabian Groffen
2018-03-25 14:13 Fabian Groffen
2018-03-25 14:00 Fabian Groffen
2018-03-23 20:17 Fabian Groffen
2018-03-23 11:56 Fabian Groffen
2018-03-23 11:29 Fabian Groffen
2017-12-29 11:45 Fabian Groffen
2017-12-29 11:45 Fabian Groffen
2017-12-29 11:45 Fabian Groffen
2016-12-29 2:25 Mike Frysinger
2016-11-12 17:23 Mike Frysinger
2016-02-14 1:26 Mike Frysinger
2016-02-14 1:26 Mike Frysinger
2015-11-26 8:43 Mike Frysinger
2015-10-15 22:00 Mike Frysinger
2015-10-15 22:00 Mike Frysinger
2015-05-31 8:31 Mike Frysinger
2015-05-19 17:37 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-21 18:06 Mike Frysinger
2015-02-16 11:47 Mike Frysinger
2014-03-11 4:53 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1623166127.9a4c654be5e759b4bb0fed1ac802a57fb1cb5c30.grobian@gentoo \
--to=grobian@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox