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: /
Date: Fri, 31 Jan 2020 10:49:54
Message-Id: 1580467668.01b7a90b59097201a3316ee10f2cb512a1db852d.grobian@gentoo
1 commit: 01b7a90b59097201a3316ee10f2cb512a1db852d
2 Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
3 AuthorDate: Fri Jan 31 10:47:48 2020 +0000
4 Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
5 CommitDate: Fri Jan 31 10:47:48 2020 +0000
6 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=01b7a90b
7
8 qsize: don't count hardlinked files double, #11
9
10 While ensuring hardlinked files are counted only once, also report on
11 the amount of real unique files, if different from file count.
12
13 This is an alternative take to the work of Jan Ziak.
14
15 Closes: PR #11
16 Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
17
18 qsize.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++----------------
19 1 file changed, 49 insertions(+), 16 deletions(-)
20
21 diff --git a/qsize.c b/qsize.c
22 index aa5e1d1..1a1b40e 100644
23 --- a/qsize.c
24 +++ b/qsize.c
25 @@ -93,7 +93,10 @@ struct qsize_opt_state {
26 const char *fmt;
27 bool need_full_atom:1;
28
29 - size_t num_all_files, num_all_nonfiles, num_all_ignored;
30 + set *uniq_files;
31 + size_t num_all_files;
32 + size_t num_all_nonfiles;
33 + size_t num_all_ignored;
34 uint64_t num_all_bytes;
35 };
36
37 @@ -107,6 +110,11 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv)
38 char *savep;
39 size_t num_files, num_nonfiles, num_ignored;
40 uint64_t num_bytes;
41 + struct stat st;
42 + bool ok = false;
43 + char ikey[2 * (sizeof(size_t) * 2) + 1]; /* hex rep */
44 + size_t cur_uniq = cnt_set(state->uniq_files);
45 + bool isuniq;
46
47 if ((line = tree_pkg_meta_get(pkg_ctx, CONTENTS)) == NULL)
48 return EXIT_SUCCESS;
49 @@ -115,8 +123,8 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv)
50 for (; (line = strtok_r(line, "\n", &savep)) != NULL; line = NULL) {
51 contents_entry *e;
52 regex_t *regex;
53 - int ok = 0;
54
55 + ok = false;
56 e = contents_parse_line(line);
57 if (!e)
58 continue;
59 @@ -124,21 +132,27 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv)
60 array_for_each(state->ignore_regexp, i, regex) {
61 if (!regexec(regex, e->name, 0, NULL, 0)) {
62 num_ignored++;
63 - ok = 1;
64 + ok = true;
65 }
66 }
67 if (ok)
68 continue;
69
70 if (e->type == CONTENTS_OBJ || e->type == CONTENTS_SYM) {
71 - struct stat st;
72 - ++num_files;
73 - if (!fstatat(pkg_ctx->cat_ctx->ctx->portroot_fd,
74 - e->name + 1, &st, AT_SYMLINK_NOFOLLOW))
75 - num_bytes +=
76 - state->fs_size ? st.st_blocks * S_BLKSIZE : st.st_size;
77 - } else
78 - ++num_nonfiles;
79 + num_files++;
80 + if (fstatat(pkg_ctx->cat_ctx->ctx->portroot_fd,
81 + e->name + 1, &st, AT_SYMLINK_NOFOLLOW) == 0)
82 + {
83 + snprintf(ikey, sizeof(ikey), "%zx%zx",
84 + (size_t)st.st_dev, (size_t)st.st_ino);
85 + add_set_unique(ikey, state->uniq_files, &isuniq);
86 + if (isuniq)
87 + num_bytes +=
88 + state->fs_size ? st.st_blocks * S_BLKSIZE : st.st_size;
89 + }
90 + } else {
91 + num_nonfiles++;
92 + }
93 }
94 state->num_all_bytes += num_bytes;
95 state->num_all_files += num_files;
96 @@ -146,10 +160,19 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv)
97 state->num_all_ignored += num_ignored;
98
99 if (!state->summary_only) {
100 + char uniqbuf[32];
101 +
102 + cur_uniq = cnt_set(state->uniq_files) - cur_uniq;
103 atom = tree_get_atom(pkg_ctx, state->need_full_atom);
104 - printf("%s: %zu files, %zu non-files, ",
105 +
106 + if (cur_uniq != num_files)
107 + snprintf(uniqbuf, sizeof(uniqbuf), " (%zu unique)", cur_uniq);
108 + else
109 + uniqbuf[0] = '\0';
110 +
111 + printf("%s: %zu files%s, %zu non-files, ",
112 atom_format(state->fmt, atom),
113 - num_files, num_nonfiles);
114 + num_files, uniqbuf, num_nonfiles);
115 if (num_ignored)
116 printf("%zu names-ignored, ", num_ignored);
117 printf("%s %s\n",
118 @@ -177,10 +200,11 @@ int qsize_main(int argc, char **argv)
119 .disp_units = 0,
120 .str_disp_units = NULL,
121 .ignore_regexp = ignore_regexp,
122 - .num_all_bytes = 0,
123 + .uniq_files = create_set(),
124 .num_all_files = 0,
125 .num_all_nonfiles = 0,
126 .num_all_ignored = 0,
127 + .num_all_bytes = 0,
128 .need_full_atom = false,
129 .fmt = NULL,
130 };
131 @@ -238,8 +262,16 @@ int qsize_main(int argc, char **argv)
132 }
133
134 if (state.summary) {
135 - printf(" %sTotals%s: %zu files, %zu non-files, ", BOLD, NORM,
136 - state.num_all_files, state.num_all_nonfiles);
137 + char uniqbuf[32];
138 + size_t uniq_files = cnt_set(state.uniq_files);
139 +
140 + if (uniq_files != state.num_all_files)
141 + snprintf(uniqbuf, sizeof(uniqbuf), " (%zu unique)", uniq_files);
142 + else
143 + uniqbuf[0] = '\0';
144 +
145 + printf(" %sTotals%s: %zu files%s, %zu non-files, ", BOLD, NORM,
146 + state.num_all_files, uniqbuf, state.num_all_nonfiles);
147 if (state.num_all_ignored)
148 printf("%zu names-ignored, ", state.num_all_ignored);
149 printf("%s %s\n",
150 @@ -252,6 +284,7 @@ int qsize_main(int argc, char **argv)
151 atom_implode(atom);
152 xarrayfree_int(state.atoms);
153 xarrayfree(state.ignore_regexp);
154 + free_set(state.uniq_files);
155
156 return ret;
157 }