diff --git a/content/fetchers/about.c b/content/fetchers/about.c index 5c33c1881..cb533bc54 100644 --- a/content/fetchers/about.c +++ b/content/fetchers/about.c @@ -54,6 +54,7 @@ #include "utils/utils.h" #include "utils/ring.h" #include "utils/testament.h" +#include "image/image_cache.h" struct fetch_about_context; @@ -159,7 +160,88 @@ static bool fetch_about_licence_handler(struct fetch_about_context *ctx) return true; } +/** Handler to generate about:cache page. + * + * Shows details of current iamge cache + * + */ +static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx) +{ + char buffer[1024]; /* output buffer */ + int code = 200; + int slen; + unsigned int cent_loop = 0; + int res = 0; + /* content is going to return ok */ + fetch_set_http_code(ctx->fetchh, code); + + /* content type */ + if (fetch_about_send_header(ctx, "Content-Type: text/html")) + goto fetch_about_imagecache_handler_aborted; + + slen = snprintf(buffer, sizeof buffer, + "\n
\n" + "Entry | Content Key | Redraw Count | Conversion Count | Last Redraw | Bitmap Age | Bitmap Size |
---|---|---|---|---|---|---|
%e | %k | %r | %c | %a | %g | %s |
Configured limit of %ld hysteresis of %ld", + image_cache->params.limit, image_cache->params.hysteresis); + + slen += snprintf(string + slen, size - slen, + "
Total bitmap size in use %ld (in %d)", + image_cache->total_bitmap_size, + image_cache->bitmap_count); + + op_count = image_cache->hit_count + + image_cache->miss_count + + image_cache->fail_count; + + slen += snprintf(string + slen, size - slen, + "
Age %ds", image_cache->current_age / 1000); + + slen += snprintf(string + slen, size - slen, + "
Peak size %ld (in %d)", + image_cache->max_bitmap_size, + image_cache->max_bitmap_size_count ); + slen += snprintf(string + slen, size - slen, + "
Peak image count %d (size %ld)", + image_cache->max_bitmap_count, + image_cache->max_bitmap_count_size); + + if (op_count > 0) { + uint64_t op_size; + + op_size = image_cache->hit_size + + image_cache->miss_size + + image_cache->fail_size; + + slen += snprintf(string + slen, size - slen, + "
Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)", + op_count, + image_cache->hit_count, + image_cache->miss_count, + image_cache->fail_count, + (image_cache->hit_count * 100) / op_count, + (image_cache->miss_count * 100) / op_count, + (image_cache->fail_count * 100) / op_count); + + slen += snprintf(string + slen, size - slen, + "
Cache total/hit/miss/fail (size) %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64" (100%%/%"PRIu64"%%/%"PRIu64"%%/%"PRIu64"%%)", + op_size, + image_cache->hit_size, + image_cache->miss_size, + image_cache->fail_size, + (image_cache->hit_size * 100) / op_size, + (image_cache->miss_size * 100) / op_size, + (image_cache->fail_size * 100) / op_size); + } + + slen += snprintf(string + slen, size - slen, + "
Total images never rendered: %d (includes %d that were converted)", + image_cache->total_unrendered, + image_cache->specultive_miss_count); + + slen += snprintf(string + slen, size - slen, + "
Total number of excessive conversions: %d (from %d images converted more than once)", + image_cache->total_extra_conversions, + image_cache->total_extra_conversions_count); + + slen += snprintf(string + slen, size - slen, + "
Bitmap of size %d had most (%d) conversions", + image_cache->peak_conversions_size, + image_cache->peak_conversions); + + return slen; +} + +/* exported interface documented in image_cache.h */ +int image_cache_snentryf(char *string, size_t size, unsigned int entryn, + const char *fmt) +{ + struct image_cache_entry_s *centry; + size_t slen = 0; /* current output string length */ + int fmtc = 0; /* current index into format string */ + + centry = image_cache__findn(entryn); + if (centry == NULL) + return -1; + + while((slen < size) && (fmt[fmtc] != 0)) { + if (fmt[fmtc] == '%') { + fmtc++; + switch (fmt[fmtc]) { + case 'e': + slen += snprintf(string + slen, size - slen, + "%d", entryn); + break; + + case 'r': + slen += snprintf(string + slen, size - slen, + "%u", centry->redraw_count); + break; + + case 'a': + slen += snprintf(string + slen, size - slen, + "%.2f", (float)((image_cache->current_age - centry->redraw_age)) / 1000); + break; + + + case 'c': + slen += snprintf(string + slen, size - slen, + "%d", centry->conversion_count); + break; + + case 'g': + slen += snprintf(string + slen, size - slen, + "%.2f", (float)((image_cache->current_age - centry->bitmap_age)) / 1000); + break; + + case 'k': + slen += snprintf(string + slen, size - slen, + "%p", centry->content); + break; + + case 's': + if (centry->bitmap != NULL) { + slen += snprintf(string + slen, + size - slen, + "%ld", + centry->bitmap_size); + } else { + slen += snprintf(string + slen, + size - slen, + "0"); + } + break; + } + fmtc++; + } else { + string[slen] = fmt[fmtc]; + slen++; + fmtc++; + } + } + + /* Ensure that we NUL-terminate the output */ + string[min(slen, size - 1)] = '\0'; + + return slen; +} + + /* exported interface documented in image_cache.h */ bool image_cache_redraw(struct content *c, struct content_redraw_data *data, diff --git a/image/image_cache.h b/image/image_cache.h index e879c740d..e1ae24e3a 100644 --- a/image/image_cache.h +++ b/image/image_cache.h @@ -96,7 +96,30 @@ struct bitmap *image_cache_find_bitmap(struct content *c); */ bool image_cache_speculate(struct content *c); -/* Image content handler generic cache callbacks */ +/** + * Fill a buffer with an option using a format. + * + * The format string is copied into the output buffer with the + * following replaced: + * %e - The entry number + * %k - The content key + * %r - The number of redraws of this bitmap + * %c - The number of times this bitmap has been converted + * %s - The size of the current bitmap allocation + * + * \param string The buffer in which to place the results. + * \param size The size of the string buffer. + * \param entryn The opaque entry number. + * \param fmt The format string. + * \return The number of bytes written to \a string or -1 on error + */ +int image_cache_snentryf(char *string, size_t size, unsigned int entryn, + const char *fmt); + +/** cache summary */ +int image_cache_snsummaryf(char *string, size_t size, const char *fmt); + +/********* Image content handler generic cache callbacks ************/ /** Generic content redraw callback *