]> git.ipfire.org Git - thirdparty/squid.git/blame - src/refresh.cc
Use InstanceId for async job and calls identification.
[thirdparty/squid.git] / src / refresh.cc
CommitLineData
e4e6a8db 1
2/*
262a0e14 3 * $Id$
e4e6a8db 4 *
5 * DEBUG: section 22 Refresh Calculation
6 * AUTHOR: Harvest Derived
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
e4e6a8db 10 *
2b6662ba 11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
e4e6a8db 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
26ac0430 24 *
e4e6a8db 25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
26ac0430 29 *
e4e6a8db 30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
e4e6a8db 34 */
35
36#ifndef USE_POSIX_REGEX
37#define USE_POSIX_REGEX /* put before includes; always use POSIX */
38#endif
39
40#include "squid.h"
62ee09ca 41#include "CacheManager.h"
e6ccf245 42#include "Store.h"
528b2c61 43#include "MemObject.h"
a2ac85d9 44#include "HttpRequest.h"
924f73bc 45#include "HttpReply.h"
985c86bc 46#include "SquidTime.h"
e4e6a8db 47
7d47d8e6 48typedef enum {
65fa5c61 49 rcHTTP,
50 rcICP,
51#if USE_HTCP
52 rcHTCP,
53#endif
54#if USE_CACHE_DIGESTS
55 rcCDigest,
56#endif
57 rcStore,
58 rcCount
7d47d8e6 59} refreshCountsEnum;
829a9357 60
26ac0430 61typedef struct {
1f848b2c 62 bool expires;
63 bool min;
64 bool lmfactor;
65 bool max;
2fadd50d 66} stale_flags;
65fa5c61 67
68/*
69 * This enumerated list assigns specific values, ala HTTP/FTP status
70 * codes. All Fresh codes are in the range 100-199 and all stale
71 * codes are 200-299. We might want to use these codes in logging,
72 * so best to keep them consistent over time.
73 */
74enum {
75 FRESH_REQUEST_MAX_STALE_ALL = 100,
76 FRESH_REQUEST_MAX_STALE_VALUE,
77 FRESH_EXPIRES,
78 FRESH_LMFACTOR_RULE,
79 FRESH_MIN_RULE,
80 FRESH_OVERRIDE_EXPIRES,
81 FRESH_OVERRIDE_LASTMOD,
82 STALE_MUST_REVALIDATE = 200,
83 STALE_RELOAD_INTO_IMS,
84 STALE_FORCED_RELOAD,
85 STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE,
86 STALE_EXPIRES,
87 STALE_MAX_RULE,
88 STALE_LMFACTOR_RULE,
89 STALE_DEFAULT = 299
90};
91
26ac0430 92static struct RefreshCounts {
829a9357 93 const char *proto;
1c3e77cd 94 int total;
65fa5c61 95 int status[STALE_DEFAULT + 1];
62e76326 96}
97
98refreshCounts[rcCount];
1c3e77cd 99
e4e6a8db 100/*
101 * Defaults:
102 * MIN NONE
103 * PCT 20%
104 * MAX 3 days
105 */
48f44632 106#define REFRESH_DEFAULT_MIN (time_t)0
c3f6d204 107#define REFRESH_DEFAULT_PCT 0.20
48f44632 108#define REFRESH_DEFAULT_MAX (time_t)259200
e4e6a8db 109
2b5133db 110static const refresh_t *refreshUncompiledPattern(const char *);
1c3e77cd 111static OBJH refreshStats;
efd62b86 112static int refreshStaleness(const StoreEntry * entry, time_t check_time, const time_t age, const refresh_t * R, stale_flags * sf);
65fa5c61 113
114static refresh_t DefaultRefresh;
2b5133db 115
38f9c547 116const refresh_t *
6018f0de 117refreshLimits(const char *url)
118{
119 const refresh_t *R;
62e76326 120
6018f0de 121 for (R = Config.Refresh; R; R = R->next) {
62e76326 122 if (!regexec(&(R->compiled_pattern), url, 0, 0, 0))
123 return R;
6018f0de 124 }
62e76326 125
6018f0de 126 return NULL;
127}
128
2b5133db 129static const refresh_t *
130refreshUncompiledPattern(const char *pat)
131{
132 const refresh_t *R;
62e76326 133
2b5133db 134 for (R = Config.Refresh; R; R = R->next) {
62e76326 135 if (0 == strcmp(R->pattern, pat))
136 return R;
2b5133db 137 }
62e76326 138
2b5133db 139 return NULL;
140}
141
b2f01ec3 142/**
65fa5c61 143 * Calculate how stale the response is (or will be at the check_time).
144 * Staleness calculation is based on the following: (1) response
145 * expiration time, (2) age greater than configured maximum, (3)
146 * last-modified factor, and (4) age less than configured minimum.
147 *
b2f01ec3
AJ
148 * \retval -1 If the response is fresh.
149 * \retval >0 Otherwise return it's staleness.
150 * \retval 0 NOTE return value of 0 means the response is stale.
65fa5c61 151 *
152 * The 'stale_flags' structure is used to tell the calling function
153 * _why_ this response is fresh or stale. Its used, for example,
154 * when the admin wants to override expiration and last-modified
155 * times.
156 */
157static int
efd62b86 158refreshStaleness(const StoreEntry * entry, time_t check_time, const time_t age, const refresh_t * R, stale_flags * sf)
65fa5c61 159{
b2f01ec3
AJ
160 /** \par
161 * Check for an explicit expiration time (Expires: header).
65fa5c61 162 */
163 if (entry->expires > -1) {
1f848b2c 164 sf->expires = true;
62e76326 165
166 if (entry->expires > check_time) {
4a7a3d56 167 debugs(22, 3, "FRESH: expires " << entry->expires <<
168 " >= check_time " << check_time << " ");
bf8fe701 169
62e76326 170 return -1;
171 } else {
4a7a3d56 172 debugs(22, 3, "STALE: expires " << entry->expires <<
173 " < check_time " << check_time << " ");
bf8fe701 174
62e76326 175 return (check_time - entry->expires);
176 }
65fa5c61 177 }
62e76326 178
b2f01ec3 179 /** \par
65fa5c61 180 * Use local heuristics to determine staleness. Start with the
181 * max age from the refresh_pattern rule.
182 */
183 if (age > R->max) {
4a7a3d56 184 debugs(22, 3, "STALE: age " << age << " > max " << R->max << " ");
1f848b2c 185 sf->max = true;
62e76326 186 return (age - R->max);
65fa5c61 187 }
62e76326 188
b2f01ec3
AJ
189 /** \par
190 * Try the last-modified factor algorithm: refresh_pattern n% percentage of Last-Modified: age.
65fa5c61 191 */
192 if (entry->lastmod > -1 && entry->timestamp > entry->lastmod) {
62e76326 193 /*
194 * stale_age is the Age of the response when it became/becomes
195 * stale according to the last-modified factor algorithm.
196 */
197 time_t stale_age = static_cast<time_t>((entry->timestamp - entry->lastmod) * R->pct);
1f848b2c 198 sf->lmfactor = true;
62e76326 199
200 if (age >= stale_age) {
4a7a3d56 201 debugs(22, 3, "STALE: age " << age << " > stale_age " << stale_age);
62e76326 202 return (age - stale_age);
203 } else {
4a7a3d56 204 debugs(22, 3, "FRESH: age " << age << " <= stale_age " << stale_age);
62e76326 205 return -1;
206 }
65fa5c61 207 }
62e76326 208
b2f01ec3
AJ
209 /** \par
210 * Finally, if all else fails; staleness is determined by the refresh_pattern
65fa5c61 211 * configured minimum age.
212 */
9e4b5932 213 if (age < R->min) {
214 debugs(22, 3, "FRESH: age " << age << " < min " << R->min);
1f848b2c 215 sf->min = true;
62e76326 216 return -1;
65fa5c61 217 }
62e76326 218
9e4b5932 219 debugs(22, 3, "STALE: age " << age << " >= min " << R->min);
65fa5c61 220 return (age - R->min);
221}
222
b2f01ec3
AJ
223/**
224 * \retval 1 if the entry must be revalidated within delta seconds
225 * \retval 0 otherwise
829a9357 226 *
227 * note: request maybe null (e.g. for cache digests build)
e4e6a8db 228 */
829a9357 229static int
190154cf 230refreshCheck(const StoreEntry * entry, HttpRequest * request, time_t delta)
e4e6a8db 231{
6018f0de 232 const refresh_t *R;
829a9357 233 const char *uri = NULL;
65fa5c61 234 time_t age = 0;
a207429f 235 time_t check_time = squid_curtime + delta;
65fa5c61 236 int staleness;
237 stale_flags sf;
62e76326 238
9b5d1d21 239 if (entry->mem_obj)
62e76326 240 uri = entry->mem_obj->url;
7d47d8e6 241 else if (request)
62e76326 242 uri = urlCanonical(request);
7d47d8e6 243
bf8fe701 244 debugs(22, 3, "refreshCheck: '" << (uri ? uri : "<none>") << "'");
65fa5c61 245
246 if (check_time > entry->timestamp)
62e76326 247 age = check_time - entry->timestamp;
248
efd62b86 249 // FIXME: what to do when age < 0 or counter overflow?
b2f01ec3 250 assert(age >= 0);
efd62b86 251
65fa5c61 252 R = uri ? refreshLimits(uri) : refreshUncompiledPattern(".");
62e76326 253
65fa5c61 254 if (NULL == R)
62e76326 255 R = &DefaultRefresh;
256
65fa5c61 257 memset(&sf, '\0', sizeof(sf));
62e76326 258
65fa5c61 259 staleness = refreshStaleness(entry, check_time, age, R, &sf);
62e76326 260
bf8fe701 261 debugs(22, 3, "Staleness = " << staleness);
262
263 debugs(22, 3, "refreshCheck: Matched '" << R->pattern << " " <<
264 (int) R->min << " " << (int) (100.0 * R->pct) << "%% " <<
265 (int) R->max << "'");
65fa5c61 266
62e76326 267
4a7a3d56 268 debugs(22, 3, "refreshCheck: age = " << age);
62e76326 269
bf8fe701 270 debugs(22, 3, "\tcheck_time:\t" << mkrfc1123(check_time));
62e76326 271
bf8fe701 272 debugs(22, 3, "\tentry->timestamp:\t" << mkrfc1123(entry->timestamp));
65fa5c61 273
4ca08219 274 if (EBIT_TEST(entry->flags, ENTRY_REVALIDATE) && staleness > -1
626096be 275#if USE_HTTP_VIOLATIONS
04f7fd38 276 && !R->flags.ignore_must_revalidate
4ca08219 277#endif
04f7fd38 278 ) {
bf8fe701 279 debugs(22, 3, "refreshCheck: YES: Must revalidate stale response");
7948b784 280 request->flags.fail_on_validation_err = 1;
62e76326 281 return STALE_MUST_REVALIDATE;
65fa5c61 282 }
62e76326 283
829a9357 284 /* request-specific checks */
432bc83c 285 if (request && !request->flags.ignore_cc) {
62e76326 286 HttpHdrCc *cc = request->cache_control;
4c3ef9b2 287
288 if (request->flags.ims && (R->flags.refresh_ims || Config.onoff.refresh_all_ims)) {
289 /* The clients no-cache header is changed into a IMS query */
bf8fe701 290 debugs(22, 3, "refreshCheck: YES: refresh-ims");
4c3ef9b2 291 return STALE_FORCED_RELOAD;
292 }
293
626096be 294#if USE_HTTP_VIOLATIONS
62e76326 295
296 if (!request->flags.nocache_hack) {
297 (void) 0;
298 } else if (R->flags.ignore_reload) {
299 /* The clients no-cache header is ignored */
bf8fe701 300 debugs(22, 3, "refreshCheck: MAYBE: ignore-reload");
62e76326 301 } else if (R->flags.reload_into_ims || Config.onoff.reload_into_ims) {
302 /* The clients no-cache header is changed into a IMS query */
bf8fe701 303 debugs(22, 3, "refreshCheck: YES: reload-into-ims");
62e76326 304 return STALE_RELOAD_INTO_IMS;
305 } else {
306 /* The clients no-cache header is not overridden on this request */
bf8fe701 307 debugs(22, 3, "refreshCheck: YES: client reload");
62e76326 308 request->flags.nocache = 1;
309 return STALE_FORCED_RELOAD;
310 }
311
9f60cfdf 312#endif
62e76326 313 if (NULL != cc) {
314 if (cc->max_age > -1) {
626096be 315#if USE_HTTP_VIOLATIONS
62e76326 316 if (R->flags.ignore_reload && cc->max_age == 0) {} else
528b2c61 317#endif
62e76326 318 {
528b2c61 319#if 0
62e76326 320
321 if (cc->max_age == 0) {
bf8fe701 322 debugs(22, 3, "refreshCheck: YES: client-max-age = 0");
62e76326 323 return STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE;
324 }
325
085008f9 326#endif
62e76326 327 if (age > cc->max_age) {
bf8fe701 328 debugs(22, 3, "refreshCheck: YES: age > client-max-age");
62e76326 329 return STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE;
330 }
331 }
332 }
333
334 if (EBIT_TEST(cc->mask, CC_MAX_STALE) && staleness > -1) {
335 if (cc->max_stale < 0) {
336 /* max-stale directive without a value */
bf8fe701 337 debugs(22, 3, "refreshCheck: NO: max-stale wildcard");
62e76326 338 return FRESH_REQUEST_MAX_STALE_ALL;
339 } else if (staleness < cc->max_stale) {
bf8fe701 340 debugs(22, 3, "refreshCheck: NO: staleness < max-stale");
62e76326 341 return FRESH_REQUEST_MAX_STALE_VALUE;
342 }
343 }
344 }
48f44632 345 }
62e76326 346
65fa5c61 347 if (-1 == staleness) {
bf8fe701 348 debugs(22, 3, "refreshCheck: object isn't stale..");
ed1de692 349 if (sf.expires) {
bf8fe701 350 debugs(22, 3, "refreshCheck: returning FRESH_EXPIRES");
62e76326 351 return FRESH_EXPIRES;
26ac0430 352 }
62e76326 353
354 assert(!sf.max);
355
ed1de692 356 if (sf.lmfactor) {
bf8fe701 357 debugs(22, 3, "refreshCheck: returning FRESH_LMFACTOR_RULE");
62e76326 358 return FRESH_LMFACTOR_RULE;
26ac0430 359 }
62e76326 360
361 assert(sf.min);
362
bf8fe701 363 debugs(22, 3, "refreshCheck: returning FRESH_MIN_RULE");
62e76326 364 return FRESH_MIN_RULE;
1dfa1d81 365 }
62e76326 366
65fa5c61 367 /*
368 * At this point the response is stale, unless one of
542c4d60 369 * the override options kicks in.
65fa5c61 370 */
371 if (sf.expires) {
626096be 372#if USE_HTTP_VIOLATIONS
62e76326 373
374 if (R->flags.override_expire && age < R->min) {
bf8fe701 375 debugs(22, 3, "refreshCheck: NO: age < min && override-expire");
62e76326 376 return FRESH_OVERRIDE_EXPIRES;
377 }
378
65fa5c61 379#endif
62e76326 380 return STALE_EXPIRES;
e4e6a8db 381 }
62e76326 382
65fa5c61 383 if (sf.max)
62e76326 384 return STALE_MAX_RULE;
385
65fa5c61 386 if (sf.lmfactor) {
626096be 387#if USE_HTTP_VIOLATIONS
62e76326 388
389 if (R->flags.override_lastmod && age < R->min) {
bf8fe701 390 debugs(22, 3, "refreshCheck: NO: age < min && override-lastmod");
62e76326 391 return FRESH_OVERRIDE_LASTMOD;
392 }
393
65fa5c61 394#endif
62e76326 395 return STALE_LMFACTOR_RULE;
e4e6a8db 396 }
62e76326 397
bf8fe701 398 debugs(22, 3, "refreshCheck: returning STALE_DEFAULT");
65fa5c61 399 return STALE_DEFAULT;
e4e6a8db 400}
48f44632 401
cfa9f1cb 402int
403refreshIsCachable(const StoreEntry * entry)
404{
405 /*
406 * Don't look at the request to avoid no-cache and other nuisances.
407 * the object should have a mem_obj so the URL will be found there.
26ac0430
AJ
408 * minimum_expiry_time seconds delta (defaults to 60 seconds), to
409 * avoid objects which expire almost immediately, and which can't
6a2f3fcf 410 * be refreshed.
cfa9f1cb 411 */
6a2f3fcf 412 int reason = refreshCheck(entry, NULL, Config.minimum_expiry_time);
65fa5c61 413 refreshCounts[rcStore].total++;
414 refreshCounts[rcStore].status[reason]++;
62e76326 415
451c8350 416 if (reason < STALE_MUST_REVALIDATE)
62e76326 417 /* Does not need refresh. This is certainly cachable */
418 return 1;
419
cfa9f1cb 420 if (entry->lastmod < 0)
62e76326 421 /* Last modified is needed to do a refresh */
422 return 0;
423
cfa9f1cb 424 if (entry->mem_obj == NULL)
62e76326 425 /* no mem_obj? */
426 return 1;
427
528b2c61 428 if (entry->getReply() == NULL)
62e76326 429 /* no reply? */
430 return 1;
431
528b2c61 432 if (entry->getReply()->content_length == 0)
62e76326 433 /* No use refreshing (caching?) 0 byte objects */
434 return 0;
435
cfa9f1cb 436 /* This seems to be refreshable. Cache it */
437 return 1;
438}
439
829a9357 440/* refreshCheck... functions below are protocol-specific wrappers around
441 * refreshCheck() function above */
442
443int
190154cf 444refreshCheckHTTP(const StoreEntry * entry, HttpRequest * request)
7d47d8e6 445{
65fa5c61 446 int reason = refreshCheck(entry, request, 0);
447 refreshCounts[rcHTTP].total++;
448 refreshCounts[rcHTTP].status[reason]++;
449 return (reason < 200) ? 0 : 1;
829a9357 450}
451
452int
190154cf 453refreshCheckICP(const StoreEntry * entry, HttpRequest * request)
7d47d8e6 454{
65fa5c61 455 int reason = refreshCheck(entry, request, 30);
456 refreshCounts[rcICP].total++;
457 refreshCounts[rcICP].status[reason]++;
458 return (reason < 200) ? 0 : 1;
829a9357 459}
460
65fa5c61 461#if USE_HTCP
32b3cf93 462int
190154cf 463refreshCheckHTCP(const StoreEntry * entry, HttpRequest * request)
32b3cf93 464{
65fa5c61 465 int reason = refreshCheck(entry, request, 10);
466 refreshCounts[rcHTCP].total++;
467 refreshCounts[rcHTCP].status[reason]++;
468 return (reason < 200) ? 0 : 1;
32b3cf93 469}
62e76326 470
65fa5c61 471#endif
32b3cf93 472
65fa5c61 473#if USE_CACHE_DIGESTS
829a9357 474int
7d47d8e6 475refreshCheckDigest(const StoreEntry * entry, time_t delta)
476{
65fa5c61 477 int reason = refreshCheck(entry,
62e76326 478 entry->mem_obj ? entry->mem_obj->request : NULL,
479 delta);
65fa5c61 480 refreshCounts[rcCDigest].total++;
481 refreshCounts[rcCDigest].status[reason]++;
482 return (reason < 200) ? 0 : 1;
6018f0de 483}
62e76326 484
65fa5c61 485#endif
6018f0de 486
48f44632 487time_t
488getMaxAge(const char *url)
489{
6018f0de 490 const refresh_t *R;
bf8fe701 491 debugs(22, 3, "getMaxAge: '" << url << "'");
62e76326 492
6018f0de 493 if ((R = refreshLimits(url)))
62e76326 494 return R->max;
6018f0de 495 else
62e76326 496 return REFRESH_DEFAULT_MAX;
48f44632 497}
1c3e77cd 498
829a9357 499static void
62e76326 500
829a9357 501refreshCountsStats(StoreEntry * sentry, struct RefreshCounts *rc)
502{
cc7cfa8e 503 int sum = 0;
504 int tot = rc->total;
505
829a9357 506 storeAppendPrintf(sentry, "\n\n%s histogram:\n", rc->proto);
65fa5c61 507 storeAppendPrintf(sentry, "Count\t%%Total\tCategory\n");
829a9357 508
65fa5c61 509#define refreshCountsStatsEntry(code,desc) { \
510 storeAppendPrintf(sentry, "%6d\t%6.2f\t%s\n", \
511 rc->status[code], xpercent(rc->status[code], tot), desc); \
512 sum += rc->status[code]; \
cc7cfa8e 513}
65fa5c61 514
515 refreshCountsStatsEntry(FRESH_REQUEST_MAX_STALE_ALL,
62e76326 516 "Fresh: request max-stale wildcard");
65fa5c61 517 refreshCountsStatsEntry(FRESH_REQUEST_MAX_STALE_VALUE,
62e76326 518 "Fresh: request max-stale value");
65fa5c61 519 refreshCountsStatsEntry(FRESH_EXPIRES,
62e76326 520 "Fresh: expires time not reached");
65fa5c61 521 refreshCountsStatsEntry(FRESH_LMFACTOR_RULE,
62e76326 522 "Fresh: refresh_pattern last-mod factor percentage");
65fa5c61 523 refreshCountsStatsEntry(FRESH_MIN_RULE,
62e76326 524 "Fresh: refresh_pattern min value");
65fa5c61 525 refreshCountsStatsEntry(FRESH_OVERRIDE_EXPIRES,
62e76326 526 "Fresh: refresh_pattern override expires");
65fa5c61 527 refreshCountsStatsEntry(FRESH_OVERRIDE_LASTMOD,
62e76326 528 "Fresh: refresh_pattern override lastmod");
65fa5c61 529 refreshCountsStatsEntry(STALE_MUST_REVALIDATE,
62e76326 530 "Stale: response has must-revalidate");
65fa5c61 531 refreshCountsStatsEntry(STALE_RELOAD_INTO_IMS,
62e76326 532 "Stale: changed reload into IMS");
65fa5c61 533 refreshCountsStatsEntry(STALE_FORCED_RELOAD,
62e76326 534 "Stale: request has no-cache directive");
65fa5c61 535 refreshCountsStatsEntry(STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE,
62e76326 536 "Stale: age exceeds request max-age value");
65fa5c61 537 refreshCountsStatsEntry(STALE_EXPIRES,
62e76326 538 "Stale: expires time reached");
65fa5c61 539 refreshCountsStatsEntry(STALE_MAX_RULE,
62e76326 540 "Stale: refresh_pattern max age rule");
65fa5c61 541 refreshCountsStatsEntry(STALE_LMFACTOR_RULE,
62e76326 542 "Stale: refresh_pattern last-mod factor percentage");
65fa5c61 543 refreshCountsStatsEntry(STALE_DEFAULT,
62e76326 544 "Stale: by default");
65fa5c61 545
7d47d8e6 546 tot = sum; /* paranoid: "total" line shows 100% if we forgot nothing */
65fa5c61 547 storeAppendPrintf(sentry, "%6d\t%6.2f\tTOTAL\n",
62e76326 548 rc->total, xpercent(rc->total, tot));
65fa5c61 549 \
62e76326 550 storeAppendPrintf(sentry, "\n");
829a9357 551}
552
1c3e77cd 553static void
554refreshStats(StoreEntry * sentry)
555{
829a9357 556 int i;
557 int total = 0;
558
559 /* get total usage count */
62e76326 560
829a9357 561 for (i = 0; i < rcCount; ++i)
62e76326 562 total += refreshCounts[i].total;
829a9357 563
564 /* protocol usage histogram */
565 storeAppendPrintf(sentry, "\nRefreshCheck calls per protocol\n\n");
62e76326 566
829a9357 567 storeAppendPrintf(sentry, "Protocol\t#Calls\t%%Calls\n");
62e76326 568
829a9357 569 for (i = 0; i < rcCount; ++i)
62e76326 570 storeAppendPrintf(sentry, "%10s\t%6d\t%6.2f\n",
571 refreshCounts[i].proto,
572 refreshCounts[i].total,
573 xpercent(refreshCounts[i].total, total));
829a9357 574
575 /* per protocol histograms */
576 storeAppendPrintf(sentry, "\n\nRefreshCheck histograms for various protocols\n");
62e76326 577
829a9357 578 for (i = 0; i < rcCount; ++i)
62e76326 579 refreshCountsStats(sentry, &refreshCounts[i]);
1c3e77cd 580}
581
5f5e883f
FC
582static void
583refreshRegisterWithCacheManager(void)
584{
585 CacheManager::GetInstance()->
26ac0430 586 registerAction("refresh", "Refresh Algorithm Statistics", refreshStats, 0, 1);
5f5e883f
FC
587}
588
1c3e77cd 589void
9bc73deb 590refreshInit(void)
1c3e77cd 591{
829a9357 592 memset(refreshCounts, 0, sizeof(refreshCounts));
593 refreshCounts[rcHTTP].proto = "HTTP";
594 refreshCounts[rcICP].proto = "ICP";
65fa5c61 595#if USE_HTCP
62e76326 596
32b3cf93 597 refreshCounts[rcHTCP].proto = "HTCP";
65fa5c61 598#endif
62e76326 599
cfa9f1cb 600 refreshCounts[rcStore].proto = "On Store";
65fa5c61 601#if USE_CACHE_DIGESTS
62e76326 602
829a9357 603 refreshCounts[rcCDigest].proto = "Cache Digests";
65fa5c61 604#endif
62e76326 605
65fa5c61 606 memset(&DefaultRefresh, '\0', sizeof(DefaultRefresh));
607 DefaultRefresh.pattern = "<none>";
608 DefaultRefresh.min = REFRESH_DEFAULT_MIN;
609 DefaultRefresh.pct = REFRESH_DEFAULT_PCT;
610 DefaultRefresh.max = REFRESH_DEFAULT_MAX;
d120ed12
FC
611
612 refreshRegisterWithCacheManager();
1c3e77cd 613}