Merge branch 'ap/strbuf-humanize'

Teach "--human-readable" aka "-H" option to "git count-objects" to
show various large numbers in Ki/Mi/GiB scaled as necessary.

* ap/strbuf-humanize:
  count-objects: add -H option to humanize sizes
  strbuf: create strbuf_humanise_bytes() to show byte sizes
This commit is contained in:
Junio C Hamano
2013-04-19 13:31:26 -07:00
6 changed files with 86 additions and 40 deletions

View File

@ -8,7 +8,7 @@ git-count-objects - Count unpacked number of objects and their disk consumption
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git count-objects' [-v] 'git count-objects' [-v] [-H | --human-readable]
DESCRIPTION DESCRIPTION
----------- -----------
@ -24,11 +24,11 @@ OPTIONS
+ +
count: the number of loose objects count: the number of loose objects
+ +
size: disk space consumed by loose objects, in KiB size: disk space consumed by loose objects, in KiB (unless -H is specified)
+ +
in-pack: the number of in-pack objects in-pack: the number of in-pack objects
+ +
size-pack: disk space consumed by the packs, in KiB size-pack: disk space consumed by the packs, in KiB (unless -H is specified)
+ +
prune-packable: the number of loose objects that are also present in prune-packable: the number of loose objects that are also present in
the packs. These objects could be pruned using `git prune-packed`. the packs. These objects could be pruned using `git prune-packed`.
@ -36,7 +36,13 @@ the packs. These objects could be pruned using `git prune-packed`.
garbage: the number of files in object database that are not valid garbage: the number of files in object database that are not valid
loose objects nor valid packs loose objects nor valid packs
+ +
size-garbage: disk space consumed by garbage files, in KiB size-garbage: disk space consumed by garbage files, in KiB (unless -H is
specified)
-H::
--human-readable::
Print sizes in human readable format
GIT GIT
--- ---

View File

@ -230,6 +230,11 @@ which can be used by the programmer of the callback as she sees fit.
destination. This is useful for literal data to be fed to either destination. This is useful for literal data to be fed to either
strbuf_expand or to the *printf family of functions. strbuf_expand or to the *printf family of functions.
`strbuf_humanise_bytes`::
Append the given byte size as a human-readable string (i.e. 12.23 KiB,
3.50 MiB).
`strbuf_addf`:: `strbuf_addf`::
Add a formatted string to the buffer. Add a formatted string to the buffer.

View File

@ -79,13 +79,13 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
} }
static char const * const count_objects_usage[] = { static char const * const count_objects_usage[] = {
N_("git count-objects [-v]"), N_("git count-objects [-v] [-H | --human-readable]"),
NULL NULL
}; };
int cmd_count_objects(int argc, const char **argv, const char *prefix) int cmd_count_objects(int argc, const char **argv, const char *prefix)
{ {
int i, verbose = 0; int i, verbose = 0, human_readable = 0;
const char *objdir = get_object_directory(); const char *objdir = get_object_directory();
int len = strlen(objdir); int len = strlen(objdir);
char *path = xmalloc(len + 50); char *path = xmalloc(len + 50);
@ -93,6 +93,8 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
off_t loose_size = 0; off_t loose_size = 0;
struct option opts[] = { struct option opts[] = {
OPT__VERBOSE(&verbose, N_("be verbose")), OPT__VERBOSE(&verbose, N_("be verbose")),
OPT_BOOL('H', "human-readable", &human_readable,
N_("print sizes in human readable format")),
OPT_END(), OPT_END(),
}; };
@ -119,6 +121,9 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
struct packed_git *p; struct packed_git *p;
unsigned long num_pack = 0; unsigned long num_pack = 0;
off_t size_pack = 0; off_t size_pack = 0;
struct strbuf loose_buf = STRBUF_INIT;
struct strbuf pack_buf = STRBUF_INIT;
struct strbuf garbage_buf = STRBUF_INIT;
if (!packed_git) if (!packed_git)
prepare_packed_git(); prepare_packed_git();
for (p = packed_git; p; p = p->next) { for (p = packed_git; p; p = p->next) {
@ -130,17 +135,40 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
size_pack += p->pack_size + p->index_size; size_pack += p->pack_size + p->index_size;
num_pack++; num_pack++;
} }
if (human_readable) {
strbuf_humanise_bytes(&loose_buf, loose_size);
strbuf_humanise_bytes(&pack_buf, size_pack);
strbuf_humanise_bytes(&garbage_buf, size_garbage);
} else {
strbuf_addf(&loose_buf, "%lu",
(unsigned long)(loose_size / 1024));
strbuf_addf(&pack_buf, "%lu",
(unsigned long)(size_pack / 1024));
strbuf_addf(&garbage_buf, "%lu",
(unsigned long)(size_garbage / 1024));
}
printf("count: %lu\n", loose); printf("count: %lu\n", loose);
printf("size: %lu\n", (unsigned long) (loose_size / 1024)); printf("size: %s\n", loose_buf.buf);
printf("in-pack: %lu\n", packed); printf("in-pack: %lu\n", packed);
printf("packs: %lu\n", num_pack); printf("packs: %lu\n", num_pack);
printf("size-pack: %lu\n", (unsigned long) (size_pack / 1024)); printf("size-pack: %s\n", pack_buf.buf);
printf("prune-packable: %lu\n", packed_loose); printf("prune-packable: %lu\n", packed_loose);
printf("garbage: %lu\n", garbage); printf("garbage: %lu\n", garbage);
printf("size-garbage: %lu\n", (unsigned long) (size_garbage / 1024)); printf("size-garbage: %s\n", garbage_buf.buf);
strbuf_release(&loose_buf);
strbuf_release(&pack_buf);
strbuf_release(&garbage_buf);
} else {
struct strbuf buf = STRBUF_INIT;
if (human_readable)
strbuf_humanise_bytes(&buf, loose_size);
else
strbuf_addf(&buf, "%lu kilobytes",
(unsigned long)(loose_size / 1024));
printf("%lu objects, %s\n", loose, buf.buf);
strbuf_release(&buf);
} }
else
printf("%lu objects, %lu kilobytes\n",
loose, (unsigned long) (loose_size / 1024));
return 0; return 0;
} }

View File

@ -10,6 +10,7 @@
#include "git-compat-util.h" #include "git-compat-util.h"
#include "progress.h" #include "progress.h"
#include "strbuf.h"
#define TP_IDX_MAX 8 #define TP_IDX_MAX 8
@ -112,34 +113,14 @@ static int display(struct progress *progress, unsigned n, const char *done)
return 0; return 0;
} }
static void throughput_string(struct throughput *tp, off_t total, static void throughput_string(struct strbuf *buf, off_t total,
unsigned int rate) unsigned int rate)
{ {
int l = sizeof(tp->display); strbuf_addstr(buf, ", ");
if (total > 1 << 30) { strbuf_humanise_bytes(buf, total);
l -= snprintf(tp->display, l, ", %u.%2.2u GiB", strbuf_addstr(buf, " | ");
(int)(total >> 30), strbuf_humanise_bytes(buf, rate * 1024);
(int)(total & ((1 << 30) - 1)) / 10737419); strbuf_addstr(buf, "/s");
} else if (total > 1 << 20) {
int x = total + 5243; /* for rounding */
l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20);
} else if (total > 1 << 10) {
int x = total + 5; /* for rounding */
l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
} else {
l -= snprintf(tp->display, l, ", %u bytes", (int)total);
}
if (rate > 1 << 10) {
int x = rate + 5; /* for rounding */
snprintf(tp->display + sizeof(tp->display) - l, l,
" | %u.%2.2u MiB/s",
x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
} else if (rate)
snprintf(tp->display + sizeof(tp->display) - l, l,
" | %u KiB/s", rate);
} }
void display_throughput(struct progress *progress, off_t total) void display_throughput(struct progress *progress, off_t total)
@ -183,6 +164,7 @@ void display_throughput(struct progress *progress, off_t total)
misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977; misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
if (misecs > 512) { if (misecs > 512) {
struct strbuf buf = STRBUF_INIT;
unsigned int count, rate; unsigned int count, rate;
count = total - tp->prev_total; count = total - tp->prev_total;
@ -197,7 +179,9 @@ void display_throughput(struct progress *progress, off_t total)
tp->last_misecs[tp->idx] = misecs; tp->last_misecs[tp->idx] = misecs;
tp->idx = (tp->idx + 1) % TP_IDX_MAX; tp->idx = (tp->idx + 1) % TP_IDX_MAX;
throughput_string(tp, total, rate); throughput_string(&buf, total, rate);
strncpy(tp->display, buf.buf, sizeof(tp->display));
strbuf_release(&buf);
if (progress->last_value != -1 && progress_update) if (progress->last_value != -1 && progress_update)
display(progress, progress->last_value, NULL); display(progress, progress->last_value, NULL);
} }
@ -253,9 +237,12 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
bufp = (len < sizeof(buf)) ? buf : xmalloc(len + 1); bufp = (len < sizeof(buf)) ? buf : xmalloc(len + 1);
if (tp) { if (tp) {
struct strbuf strbuf = STRBUF_INIT;
unsigned int rate = !tp->avg_misecs ? 0 : unsigned int rate = !tp->avg_misecs ? 0 :
tp->avg_bytes / tp->avg_misecs; tp->avg_bytes / tp->avg_misecs;
throughput_string(tp, tp->curr_total, rate); throughput_string(&strbuf, tp->curr_total, rate);
strncpy(tp->display, strbuf.buf, sizeof(tp->display));
strbuf_release(&strbuf);
} }
progress_update = 1; progress_update = 1;
sprintf(bufp, ", %s.\n", msg); sprintf(bufp, ", %s.\n", msg);

View File

@ -528,6 +528,25 @@ void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,
strbuf_add_urlencode(sb, s, strlen(s), reserved); strbuf_add_urlencode(sb, s, strlen(s), reserved);
} }
void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
{
if (bytes > 1 << 30) {
strbuf_addf(buf, "%u.%2.2u GiB",
(int)(bytes >> 30),
(int)(bytes & ((1 << 30) - 1)) / 10737419);
} else if (bytes > 1 << 20) {
int x = bytes + 5243; /* for rounding */
strbuf_addf(buf, "%u.%2.2u MiB",
x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20);
} else if (bytes > 1 << 10) {
int x = bytes + 5; /* for rounding */
strbuf_addf(buf, "%u.%2.2u KiB",
x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
} else {
strbuf_addf(buf, "%u bytes", (int)bytes);
}
}
int printf_ln(const char *fmt, ...) int printf_ln(const char *fmt, ...)
{ {
int ret; int ret;

View File

@ -170,6 +170,7 @@ extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name);
extern void strbuf_addstr_urlencode(struct strbuf *, const char *, extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
int reserved); int reserved);
extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
__attribute__((format (printf,1,2))) __attribute__((format (printf,1,2)))
extern int printf_ln(const char *fmt, ...); extern int printf_ln(const char *fmt, ...);