add about:imagecache some of teh implementation needs cleaning up

svn path=/trunk/netsurf/; revision=13030
This commit is contained in:
Vincent Sanders 2011-10-10 22:41:31 +00:00
parent e1e88e5f98
commit 56e7b23415
3 changed files with 277 additions and 2 deletions

View File

@ -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,
"<html>\n<head>\n"
"<title>NetSurf Browser Image Cache Status</title>\n"
"<link rel=\"stylesheet\" type=\"text/css\" "
"href=\"resource:internal.css\">\n"
"</head>\n"
"<body id =\"cachelist\">\n"
"<p class=\"banner\">"
"<a href=\"http://www.netsurf-browser.org/\">"
"<img src=\"resource:netsurf.png\" alt=\"NetSurf\"></a>"
"</p>\n"
"<h1>NetSurf Browser Image Cache Status</h1>\n" );
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
slen, FETCH_ERROR_NO_ERROR))
goto fetch_about_imagecache_handler_aborted;
slen = image_cache_snsummaryf(buffer, sizeof(buffer), NULL);
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
slen, FETCH_ERROR_NO_ERROR))
goto fetch_about_imagecache_handler_aborted;
slen = snprintf(buffer, sizeof buffer,
"<table class=\"config\">\n"
"<tr><th>Entry</th><th>Content Key</th><th>Redraw Count</th><th>Conversion Count</th><th>Last Redraw</th><th>Bitmap Age</th><th>Bitmap Size</th></tr>\n");
do {
res = image_cache_snentryf(buffer + slen, sizeof buffer - slen,
cent_loop,
"<tr><td>%e</td><td>%k</td><td>%r</td><td>%c</td><td>%a</td><td>%g</td><td>%s</td></tr>\n");
if (res <= 0)
break; /* last option */
if (res >= (int) (sizeof buffer - slen)) {
/* last entry would not fit in buffer, submit buffer */
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer,
slen, FETCH_ERROR_NO_ERROR))
goto fetch_about_imagecache_handler_aborted;
slen = 0;
} else {
/* normal addition */
slen += res;
cent_loop++;
}
} while (res > 0);
slen += snprintf(buffer + slen, sizeof buffer - slen,
"</table>\n</body>\n</html>\n");
if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
FETCH_ERROR_NO_ERROR))
goto fetch_about_imagecache_handler_aborted;
fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
FETCH_ERROR_NO_ERROR);
return true;
fetch_about_imagecache_handler_aborted:
return false;
}
/** Handler to generate about:config page */
static bool fetch_about_config_handler(struct fetch_about_context *ctx)
{
char buffer[1024];
@ -226,6 +308,7 @@ fetch_about_config_handler_aborted:
return false;
}
/** Generate the text of a Choices file which represents the current
* in use options.
*/
@ -408,7 +491,9 @@ struct about_handlers about_handler_list[] = {
{ "testament", SLEN("testament"), NULL, fetch_about_testament_handler, false },
{ "about", SLEN("about"), NULL, fetch_about_about_handler, true },
{ "logo", SLEN("logo"), NULL, fetch_about_logo_handler, true },
/* The default */
/* details about the cache */
{ "imagecache", SLEN("iamgecache"), NULL, fetch_about_imagecache_handler, true },
/* The default blank page */
{ "blank", SLEN("blank"), NULL, fetch_about_blank_handler, true }
};

View File

@ -22,6 +22,7 @@
#include <string.h>
#include "utils/errors.h"
#include "utils/utils.h"
#include "utils/log.h"
#include "utils/config.h"
#include "utils/schedule.h"
@ -124,6 +125,20 @@ struct image_cache_s {
static struct image_cache_s *image_cache = NULL;
/** Find the nth cache entry
*/
static struct image_cache_entry_s *image_cache__findn(int entryn)
{
struct image_cache_entry_s *found;
found = image_cache->entries;
while ((found != NULL) && (entryn > 0)) {
entryn--;
found = found->next;
}
return found;
}
/** Find the cache entry for a content
*/
static struct image_cache_entry_s *image_cache__find(const struct content *c)
@ -511,6 +526,158 @@ nserror image_cache_remove(struct content *content)
return NSERROR_OK;
}
/* exported interface documented in image_cache.h */
int image_cache_snsummaryf(char *string, size_t size, const char *fmt)
{
size_t slen = 0; /* current output string length */
unsigned int op_count;
slen += snprintf(string + slen, size - slen,
"<p>Configured limit of %ld hysteresis of %ld",
image_cache->params.limit, image_cache->params.hysteresis);
slen += snprintf(string + slen, size - slen,
"<p>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,
"<p>Age %ds", image_cache->current_age / 1000);
slen += snprintf(string + slen, size - slen,
"<p>Peak size %ld (in %d)",
image_cache->max_bitmap_size,
image_cache->max_bitmap_size_count );
slen += snprintf(string + slen, size - slen,
"<p>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,
"<p>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,
"<p>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,
"<p>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,
"<p>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,
"<p>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,

View File

@ -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
*