/*
- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
class StoreDigestState
{
-
public:
StoreDigestCBlock cblock;
- int rebuild_lock; /* bucket number */
- StoreEntry * rewrite_lock; /* points to store entry with the digest */
+ int rebuild_lock = 0; ///< bucket number
+ StoreEntry * rewrite_lock = nullptr; ///< points to store entry with the digest
+ StoreEntry * publicEntry = nullptr; ///< points to the previous store entry with the digest
StoreSearchPointer theSearch;
- int rewrite_offset;
- int rebuild_count;
- int rewrite_count;
+ int rewrite_offset = 0;
+ int rebuild_count = 0;
+ int rewrite_count = 0;
};
-typedef struct {
- int del_count; /* #store entries deleted from store_digest */
- int del_lost_count; /* #store entries not found in store_digest on delete */
- int add_count; /* #store entries accepted to store_digest */
- int add_coll_count; /* #accepted entries that collided with existing ones */
- int rej_count; /* #store entries not accepted to store_digest */
- int rej_coll_count; /* #not accepted entries that collided with existing ones */
-} StoreDigestStats;
+class StoreDigestStats
+{
+public:
+ int del_count = 0; /* #store entries deleted from store_digest */
+ int del_lost_count = 0; /* #store entries not found in store_digest on delete */
+ int add_count = 0; /* #store entries accepted to store_digest */
+ int add_coll_count = 0; /* #accepted entries that collided with existing ones */
+ int rej_count = 0; /* #store entries not accepted to store_digest */
+ int rej_coll_count = 0; /* #not accepted entries that collided with existing ones */
+};
/* local vars */
static StoreDigestState sd_state;
static void storeDigestCBlockSwapOut(StoreEntry * e);
static void storeDigestAdd(const StoreEntry *);
-static void
-storeDigestRegisterWithCacheManager(void)
-{
- Mgr::RegisterAction("store_digest", "Store Digest", storeDigestReport, 0, 1);
-}
-
/// calculates digest capacity
static uint64_t
storeDigestCalcCap()
// this matches cacheDigestCalcMaskSize doing (cap*bpe)+7 < INT_MAX
const uint64_t absolute_max = (INT_MAX -8) / Config.digest.bits_per_entry;
if (cap > absolute_max) {
- debugs(71, DBG_CRITICAL, "WARNING: Cache Digest cannot store " << cap << " entries. Limiting to " << absolute_max);
+ static time_t last_loud = 0;
+ if (last_loud < squid_curtime - 86400) {
+ debugs(71, DBG_IMPORTANT, "WARNING: Cache Digest cannot store " << cap << " entries. Limiting to " << absolute_max);
+ last_loud = squid_curtime;
+ } else {
+ debugs(71, 3, "WARNING: Cache Digest cannot store " << cap << " entries. Limiting to " << absolute_max);
+ }
cap = absolute_max;
}
void
storeDigestInit(void)
{
- storeDigestRegisterWithCacheManager();
+ Mgr::RegisterAction("store_digest", "Store Digest", storeDigestReport, 0, 1);
#if USE_CACHE_DIGESTS
if (!Config.onoff.digest_generation) {
(int) Config.digest.rebuild_period << "/" <<
(int) Config.digest.rewrite_period << " sec");
- memset(&sd_state, 0, sizeof(sd_state));
+ sd_state = StoreDigestState();
#else
store_digest = NULL;
debugs(71, 3, "Local cache digest is 'off'");
}
if (store_digest) {
- cacheDigestReport(store_digest, "store", e);
+ static const SBuf label("store");
+ cacheDigestReport(store_digest, label, e);
storeAppendPrintf(e, "\t added: %d rejected: %d ( %.2f %%) del-ed: %d\n",
sd_stats.add_count,
sd_stats.rej_count,
{
const uint64_t cap = storeDigestCalcCap();
assert(store_digest);
- uint64_t diff = abs(cap - store_digest->capacity);
+ uint64_t diff;
+ if (cap > store_digest->capacity)
+ diff = cap - store_digest->capacity;
+ else
+ diff = store_digest->capacity - cap;
debugs(71, 2, store_digest->capacity << " -> " << cap << "; change: " <<
diff << " (" << xpercentInt(diff, store_digest->capacity) << "%)" );
/* avoid minor adjustments */
if (!storeDigestResize())
store_digest->clear(); /* not clean()! */
- memset(&sd_stats, 0, sizeof(sd_stats));
+ sd_stats = StoreDigestStats();
eventAdd("storeDigestRebuildStep", storeDigestRebuildStep, NULL, 0.0, 1);
}
static void
storeDigestRewriteStart(void *datanotused)
{
- RequestFlags flags;
- char *url;
- StoreEntry *e;
-
assert(store_digest);
/* prevent overlapping if rewrite schedule is too tight */
}
debugs(71, 2, "storeDigestRewrite: start rewrite #" << sd_state.rewrite_count + 1);
- /* make new store entry */
- url = internalLocalUri("/squid-internal-periodic/", SBuf(StoreDigestFileName));
+
+ const char *url = internalLocalUri("/squid-internal-periodic/", SBuf(StoreDigestFileName));
+ const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest);
+ auto req = HttpRequest::FromUrlXXX(url, mx);
+
+ RequestFlags flags;
flags.cachable = true;
- e = storeCreateEntry(url, url, flags, Http::METHOD_GET);
+
+ StoreEntry *e = storeCreateEntry(url, url, flags, Http::METHOD_GET);
assert(e);
sd_state.rewrite_lock = e;
debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text());
- HttpRequest *req = HttpRequest::CreateFromUrl(url);
e->mem_obj->request = req;
- HTTPMSGLOCK(e->mem_obj->request);
- /* wait for rebuild (if any) to finish */
+ /* wait for rebuild (if any) to finish */
if (sd_state.rebuild_lock) {
debugs(71, 2, "storeDigestRewriteStart: waiting for rebuild to finish.");
return;
e = sd_state.rewrite_lock;
sd_state.rewrite_offset = 0;
EBIT_SET(e->flags, ENTRY_SPECIAL);
- /* setting public key will purge old digest entry if any */
+ /* setting public key will mark the old digest entry for removal once unlocked */
e->setPublicKey();
+ if (const auto oldEntry = sd_state.publicEntry) {
+ oldEntry->release(true);
+ sd_state.publicEntry = nullptr;
+ oldEntry->unlock("storeDigestRewriteResume");
+ }
+ assert(e->locked());
+ sd_state.publicEntry = e;
/* fake reply */
HttpReply *rep = new HttpReply;
rep->setHeaders(Http::scOkay, "Cache Digest OK",
" (" << std::showpos << (int) (e->expires - squid_curtime) << ")");
/* is this the write order? @?@ */
e->mem_obj->unlinkRequest();
- e->unlock("storeDigestRewriteFinish");
sd_state.rewrite_lock = NULL;
++sd_state.rewrite_count;
eventAdd("storeDigestRewriteStart", storeDigestRewriteStart, NULL, (double)