]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/store_digest.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / store_digest.cc
index 1fbacda670b0631029faa3e74a6e83f7fdd08569..9030e6bf6c9f31dcaf7fb5ed294fb0268fbb1806 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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;
@@ -79,12 +81,6 @@ static EVH storeDigestSwapOutStep;
 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()
@@ -113,7 +109,13 @@ 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;
     }
 
@@ -124,7 +126,7 @@ storeDigestCalcCap()
 void
 storeDigestInit(void)
 {
-    storeDigestRegisterWithCacheManager();
+    Mgr::RegisterAction("store_digest", "Store Digest", storeDigestReport, 0, 1);
 
 #if USE_CACHE_DIGESTS
     if (!Config.onoff.digest_generation) {
@@ -139,7 +141,7 @@ storeDigestInit(void)
            (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'");
@@ -196,7 +198,8 @@ storeDigestReport(StoreEntry * e)
     }
 
     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,
@@ -324,7 +327,11 @@ storeDigestResize()
 {
     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 */
@@ -351,7 +358,7 @@ storeDigestRebuildResume(void)
     if (!storeDigestResize())
         store_digest->clear();     /* not clean()! */
 
-    memset(&sd_stats, 0, sizeof(sd_stats));
+    sd_stats = StoreDigestStats();
 
     eventAdd("storeDigestRebuildStep", storeDigestRebuildStep, NULL, 0.0, 1);
 }
@@ -397,10 +404,6 @@ storeDigestRebuildStep(void *datanotused)
 static void
 storeDigestRewriteStart(void *datanotused)
 {
-    RequestFlags flags;
-    char *url;
-    StoreEntry *e;
-
     assert(store_digest);
     /* prevent overlapping if rewrite schedule is too tight */
 
@@ -410,18 +413,21 @@ storeDigestRewriteStart(void *datanotused)
     }
 
     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;
@@ -440,8 +446,15 @@ storeDigestRewriteResume(void)
     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",
@@ -467,7 +480,6 @@ storeDigestRewriteFinish(StoreEntry * e)
            " (" << 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)