116
116
if (!Config.onoff.digest_generation) {
117
117
store_digest = NULL;
118
debug(71, 3) ("Local cache digest generation disabled\n");
118
debugs(71, 3, "Local cache digest generation disabled");
122
122
store_digest = cacheDigestCreate(cap, Config.digest.bits_per_entry);
123
debug(71, 1) ("Local cache digest enabled; rebuild/rewrite every %d/%d sec\n",
124
(int) Config.digest.rebuild_period, (int) Config.digest.rewrite_period);
123
debugs(71, 1, "Local cache digest enabled; rebuild/rewrite every " <<
124
(int) Config.digest.rebuild_period << "/" <<
125
(int) Config.digest.rewrite_period << " sec");
125
127
memset(&sd_state, 0, sizeof(sd_state));
128
130
store_digest = NULL;
129
debug(71, 3) ("Local cache digest is 'off'\n");
131
debugs(71, 3, "Local cache digest is 'off'");
163
165
assert(entry && store_digest);
164
debug(71, 6) ("storeDigestDel: checking entry, key: %s\n",
165
entry->getMD5Text());
166
debugs(71, 6, "storeDigestDel: checking entry, key: " << entry->getMD5Text());
167
168
if (!EBIT_TEST(entry->flags, KEY_PRIVATE)) {
168
169
if (!cacheDigestTest(store_digest, (const cache_key *)entry->key)) {
169
170
sd_stats.del_lost_count++;
170
debug(71, 6) ("storeDigestDel: lost entry, key: %s url: %s\n",
171
entry->getMD5Text(), storeUrl(entry));
171
debugs(71, 6, "storeDigestDel: lost entry, key: " << entry->getMD5Text() << " url: " << entry->url() );
173
173
sd_stats.del_count++;
174
174
cacheDigestDel(store_digest, (const cache_key *)entry->key);
175
debug(71, 6) ("storeDigestDel: deled entry, key: %s\n",
176
entry->getMD5Text());
175
debugs(71, 6, "storeDigestDel: deled entry, key: " << entry->getMD5Text());
219
218
/* add some stats! XXX */
221
debug(71, 6) ("storeDigestAddable: checking entry, key: %s\n",
220
debugs(71, 6, "storeDigestAddable: checking entry, key: " << e->getMD5Text());
224
/* check various entry flags (mimics storeCheckCachable XXX) */
222
/* check various entry flags (mimics StoreEntry::checkCachable XXX) */
226
224
if (!EBIT_TEST(e->flags, ENTRY_CACHABLE)) {
227
debug(71, 6) ("storeDigestAddable: NO: not cachable\n");
225
debugs(71, 6, "storeDigestAddable: NO: not cachable");
231
229
if (EBIT_TEST(e->flags, KEY_PRIVATE)) {
232
debug(71, 6) ("storeDigestAddable: NO: private key\n");
230
debugs(71, 6, "storeDigestAddable: NO: private key");
236
234
if (EBIT_TEST(e->flags, ENTRY_NEGCACHED)) {
237
debug(71, 6) ("storeDigestAddable: NO: negative cached\n");
235
debugs(71, 6, "storeDigestAddable: NO: negative cached");
241
239
if (EBIT_TEST(e->flags, RELEASE_REQUEST)) {
242
debug(71, 6) ("storeDigestAddable: NO: release requested\n");
240
debugs(71, 6, "storeDigestAddable: NO: release requested");
246
244
if (e->store_status == STORE_OK && EBIT_TEST(e->flags, ENTRY_BAD_LENGTH)) {
247
debug(71, 6) ("storeDigestAddable: NO: wrong content-length\n");
245
debugs(71, 6, "storeDigestAddable: NO: wrong content-length");
251
249
/* do not digest huge objects */
252
250
if (e->swap_file_sz > Config.Store.maxObjectSize) {
253
debug(71, 6) ("storeDigestAddable: NO: too big\n");
251
debugs(71, 6, "storeDigestAddable: NO: too big");
257
255
/* still here? check staleness */
258
256
/* Note: We should use the time of the next rebuild, not (cur_time+period) */
259
257
if (refreshCheckDigest(e, Config.digest.rebuild_period)) {
260
debug(71, 6) ("storeDigestAdd: entry expires within %d secs, ignoring\n",
261
(int) Config.digest.rebuild_period);
258
debugs(71, 6, "storeDigestAdd: entry expires within " << Config.digest.rebuild_period << " secs, ignoring");
294
285
cacheDigestAdd(store_digest, (const cache_key *)entry->key);
296
debug(71, 6) ("storeDigestAdd: added entry, key: %s\n",
297
entry->getMD5Text());
287
debugs(71, 6, "storeDigestAdd: added entry, key: " << entry->getMD5Text());
299
289
sd_stats.rej_count++;
311
301
/* prevent overlapping if rebuild schedule is too tight */
313
303
if (sd_state.rebuild_lock) {
314
debug(71, 1) ("storeDigestRebuildStart: overlap detected, consider increasing rebuild period\n");
304
debugs(71, 1, "storeDigestRebuildStart: overlap detected, consider increasing rebuild period");
318
308
sd_state.rebuild_lock = 1;
319
debug(71, 2) ("storeDigestRebuildStart: rebuild #%d\n", sd_state.rebuild_count + 1);
309
debugs(71, 2, "storeDigestRebuildStart: rebuild #" << sd_state.rebuild_count + 1);
321
311
if (sd_state.rewrite_lock) {
322
debug(71, 2) ("storeDigestRebuildStart: waiting for Rewrite to finish.\n");
312
debugs(71, 2, "storeDigestRebuildStart: waiting for Rewrite to finish.");
350
340
assert(sd_state.rebuild_lock);
351
341
sd_state.rebuild_lock = 0;
352
342
sd_state.rebuild_count++;
353
debug(71, 2) ("storeDigestRebuildFinish: done.\n");
343
debugs(71, 2, "storeDigestRebuildFinish: done.");
354
344
eventAdd("storeDigestRebuildStart", storeDigestRebuildStart, NULL, (double)
355
345
Config.digest.rebuild_period, 1);
356
346
/* resume pending Rewrite if any */
368
358
(double) Config.digest.rebuild_chunk_percentage / 100.0);
369
359
assert(sd_state.rebuild_lock);
371
debug(71, 3) ("storeDigestRebuildStep: buckets: %d entries to check: %d\n",
372
store_hash_buckets, count);
361
debugs(71, 3, "storeDigestRebuildStep: buckets: " << store_hash_buckets << " entries to check: " << count);
374
363
while (count-- && !sd_state.theSearch->isDone() && sd_state.theSearch->next())
375
364
storeDigestAdd(sd_state.theSearch->currentItem());
394
383
/* prevent overlapping if rewrite schedule is too tight */
396
385
if (sd_state.rewrite_lock) {
397
debug(71, 1) ("storeDigestRewrite: overlap detected, consider increasing rewrite period\n");
386
debugs(71, 1, "storeDigestRewrite: overlap detected, consider increasing rewrite period");
401
debug(71, 2) ("storeDigestRewrite: start rewrite #%d\n", sd_state.rewrite_count + 1);
390
debugs(71, 2, "storeDigestRewrite: start rewrite #" << sd_state.rewrite_count + 1);
402
391
/* make new store entry */
403
392
url = internalLocalUri("/squid-internal-periodic/", StoreDigestFileName);
404
393
flags.cachable = 1;
405
394
e = storeCreateEntry(url, url, flags, METHOD_GET);
407
396
sd_state.rewrite_lock = e;
408
debug(71, 3) ("storeDigestRewrite: url: %s key: %s\n", url, e->getMD5Text());
397
debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text());
409
398
HttpRequest *req = HttpRequest::CreateFromUrl(url);
410
399
e->mem_obj->request = HTTPMSGLOCK(req);
411
400
/* wait for rebuild (if any) to finish */
413
402
if (sd_state.rebuild_lock) {
414
debug(71, 2) ("storeDigestRewriteStart: waiting for rebuild to finish.\n");
403
debugs(71, 2, "storeDigestRewriteStart: waiting for rebuild to finish.");
429
418
sd_state.rewrite_offset = 0;
430
419
EBIT_SET(e->flags, ENTRY_SPECIAL);
431
420
/* setting public key will purge old digest entry if any */
432
storeSetPublicKey(e);
434
423
HttpReply *rep = new HttpReply;
435
424
HttpVersion version(1, 0);
436
425
rep->setHeaders(version, HTTP_OK, "Cache Digest OK",
437
426
"application/cache-digest", store_digest->mask_size + sizeof(sd_state.cblock),
438
427
squid_curtime, squid_curtime + Config.digest.rewrite_period);
439
debug(71, 3) ("storeDigestRewrite: entry expires on %ld (%+d)\n",
440
(long int) rep->expires, (int) (rep->expires - squid_curtime));
428
debugs(71, 3, "storeDigestRewrite: entry expires on " << rep->expires <<
429
" (" << std::showpos << (int) (rep->expires - squid_curtime) << ")");
442
431
e->replaceHttpReply(rep);
443
432
storeDigestCBlockSwapOut(e);
445
434
eventAdd("storeDigestSwapOutStep", storeDigestSwapOutStep, sd_state.rewrite_lock, 0.0, 1, false);
452
441
assert(e == sd_state.rewrite_lock);
454
storeTimestampsSet(e);
455
debug(71, 2) ("storeDigestRewriteFinish: digest expires at %ld (%+d)\n",
456
(long int) e->expires, (int) (e->expires - squid_curtime));
444
debugs(71, 2, "storeDigestRewriteFinish: digest expires at " << e->expires <<
445
" (" << std::showpos << (int) (e->expires - squid_curtime) << ")");
457
446
/* is this the write order? @?@ */
458
447
e->mem_obj->unlinkRequest();
480
469
if ((size_t)(sd_state.rewrite_offset + chunk_size) > store_digest->mask_size)
481
470
chunk_size = store_digest->mask_size - sd_state.rewrite_offset;
483
storeAppend(e, store_digest->mask + sd_state.rewrite_offset, chunk_size);
472
e->append(store_digest->mask + sd_state.rewrite_offset, chunk_size);
485
474
debugs(71, 3, "storeDigestSwapOutStep: size: " << store_digest->mask_size <<
486
475
" offset: " << sd_state.rewrite_offset << " chunk: " <<
508
497
sd_state.cblock.bits_per_entry = (unsigned char)
509
498
Config.digest.bits_per_entry;
510
499
sd_state.cblock.hash_func_count = (unsigned char) CacheDigestHashFuncCount;
511
storeAppend(e, (char *) &sd_state.cblock, sizeof(sd_state.cblock));
500
e->append((char *) &sd_state.cblock, sizeof(sd_state.cblock));
514
503
/* calculates digest capacity */
524
513
const int lo_cap = 1 + store_swap_size / Config.Store.avgObjectSize;
525
514
const int e_count = StoreEntry::inUseCount();
526
515
int cap = e_count ? e_count : hi_cap;
527
debug(71, 2) ("storeDigestCalcCap: have: %d, want %d entries; limits: [%d, %d]\n",
528
e_count, cap, lo_cap, hi_cap);
516
debugs(71, 2, "storeDigestCalcCap: have: " << e_count << ", want " << cap <<
517
" entries; limits: [" << lo_cap << ", " << hi_cap << "]");
530
519
if (cap < lo_cap)
546
535
assert(store_digest);
547
536
diff = abs(cap - store_digest->capacity);
548
debug(71, 2) ("storeDigestResize: %d -> %d; change: %d (%d%%)\n",
549
store_digest->capacity, cap, diff,
550
xpercentInt(diff, store_digest->capacity));
537
debugs(71, 2, "storeDigestResize: " <<
538
store_digest->capacity << " -> " << cap << "; change: " <<
539
diff << " (" << xpercentInt(diff, store_digest->capacity) << "%)" );
551
540
/* avoid minor adjustments */
553
542
if (diff <= store_digest->capacity / 10) {
554
debug(71, 2) ("storeDigestResize: small change, will not resize.\n");
543
debugs(71, 2, "storeDigestResize: small change, will not resize.");
557
debug(71, 2) ("storeDigestResize: big change, resizing.\n");
546
debugs(71, 2, "storeDigestResize: big change, resizing.");
558
547
cacheDigestChangeCap(store_digest, cap);