X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/agedu/blobdiff_plain/b49db535793898495dc9ee9a05f86c65a2af3190..f5d425d99c31f10cf2b74e5250f87ce8d2aa3a3e:/html.c diff --git a/html.c b/html.c index 4390668..dacd68c 100644 --- a/html.c +++ b/html.c @@ -24,7 +24,7 @@ struct html { time_t now; }; -static void vhtprintf(struct html *ctx, char *fmt, va_list ap) +static void vhtprintf(struct html *ctx, const char *fmt, va_list ap) { va_list ap2; int size, size2; @@ -50,7 +50,7 @@ static void vhtprintf(struct html *ctx, char *fmt, va_list ap) ctx->buflen += size; } -static void htprintf(struct html *ctx, char *fmt, ...) +static void htprintf(struct html *ctx, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -176,7 +176,21 @@ static unsigned long long fetch_size(const void *t, unsigned long xi1, unsigned long xi2, unsigned long long atime) { - return index_query(t, xi2, atime) - index_query(t, xi1, atime); + if (xi2 - xi1 == 1) { + /* + * We are querying an individual file, so we should not + * depend on the index entries either side of the node, + * since they almost certainly don't both exist. Instead, + * just look up the file's size and atime in the main trie. + */ + const struct trie_file *f = trie_getfile(t, xi1); + if (f->atime < atime) + return f->size; + else + return 0; + } else { + return index_query(t, xi2, atime) - index_query(t, xi1, atime); + } } static void htescape(struct html *ctx, const char *s, int n, int italics) @@ -235,7 +249,7 @@ static void end_colour_bar(struct html *ctx) } struct vector { - int want_href; + int want_href, essential; char *name; int literal; /* should the name be formatted in fixed-pitch? */ unsigned long index; @@ -261,17 +275,23 @@ int vec_compare(const void *av, const void *bv) return -1; else if (a->index > b->index) return +1; + else if (a->essential < b->essential) + return +1; + else if (a->essential > b->essential) + return -1; return 0; } static struct vector *make_vector(struct html *ctx, char *path, - int want_href, char *name, int literal) + int want_href, int essential, + char *name, int literal) { unsigned long xi1, xi2; struct vector *vec = snew(struct vector); int i; vec->want_href = want_href; + vec->essential = essential; vec->name = name ? dupstr(name) : NULL; vec->literal = literal; @@ -297,12 +317,31 @@ static void print_heading(struct html *ctx, const char *title) "%s\n\n", title); } +static void compute_display_size(unsigned long long size, + const char **fmt, double *display_size) +{ + static const char *const fmts[] = { + "%g b", "%g Kb", "%#.1f Mb", "%#.1f Gb", "%#.1f Tb", + "%#.1f Pb", "%#.1f Eb", "%#.1f Zb", "%#.1f Yb" + }; + int shift = 0; + + while (size >= 1024 && shift < lenof(fmts)-1) { + size >>= 10; + shift++; + } + *display_size = (double)size; + *fmt = fmts[shift]; +} + #define PIXEL_SIZE 600 /* FIXME: configurability? */ static void write_report_line(struct html *ctx, struct vector *vec) { unsigned long long size, asize, divisor; + double display_size; int pix, newpix; int i; + const char *unitsfmt; /* * A line with literally zero space usage should not be @@ -313,7 +352,7 @@ static void write_report_line(struct html *ctx, struct vector *vec) * case we must fiddle about to prevent divisions by zero in * the code below. */ - if (!vec->sizes[MAXCOLOUR] && vec->want_href) + if (!vec->sizes[MAXCOLOUR] && !vec->essential) return; divisor = ctx->totalsize; if (!divisor) { @@ -324,9 +363,11 @@ static void write_report_line(struct html *ctx, struct vector *vec) * Find the total size of this subdirectory. */ size = vec->sizes[MAXCOLOUR]; + compute_display_size(size, &unitsfmt, &display_size); htprintf(ctx, "\n" - "%lluMb\n", - ((size + ((1<<20)-1)) >> 20)); /* convert to Mb, rounding up */ + ""); + htprintf(ctx, unitsfmt, display_size); + htprintf(ctx, "\n"); /* * Generate a colour bar. @@ -542,7 +583,7 @@ char *html_query(const void *t, unsigned long index, vecsize = 64; vecs = snewn(vecsize, struct vector *); nvecs = 1; - vecs[0] = make_vector(ctx, path, 0, NULL, 0); + vecs[0] = make_vector(ctx, path, 0, 1, NULL, 0); print_heading(ctx, "Overall"); write_report_line(ctx, vecs[0]); @@ -563,14 +604,15 @@ char *html_query(const void *t, unsigned long index, trie_getpath(t, xi1, path2); get_indices(t, ctx->path2, &xj1, &xj2); xi1 = xj2; - if (xj2 - xj1 <= 1) + if (!cfg->showfiles && xj2 - xj1 <= 1) continue; /* skip individual files */ if (nvecs >= vecsize) { vecsize = nvecs * 3 / 2 + 64; vecs = sresize(vecs, vecsize, struct vector *); } assert(strlen(path2) > pathlen); - vecs[nvecs] = make_vector(ctx, path2, 1, path2 + subdirpos, 1); + vecs[nvecs] = make_vector(ctx, path2, (xj2 - xj1 > 1), 0, + path2 + subdirpos, 1); for (i = 0; i <= MAXCOLOUR; i++) vecs[0]->sizes[i] -= vecs[nvecs]->sizes[i]; nvecs++;