From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 901CA138350 for ; Fri, 31 Jan 2020 10:49:54 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id C900DE0844; Fri, 31 Jan 2020 10:49:53 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 9C55DE0844 for ; Fri, 31 Jan 2020 10:49:53 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 72E5C34E618 for ; Fri, 31 Jan 2020 10:49:52 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 0F5C110B for ; Fri, 31 Jan 2020 10:49:50 +0000 (UTC) From: "Fabian Groffen" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Fabian Groffen" Message-ID: <1580467668.01b7a90b59097201a3316ee10f2cb512a1db852d.grobian@gentoo> Subject: [gentoo-commits] proj/portage-utils:master commit in: / X-VCS-Repository: proj/portage-utils X-VCS-Files: qsize.c X-VCS-Directories: / X-VCS-Committer: grobian X-VCS-Committer-Name: Fabian Groffen X-VCS-Revision: 01b7a90b59097201a3316ee10f2cb512a1db852d X-VCS-Branch: master Date: Fri, 31 Jan 2020 10:49:50 +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-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: b3b7eb00-22fd-4bd2-8ebd-5974c6b417f4 X-Archives-Hash: 341d7a63e6bbabae74be913e1abdf69c commit: 01b7a90b59097201a3316ee10f2cb512a1db852d Author: Fabian Groffen gentoo org> AuthorDate: Fri Jan 31 10:47:48 2020 +0000 Commit: Fabian Groffen gentoo org> CommitDate: Fri Jan 31 10:47:48 2020 +0000 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=01b7a90b qsize: don't count hardlinked files double, #11 While ensuring hardlinked files are counted only once, also report on the amount of real unique files, if different from file count. This is an alternative take to the work of Jan Ziak. Closes: PR #11 Signed-off-by: Fabian Groffen gentoo.org> qsize.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/qsize.c b/qsize.c index aa5e1d1..1a1b40e 100644 --- a/qsize.c +++ b/qsize.c @@ -93,7 +93,10 @@ struct qsize_opt_state { const char *fmt; bool need_full_atom:1; - size_t num_all_files, num_all_nonfiles, num_all_ignored; + set *uniq_files; + size_t num_all_files; + size_t num_all_nonfiles; + size_t num_all_ignored; uint64_t num_all_bytes; }; @@ -107,6 +110,11 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv) char *savep; size_t num_files, num_nonfiles, num_ignored; uint64_t num_bytes; + struct stat st; + bool ok = false; + char ikey[2 * (sizeof(size_t) * 2) + 1]; /* hex rep */ + size_t cur_uniq = cnt_set(state->uniq_files); + bool isuniq; if ((line = tree_pkg_meta_get(pkg_ctx, CONTENTS)) == NULL) return EXIT_SUCCESS; @@ -115,8 +123,8 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv) for (; (line = strtok_r(line, "\n", &savep)) != NULL; line = NULL) { contents_entry *e; regex_t *regex; - int ok = 0; + ok = false; e = contents_parse_line(line); if (!e) continue; @@ -124,21 +132,27 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv) array_for_each(state->ignore_regexp, i, regex) { if (!regexec(regex, e->name, 0, NULL, 0)) { num_ignored++; - ok = 1; + ok = true; } } if (ok) continue; if (e->type == CONTENTS_OBJ || e->type == CONTENTS_SYM) { - struct stat st; - ++num_files; - if (!fstatat(pkg_ctx->cat_ctx->ctx->portroot_fd, - e->name + 1, &st, AT_SYMLINK_NOFOLLOW)) - num_bytes += - state->fs_size ? st.st_blocks * S_BLKSIZE : st.st_size; - } else - ++num_nonfiles; + num_files++; + if (fstatat(pkg_ctx->cat_ctx->ctx->portroot_fd, + e->name + 1, &st, AT_SYMLINK_NOFOLLOW) == 0) + { + snprintf(ikey, sizeof(ikey), "%zx%zx", + (size_t)st.st_dev, (size_t)st.st_ino); + add_set_unique(ikey, state->uniq_files, &isuniq); + if (isuniq) + num_bytes += + state->fs_size ? st.st_blocks * S_BLKSIZE : st.st_size; + } + } else { + num_nonfiles++; + } } state->num_all_bytes += num_bytes; state->num_all_files += num_files; @@ -146,10 +160,19 @@ qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv) state->num_all_ignored += num_ignored; if (!state->summary_only) { + char uniqbuf[32]; + + cur_uniq = cnt_set(state->uniq_files) - cur_uniq; atom = tree_get_atom(pkg_ctx, state->need_full_atom); - printf("%s: %zu files, %zu non-files, ", + + if (cur_uniq != num_files) + snprintf(uniqbuf, sizeof(uniqbuf), " (%zu unique)", cur_uniq); + else + uniqbuf[0] = '\0'; + + printf("%s: %zu files%s, %zu non-files, ", atom_format(state->fmt, atom), - num_files, num_nonfiles); + num_files, uniqbuf, num_nonfiles); if (num_ignored) printf("%zu names-ignored, ", num_ignored); printf("%s %s\n", @@ -177,10 +200,11 @@ int qsize_main(int argc, char **argv) .disp_units = 0, .str_disp_units = NULL, .ignore_regexp = ignore_regexp, - .num_all_bytes = 0, + .uniq_files = create_set(), .num_all_files = 0, .num_all_nonfiles = 0, .num_all_ignored = 0, + .num_all_bytes = 0, .need_full_atom = false, .fmt = NULL, }; @@ -238,8 +262,16 @@ int qsize_main(int argc, char **argv) } if (state.summary) { - printf(" %sTotals%s: %zu files, %zu non-files, ", BOLD, NORM, - state.num_all_files, state.num_all_nonfiles); + char uniqbuf[32]; + size_t uniq_files = cnt_set(state.uniq_files); + + if (uniq_files != state.num_all_files) + snprintf(uniqbuf, sizeof(uniqbuf), " (%zu unique)", uniq_files); + else + uniqbuf[0] = '\0'; + + printf(" %sTotals%s: %zu files%s, %zu non-files, ", BOLD, NORM, + state.num_all_files, uniqbuf, state.num_all_nonfiles); if (state.num_all_ignored) printf("%zu names-ignored, ", state.num_all_ignored); printf("%s %s\n", @@ -252,6 +284,7 @@ int qsize_main(int argc, char **argv) atom_implode(atom); xarrayfree_int(state.atoms); xarrayfree(state.ignore_regexp); + free_set(state.uniq_files); return ret; }